<commit_before>var Views = {
	Options: Backbone.View.extend({
		tagName: "form",

		events: {
			"change input": "handleChange"
		},

		initialize: function() {
			this.$el.appendTo("body");

			var metrics = localStorage.getItem("metrics") === "on";
			this.model.set("metrics", metrics);

			this.model.on("change", this.render, this);
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			console.log(data);
			this.$el.html(Templates.Options(data));

			return this;
		},

		handleChange: function(event) {
			var metrics = this.$("[name=metrics]").prop("checked");

			if (!metrics) {
				this.setAndStore("metrics", "off");
			} else if (confirm("Enabling this will query Altmetric and Scopus for article-level metrics, and they will be able to see your search terms.")) {
				this.setAndStore("metrics", "on");
			} else {
				event.preventDefault();
			}
		},

		setAndStore: function(name, metrics) {
			this.model.set(name, metrics);
			localStorage.setItem(name, metrics);
			window.location.reload(); // TODO: just update the page
		}
	}),

	Input: Backbone.View.extend({
		tagName: "form",

		attributes: {
			autocapitalize: "off"
		},

		events: {
			"change input[type=checkbox],select": "submitChangedForm",
			"click .clear": "clearInput",
			//"click input[name=term]": "selectInput"
		},

		initialize: function() {
			this.$el.appendTo("body");

			if (location.search) {
				this.parseQueryString().forEach(this.handleQueryPart, this);

				// only use "days" for "related" queries
				if (!this.model.get("relatedQuery")) {
					this.model.set("days", 0);
				}
			}

			this.model.on("change", this.render, this);
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Input(data));
		},

		parseQueryString: function() {
			return location.search.substring(1).split("&").map(function(item) {
				return item.split("=").map(decodeURIComponent).map(function(text) {
					return text.replace(/\+/g, " ");
				});
			});
		},

		handleQueryPart: function(item) {
			var name = item[0];
			var value = item[1].replace(/\/$/, "");

			switch (name) {
				case "days":
					this.model.set("days", Number(value));
					return;

				case "term":
					this.model.set("relatedQuery", value.match(/^related:/));
					this.model.set("term", value);
					break;

				case "filter":
					var filters = this.model.get("filters");

					if (typeof filters[value] !== "undefined") {
						filters[value].enabled = true;
						this.model.set("filters", filters);
					}

					break;
			}
		},

		submitChangedForm: function() {
			this.$el.submit();
		},

		clearInput: function() {
			this.model.set("term", null);
			this.$("[name=term]").val("").focus();
		},

		selectInput: function(event) {
			$(event.currentTarget).select();
		}
	}),

	Articles: Backbone.View.extend({
		offset: 0,
		limit: 5,

		initialize: function() {
			this.$el.appendTo("body");
			this.collection.on("reset", this.reset, this);
			this.collection.on("add", this.add, this);
		},

		reset: function() {
			this.$el.empty();

			this.collection.each(this.add, this);

			var articles = $("article");

			if (articles.length === 1) {
				articles.trigger("toggleExpanded");
			}
		},

		add: function(article) {
			var view = new Views.Article({ model: article });
			this.$el.append(view.render().el);
		}
	}),

	Article: Backbone.View.extend({
		tagName: "article",

		attributes: {
			"vocab": "http://schema.org/",
			"typeof": "MedicalScholarlyArticle"
		},

		events: {
			"click a[data-action]": "action",
			"toggleExpanded": "toggleExpanded",
		},

		initialize: function() {
			this.links = new Views.Links({ model: this.model });
			this.metrics = new Views.Metrics({ collection: this.model.metrics });

			this.model.on("change", this.render, this);
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Article(data));

			this.$el.find("[property=creators]").formatAuthors(5, "creator");
			this.$el.find("[property=abstract]").formatAbstract();

			this.$el.find("footer").prepend(this.links.$el);
			this.$el.find(".context").append(this.metrics.$el);

			return this;
		},

		action: function(event) {
			if (event.metaKey || event.ctrlKey) {
				return true;
			}

			var node = $(event.currentTarget);

			switch (node.data("action")) {
				case "show-abstract":
					node.closest("article").trigger("toggleExpanded");
				break;
			}

			return false;
		},

		toggleExpanded: function(event) {
			var node = $(event.target).toggleClass("expanded");
			var url = this.$(".read").attr("href");

			$("article.active").removeClass("active");

			if (node.is(".expanded")) {
				node.addClass("active").scrollIntoView();
				window.parent.postMessage({ url: url }, window.location.origin);
			}
		}
	}),

	Metrics: Backbone.View.extend({
		tagName: "span",
		className: "metrics",

		initialize: function() {
			this.collection.on("reset", this.reset, this);
			this.collection.on("add", this.add, this);
		},

		reset: function() {
			this.$el.empty();
			this.collection.each(this.add, this);
		},

		add: function(metric) {
			var view = new Views.Metric({ model: metric });
			view.render().$el.appendTo(this.$el);
		}
	}),

	Metric: Backbone.View.extend({
		tagName: "a",

		className: "metric",

		attributes: {
			target: "_blank"
		},

		initialize: function() {
			this.model.on("change", this.render, this);
		},

		render: function() {
			var data = this.model.toJSON();

			this.$el.attr("href", data.url).text(data.text);

			if (data.image) {
				$("<img/>", { src: "images/" + data.image }).prependTo(this.$el);
			}

			return this;
		}
	}),

	Links: Backbone.View.extend({
		className: "links",

		events: {
			"click .link": "handleClick",
		},

		initialize: function() {
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Links(data));
		},

		handleClick: function(event) {
			var node = $(event.target);

			switch (node.data("intent")) {
				case "save":
					var type = localStorage.getItem("saveType");
					if (type) {
						this.$("[rel=save][type='" + type + "']").click();
					} else {
						node.next(".link").click();
					}
					return;

				case "find":
					var type = localStorage.getItem("findType");

					if (type) {
						this.$("[rel=find][type='" + type + "']").click();
					} else {
						node.next(".link").click();
					}
					return;

				case "read":
					window.open(this.$el.closest("article").find("[property=url]").attr("href"));
					return false;
			}

			if (node.data("dropdown-target")) {
				var target = this.$(node.data("dropdown-target"));

				if (target.is(":visible")) {
					target.hide();
				} else {
					event.stopPropagation();
					var offset = node.offset();
					var previous = node.prev(".link");

					target.show();
					target.offset({ top: offset.top + node.height(), left: offset.left - previous.width() });

					window.setTimeout(function() {
						$(document).one("click", function() {
							$(".dropdown-list:visible").hide();
						});
					}, 100);
				}

				return false;
			}

			switch (node.attr("rel")) {
				case "related":
					if (event.metaKey || event.ctrlKey) {
						event.preventDefault();

						var pmid = this.model.get("pmid");

						var currentTerm = $.trim(app.models.query.get("term"));

						var term;
						if (app.models.query.get("relatedQuery")) {
							term = currentTerm + "," + pmid;
						} else {
							term = "related:" + pmid;
						}

						app.models.query.set("term", term);
						app.views.input.$el.submit();
					}

					return;

				case "save":
					event.preventDefault();
					event.stopPropagation();
					localStorage.setItem("saveType", node.attr("type"));
					if (node.attr("download")) {
						window.location = node.attr("href");
					} else {
						window.open(node.attr("href"));
					}
					return;

				case "find":
					event.preventDefault();
					event.stopPropagation();
					localStorage.setItem("findType", node.attr("type"));
					window.open(node.attr("href"));
					return;

				default:
					return;
			}
		}
	}),

	Pagination: Backbone.View.extend({
		tagName: "a",

		events: {
			"click": "fetchPage"
		},

        initialize: function() {
            _.bindAll(this);

            this
                .$el
                .attr("href", "#")
                .attr("rel", "next")
                .html("More ↓")
                .data("offset", 0)
                .hide()
                .appendTo("body");
        },

        start: function() {
            this.fetchPage();
            this.watchScrollPosition(this.fetchPage, 500, 500);
        },

        watchScrollPosition: function(callback, distance, interval) {
            var $window = $(window),
                $document = $(document);

            var checkScrollPosition = function() {
                var top = $document.height() - $window.height() - distance;

                if ($window.scrollTop() >= top) {
                    callback();
                }
            };

            setInterval(checkScrollPosition, interval);
        },

		setNextOffset: function() {
			var offset = app.views.articles.offset + app.views.articles.limit;
			this.$el.data("offset", offset).removeClass("loading").html("More ↓");
			this.$el.show();
		},

		fetchPage: function() {
			var node = this.$el;

			if (node.hasClass("loading")) {
				return false;
			}

			var spinner = $("<img/>", { src: "./images/spinner.gif"}).addClass("spinner");

			var count = app.models.query.get("count");
			var text;
			if (count) {
				var offset = app.views.articles.offset + app.views.articles.limit + 1;
				var nextOffset = Math.min(count, offset + app.views.articles.limit);
				var text = "Loading " + offset + " - " + nextOffset + " of " + this.numberWithCommas(count) + " articles";
			} else {
				text = "Searching";
			}
			node.addClass("loading").text(text).append(spinner);

			app.views.articles.offset = node.data("offset");

			app.collections.articles.fetch({ add: true, success: this.collectionUpdated });

            return false;
        },

        numberWithCommas: function(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        },

		noMoreItems: function() {
			this.$el.text("No more items");
		},

		collectionUpdated: function() {
			if (app.views.articles.offset == 0) {
				$(document).trigger("ZoteroItemUpdated");
			}
		}
	})
};<commit_msg>Remove console.log<commit_after>var Views = {
	Options: Backbone.View.extend({
		tagName: "form",

		events: {
			"change input": "handleChange"
		},

		initialize: function() {
			this.$el.appendTo("body");

			var metrics = localStorage.getItem("metrics") === "on";
			this.model.set("metrics", metrics);

			this.model.on("change", this.render, this);
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Options(data));

			return this;
		},

		handleChange: function(event) {
			var metrics = this.$("[name=metrics]").prop("checked");

			if (!metrics) {
				this.setAndStore("metrics", "off");
			} else if (confirm("Enabling this will query Altmetric and Scopus for article-level metrics, and they will be able to see your search terms.")) {
				this.setAndStore("metrics", "on");
			} else {
				event.preventDefault();
			}
		},

		setAndStore: function(name, metrics) {
			this.model.set(name, metrics);
			localStorage.setItem(name, metrics);
			window.location.reload(); // TODO: just update the page
		}
	}),

	Input: Backbone.View.extend({
		tagName: "form",

		attributes: {
			autocapitalize: "off"
		},

		events: {
			"change input[type=checkbox],select": "submitChangedForm",
			"click .clear": "clearInput",
			//"click input[name=term]": "selectInput"
		},

		initialize: function() {
			this.$el.appendTo("body");

			if (location.search) {
				this.parseQueryString().forEach(this.handleQueryPart, this);

				// only use "days" for "related" queries
				if (!this.model.get("relatedQuery")) {
					this.model.set("days", 0);
				}
			}

			this.model.on("change", this.render, this);
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Input(data));
		},

		parseQueryString: function() {
			return location.search.substring(1).split("&").map(function(item) {
				return item.split("=").map(decodeURIComponent).map(function(text) {
					return text.replace(/\+/g, " ");
				});
			});
		},

		handleQueryPart: function(item) {
			var name = item[0];
			var value = item[1].replace(/\/$/, "");

			switch (name) {
				case "days":
					this.model.set("days", Number(value));
					return;

				case "term":
					this.model.set("relatedQuery", value.match(/^related:/));
					this.model.set("term", value);
					break;

				case "filter":
					var filters = this.model.get("filters");

					if (typeof filters[value] !== "undefined") {
						filters[value].enabled = true;
						this.model.set("filters", filters);
					}

					break;
			}
		},

		submitChangedForm: function() {
			this.$el.submit();
		},

		clearInput: function() {
			this.model.set("term", null);
			this.$("[name=term]").val("").focus();
		},

		selectInput: function(event) {
			$(event.currentTarget).select();
		}
	}),

	Articles: Backbone.View.extend({
		offset: 0,
		limit: 5,

		initialize: function() {
			this.$el.appendTo("body");
			this.collection.on("reset", this.reset, this);
			this.collection.on("add", this.add, this);
		},

		reset: function() {
			this.$el.empty();

			this.collection.each(this.add, this);

			var articles = $("article");

			if (articles.length === 1) {
				articles.trigger("toggleExpanded");
			}
		},

		add: function(article) {
			var view = new Views.Article({ model: article });
			this.$el.append(view.render().el);
		}
	}),

	Article: Backbone.View.extend({
		tagName: "article",

		attributes: {
			"vocab": "http://schema.org/",
			"typeof": "MedicalScholarlyArticle"
		},

		events: {
			"click a[data-action]": "action",
			"toggleExpanded": "toggleExpanded",
		},

		initialize: function() {
			this.links = new Views.Links({ model: this.model });
			this.metrics = new Views.Metrics({ collection: this.model.metrics });

			this.model.on("change", this.render, this);
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Article(data));

			this.$el.find("[property=creators]").formatAuthors(5, "creator");
			this.$el.find("[property=abstract]").formatAbstract();

			this.$el.find("footer").prepend(this.links.$el);
			this.$el.find(".context").append(this.metrics.$el);

			return this;
		},

		action: function(event) {
			if (event.metaKey || event.ctrlKey) {
				return true;
			}

			var node = $(event.currentTarget);

			switch (node.data("action")) {
				case "show-abstract":
					node.closest("article").trigger("toggleExpanded");
				break;
			}

			return false;
		},

		toggleExpanded: function(event) {
			var node = $(event.target).toggleClass("expanded");
			var url = this.$(".read").attr("href");

			$("article.active").removeClass("active");

			if (node.is(".expanded")) {
				node.addClass("active").scrollIntoView();
				window.parent.postMessage({ url: url }, window.location.origin);
			}
		}
	}),

	Metrics: Backbone.View.extend({
		tagName: "span",
		className: "metrics",

		initialize: function() {
			this.collection.on("reset", this.reset, this);
			this.collection.on("add", this.add, this);
		},

		reset: function() {
			this.$el.empty();
			this.collection.each(this.add, this);
		},

		add: function(metric) {
			var view = new Views.Metric({ model: metric });
			view.render().$el.appendTo(this.$el);
		}
	}),

	Metric: Backbone.View.extend({
		tagName: "a",

		className: "metric",

		attributes: {
			target: "_blank"
		},

		initialize: function() {
			this.model.on("change", this.render, this);
		},

		render: function() {
			var data = this.model.toJSON();

			this.$el.attr("href", data.url).text(data.text);

			if (data.image) {
				$("<img/>", { src: "images/" + data.image }).prependTo(this.$el);
			}

			return this;
		}
	}),

	Links: Backbone.View.extend({
		className: "links",

		events: {
			"click .link": "handleClick",
		},

		initialize: function() {
			this.render();
		},

		render: function() {
			var data = this.model.toJSON();
			this.$el.html(Templates.Links(data));
		},

		handleClick: function(event) {
			var node = $(event.target);

			switch (node.data("intent")) {
				case "save":
					var type = localStorage.getItem("saveType");
					if (type) {
						this.$("[rel=save][type='" + type + "']").click();
					} else {
						node.next(".link").click();
					}
					return;

				case "find":
					var type = localStorage.getItem("findType");

					if (type) {
						this.$("[rel=find][type='" + type + "']").click();
					} else {
						node.next(".link").click();
					}
					return;

				case "read":
					window.open(this.$el.closest("article").find("[property=url]").attr("href"));
					return false;
			}

			if (node.data("dropdown-target")) {
				var target = this.$(node.data("dropdown-target"));

				if (target.is(":visible")) {
					target.hide();
				} else {
					event.stopPropagation();
					var offset = node.offset();
					var previous = node.prev(".link");

					target.show();
					target.offset({ top: offset.top + node.height(), left: offset.left - previous.width() });

					window.setTimeout(function() {
						$(document).one("click", function() {
							$(".dropdown-list:visible").hide();
						});
					}, 100);
				}

				return false;
			}

			switch (node.attr("rel")) {
				case "related":
					if (event.metaKey || event.ctrlKey) {
						event.preventDefault();

						var pmid = this.model.get("pmid");

						var currentTerm = $.trim(app.models.query.get("term"));

						var term;
						if (app.models.query.get("relatedQuery")) {
							term = currentTerm + "," + pmid;
						} else {
							term = "related:" + pmid;
						}

						app.models.query.set("term", term);
						app.views.input.$el.submit();
					}

					return;

				case "save":
					event.preventDefault();
					event.stopPropagation();
					localStorage.setItem("saveType", node.attr("type"));
					if (node.attr("download")) {
						window.location = node.attr("href");
					} else {
						window.open(node.attr("href"));
					}
					return;

				case "find":
					event.preventDefault();
					event.stopPropagation();
					localStorage.setItem("findType", node.attr("type"));
					window.open(node.attr("href"));
					return;

				default:
					return;
			}
		}
	}),

	Pagination: Backbone.View.extend({
		tagName: "a",

		events: {
			"click": "fetchPage"
		},

        initialize: function() {
            _.bindAll(this);

            this
                .$el
                .attr("href", "#")
                .attr("rel", "next")
                .html("More ↓")
                .data("offset", 0)
                .hide()
                .appendTo("body");
        },

        start: function() {
            this.fetchPage();
            this.watchScrollPosition(this.fetchPage, 500, 500);
        },

        watchScrollPosition: function(callback, distance, interval) {
            var $window = $(window),
                $document = $(document);

            var checkScrollPosition = function() {
                var top = $document.height() - $window.height() - distance;

                if ($window.scrollTop() >= top) {
                    callback();
                }
            };

            setInterval(checkScrollPosition, interval);
        },

		setNextOffset: function() {
			var offset = app.views.articles.offset + app.views.articles.limit;
			this.$el.data("offset", offset).removeClass("loading").html("More ↓");
			this.$el.show();
		},

		fetchPage: function() {
			var node = this.$el;

			if (node.hasClass("loading")) {
				return false;
			}

			var spinner = $("<img/>", { src: "./images/spinner.gif"}).addClass("spinner");

			var count = app.models.query.get("count");
			var text;
			if (count) {
				var offset = app.views.articles.offset + app.views.articles.limit + 1;
				var nextOffset = Math.min(count, offset + app.views.articles.limit);
				var text = "Loading " + offset + " - " + nextOffset + " of " + this.numberWithCommas(count) + " articles";
			} else {
				text = "Searching";
			}
			node.addClass("loading").text(text).append(spinner);

			app.views.articles.offset = node.data("offset");

			app.collections.articles.fetch({ add: true, success: this.collectionUpdated });

            return false;
        },

        numberWithCommas: function(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        },

		noMoreItems: function() {
			this.$el.text("No more items");
		},

		collectionUpdated: function() {
			if (app.views.articles.offset == 0) {
				$(document).trigger("ZoteroItemUpdated");
			}
		}
	})
};<|endoftext|>


<commit_before>'use strict';

/*
LookJS is under the MIT license.
Created by Elena Torro
https://elenatorro.com
*/

var Look = {

  // -- Private --------------------------------------------------------------
  _setAttributes :
    function(element, attributes) {
      for (var name in attributes) {
        element.setAttribute(name, attributes[name]);
      }
    },

 _setContent :
  function(element, content) {
    content.forEach(function(object) {
      Look.create(object,element);
    });
  },

  _for :
    function(collection, attribute, content, position) {
      if (collection.length != 0) {
        for (var i in collection) {
          if (collection[i].getAttribute(attribute) === content) return collection[i];
        }
      }
      return false;
    },

    // -- Public ---------------------------------------------------------------

  create :
    function(object, container) {
      var element = this.newElement(object.tag);
      this._setAttributes(element, object.attr);
      if (object.content) this._setContent(element, object.content);
      container ? container.appendChild(element) : document.body.appendChild(element);
      return element;
    },

  createMany :
    function(times, object, container) {
      var i = 0;
      for (i; i < times; i++) {
        Look.create(object, container);
      }
    },

  copy :
    function(from, to) {
      return this.create(Look._clone(from), to);
    },

  _clone :
    function(object) {
      var newObject = object;
      newObject['id'] = newObject['id'] + '_copy';
      return newObject;
    },

    // -- document operations substitution ---------------------------------

  newElement :
    function(tag) {
      return document.createElement(tag);
    },

  getBy : {
    id :
      function(id) {
        return document.getElementById(id);
      },
    className :
      function(name, at) {
        if (at) return document.getElementsByClassName(name)[at];
        return document.getElementsByClassName(name);
      },
    tagName :
    function(name, at) {
      if (at) return document.getElementsByTagName(name)[at];
      return document.getElementsByTagName(name);
    },
    href :
      function(link, at) {
        if (at) return Look._for(document.getElementsByTagName('a'), 'href', link, at);
        return Look._for(document.getElementsByTagName('a'), 'href', link);
      },
    src :
      function(link, at) {
        if (at) return Look._for(document.getElementsByTagName('img'), 'src', link, at);
        return Look._for(document.getElementsByTagName('img'), 'src', link);
      }
    },

    // -- Localization ---------------------------------------------------------

setText : {
  to : {
    oneElement : function(element, text) {
      element.innerHTML = text;
    },

    manyElements : function(elements, texts, language) {
      var i = 0;
      for (i; i < elements.length; i++) {
        elements[i].innerHTML = texts[i][language];
      }
    }
  }
},

changeLanguage :
  function(language, localizer) {
    if (localizer['id']) {
      for (var element in localizer['id']) {
        Look.setText.to.oneElement(Look.getBy.id(element), localizer['id'][element][language]);
      }
    };

    if (localizer['class']) {
      for (var element in localizer['class']) {
        Look.setText.to.manyElements(Look.getBy.className(element), localizer['class'][element], language);
      }
    };

    if (localizer['tag']) {
      for (var element in localizer['tag']) {
        Look.setText.to.manyElements(Look.getBy.tagName(element), localizer['tag'][element], language);
      }
    };

  }
}
<commit_msg>textContent instead of innerHTML<commit_after>'use strict';

/*
LookJS is under the MIT license.
Created by Elena Torro
https://elenatorro.com
*/

var Look = {

  // -- Private --------------------------------------------------------------
  _setAttributes :
    function(element, attributes) {
      for (var name in attributes) {
        element.setAttribute(name, attributes[name]);
      }
    },

 _setContent :
  function(element, content) {
    content.forEach(function(object) {
      Look.create(object,element);
    });
  },

  _for :
    function(collection, attribute, content, position) {
      if (collection.length != 0) {
        for (var i in collection) {
          if (collection[i].getAttribute(attribute) === content) return collection[i];
        }
      }
      return false;
    },

    // -- Public ---------------------------------------------------------------

  create :
    function(object, container) {
      var element = this.newElement(object.tag);
      this._setAttributes(element, object.attr);
      if (object.content) this._setContent(element, object.content);
      container ? container.appendChild(element) : document.body.appendChild(element);
      return element;
    },

  createMany :
    function(times, object, container) {
      var i = 0;
      for (i; i < times; i++) {
        Look.create(object, container);
      }
    },

  copy :
    function(from, to) {
      return this.create(Look._clone(from), to);
    },

  _clone :
    function(object) {
      var newObject = object;
      newObject['id'] = newObject['id'] + '_copy';
      return newObject;
    },

    // -- document operations substitution ---------------------------------

  newElement :
    function(tag) {
      return document.createElement(tag);
    },

  getBy : {
    id :
      function(id) {
        return document.getElementById(id);
      },
    className :
      function(name, at) {
        if (at) return document.getElementsByClassName(name)[at];
        return document.getElementsByClassName(name);
      },
    tagName :
    function(name, at) {
      if (at) return document.getElementsByTagName(name)[at];
      return document.getElementsByTagName(name);
    },
    href :
      function(link, at) {
        if (at) return Look._for(document.getElementsByTagName('a'), 'href', link, at);
        return Look._for(document.getElementsByTagName('a'), 'href', link);
      },
    src :
      function(link, at) {
        if (at) return Look._for(document.getElementsByTagName('img'), 'src', link, at);
        return Look._for(document.getElementsByTagName('img'), 'src', link);
      }
    },

    // -- Localization ---------------------------------------------------------

setText : {
  to : {
    oneElement : function(element, text) {
      element.textContent = text;
    },

    manyElements : function(elements, texts, language) {
      var i = 0;
      for (i; i < elements.length; i++) {
        elements[i].textContent = texts[i][language];
      }
    }
  }
},

changeLanguage :
  function(language, localizer) {
    if (localizer['id']) {
      for (var element in localizer['id']) {
        Look.setText.to.oneElement(Look.getBy.id(element), localizer['id'][element][language]);
      }
    };

    if (localizer['class']) {
      for (var element in localizer['class']) {
        Look.setText.to.manyElements(Look.getBy.className(element), localizer['class'][element], language);
      }
    };

    if (localizer['tag']) {
      for (var element in localizer['tag']) {
        Look.setText.to.manyElements(Look.getBy.tagName(element), localizer['tag'][element], language);
      }
    };

  }
}
<|endoftext|>


<commit_before>const browsers = [
  'last 1 Chrome versions',
  'last 1 Firefox versions',
  'last 1 Safari versions'
];

const isCI = !!process.env.CI;
const isProduction = process.env.EMBER_ENV === 'production';

if (isCI || isProduction) {
  browsers.push('ie 11');
}

module.exports = {
  browsers
};
<commit_msg>Fixed warnings<commit_after>'use strict';

const browsers = [
  'last 1 Chrome versions',
  'last 1 Firefox versions',
  'last 1 Safari versions'
];

const isCI = !!process.env.CI;
const isProduction = process.env.EMBER_ENV === 'production';

if (isCI || isProduction) {
  browsers.push('ie 11');
}

module.exports = {
  browsers
};
<|endoftext|>


<commit_before>// Copyright 2013 Google Inc.
// Copyright 2014 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Rule stores for the basic components of math expressions:
 *    Unicode symbols and functions.
 *
 *    The idea of these stores is to provide a more efficient data structure to
 *    look up rules in the background page than the usual flat array of rules
 *    implemented by other stores.
 *
 * @author sorge@google.com (Volker Sorge)
 */

goog.provide('sre.MathCompoundStore');
goog.provide('sre.MathSimpleStore');

goog.require('sre.BaseUtil');
goog.require('sre.DomUtil');
goog.require('sre.DynamicCstr');
goog.require('sre.MathStore');
goog.require('sre.SpeechRule');
goog.require('sre.XpathUtil');

/**
 * A base store for simple Math objects.
 * @constructor
 * @extends {sre.MathStore}
 */
sre.MathSimpleStore = function() {
  sre.MathSimpleStore.base(this, 'constructor');
};
goog.inherits(sre.MathSimpleStore, sre.MathStore);

/**
 * Turns a domain mapping from its JSON representation containing simple strings
 * only into a list of speech rules.
 * @param {string} name Name for the rules.
 * @param {string} str String for precondition and constraints.
 * @param {Object.<string, Object.<string, string>>} mapping Simple string
 *     mapping.
 */
sre.MathSimpleStore.prototype.defineRulesFromMappings = function(
    name, str, mapping) {
  for (var domain in mapping) {
    for (var style in mapping[domain]) {
      var content = mapping[domain][style];
      if (str === '"') {
        var cstr = 'self::text() = \'' + str + '\'';
      } else {
        cstr = 'self::text() = "' + str + '"';
      }
      this.defineRule(name, domain + '.' + style, '[t] "' + content + '"',
                      'self::text()', cstr);
    }
  }
};

/**
 * A compound store for simple Math objects.
 * @constructor
 */
sre.MathCompoundStore = function() {
  /**
   * A set of efficient substores.
   * @type {Object.<string, sre.MathStore>}
   * @private
   */
  this.subStores_ = {};
};
goog.addSingletonGetter(sre.MathCompoundStore);

/**
 * Function creates a rule store in the compound store for a particular string,
 * and populates it with a set of rules.
 * @param {string} name Name of the rule.
 * @param {string} str String used as key to refer to the rule store
 * precondition and constr
 * @param {Object} mappings JSON representation of mappings from styles and
 *     domains to strings, from which the speech rules will be computed.
 */
sre.MathCompoundStore.prototype.defineRules = function(name, str, mappings) {
  var store = new sre.MathSimpleStore();
  store.defineRulesFromMappings(name, str, mappings);
  this.subStores_[str] = store;
};

/**
 * Makes a speech rule for Unicode characters from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addSymbolRules = function(json) {
  var key = sre.MathSimpleStore.parseUnicode_(json['key']);
  this.defineRules(json['key'], key, json['mappings']);
};

/**
 * Makes a speech rule for Function names from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addFunctionRules = function(json) {
  var names = json['names'];
  var mappings = json['mappings'];
  for (var j = 0, name; name = names[j]; j++) {
    this.defineRules(name, name, mappings);
  }
};

/**
 * Makes a speech rule for Unit descriptors from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addUnitRules = function(json) {
  var names = json['names'];
  if (names) {
    json['names'] = names.map(function(name) {return name + ':' + 'unit';});
  }
  this.addFunctionRules(json);
};

/**
 * Retrieves a rule for the given node if one exists.
 * @param {Node} node A node.
 * @param {sre.DynamicCstr} dynamic Additional dynamic
 *     constraints. These are matched against properties of a rule.
 * @return {sre.SpeechRule} The speech rule if it exists.
 */
sre.MathCompoundStore.prototype.lookupRule = function(node, dynamic) {
  var store = this.subStores_[node.textContent];
  if (store) {
    // TODO: (MOSS) Fix with order parsing.
    dynamic = dynamic || store.parser.parse('default.default');
    return store.lookupRule(node, dynamic);
  }
  return null;
};

/**
 * Looks up a rule for a given string and executes its actions.
 * @param {string} text The text to be translated.
 * @param {sre.DynamicCstr} dynamic Additional dynamic
 *     constraints. These are matched against properties of a rule.
 * @return {!string} The string resulting from the action of speech rule.
 */
sre.MathCompoundStore.prototype.lookupString = function(text, dynamic) {
  var textNode = sre.XpathUtil.currentDocument ?
      sre.XpathUtil.currentDocument.createTextNode(text) :
      sre.DomUtil.createTextNode(text);
  var rule = this.lookupRule(textNode, dynamic);
  if (!rule) {
    return '';
  }
  return rule.action.components
      .map(function(comp) {
           return comp.content.slice(1, -1);})
      .join(' ');
};

/**
 * Parses a string with a hex representatino of a unicode code point into the
 * corresponding unicode character.
 * @param {string} number The code point to be parsed.
 * @return {string} The unicode character.
 * @private
 */
sre.MathSimpleStore.parseUnicode_ = function(number) {
  var keyValue = parseInt(number, 16);
  if (keyValue < 0x10000) {
    return String.fromCharCode(keyValue);
  }
  keyValue -= 0x10000;
  var hiSurrogate = (keyValue >> 10) + 0xD800;
  var lowSurrogate = (keyValue & 0x3FF) + 0xDC00;
  return String.fromCharCode(hiSurrogate, lowSurrogate);
};
<commit_msg>Simplifies rule lookup for simple stores.<commit_after>// Copyright 2013 Google Inc.
// Copyright 2014 Volker Sorge
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Rule stores for the basic components of math expressions:
 *    Unicode symbols and functions.
 *
 *    The idea of these stores is to provide a more efficient data structure to
 *    look up rules in the background page than the usual flat array of rules
 *    implemented by other stores.
 *
 * @author sorge@google.com (Volker Sorge)
 */

goog.provide('sre.MathCompoundStore');
goog.provide('sre.MathSimpleStore');

goog.require('sre.BaseUtil');
goog.require('sre.DomUtil');
goog.require('sre.DynamicCstr');
goog.require('sre.MathStore');
goog.require('sre.SpeechRule');
goog.require('sre.XpathUtil');

/**
 * A base store for simple Math objects.
 * @constructor
 * @extends {sre.MathStore}
 */
sre.MathSimpleStore = function() {
  sre.MathSimpleStore.base(this, 'constructor');
};
goog.inherits(sre.MathSimpleStore, sre.MathStore);

/**
 * Turns a domain mapping from its JSON representation containing simple strings
 * only into a list of speech rules.
 * @param {string} name Name for the rules.
 * @param {string} str String for precondition and constraints.
 * @param {Object.<string, Object.<string, string>>} mapping Simple string
 *     mapping.
 */
sre.MathSimpleStore.prototype.defineRulesFromMappings = function(
    name, str, mapping) {
  for (var domain in mapping) {
    for (var style in mapping[domain]) {
      var content = mapping[domain][style];
      if (str === '"') {
        var cstr = 'self::text() = \'' + str + '\'';
      } else {
        cstr = 'self::text() = "' + str + '"';
      }
      this.defineRule(name, domain + '.' + style, '[t] "' + content + '"',
                      'self::text()', cstr);
    }
  }
};

/**
 * @override
 */
sre.MathSimpleStore.prototype.lookupRule = function(node, dynamic) {
  if (!node || node.nodeType != sre.DomUtil.NodeType.TEXT_NODE) {
    return null;
  }
  var rules = this.getSpeechRules().filter(
      goog.bind(
          function(rule) {
            return this.testDynamicConstraints(dynamic, rule);
            // At this point we can be sure that the rule matches.
            // TODO (MOSS): Remove after Trie introduction.
            // rule.precondition.constraints[0].slice(0,-1).slice(16);
          },
        this));
  return rules.length ?
    rules.sort(function(r1, r2) {
      return sre.Engine.getInstance().comparator.
        compare(r1.dynamicCstr, r2.dynamicCstr);})[0] : null;
};

/**
 * A compound store for simple Math objects.
 * @constructor
 */
sre.MathCompoundStore = function() {
  /**
   * A set of efficient substores.
   * @type {Object.<string, sre.MathStore>}
   * @private
   */
  this.subStores_ = {};
};
goog.addSingletonGetter(sre.MathCompoundStore);

/**
 * Function creates a rule store in the compound store for a particular string,
 * and populates it with a set of rules.
 * @param {string} name Name of the rule.
 * @param {string} str String used as key to refer to the rule store
 * precondition and constr
 * @param {Object} mappings JSON representation of mappings from styles and
 *     domains to strings, from which the speech rules will be computed.
 */
sre.MathCompoundStore.prototype.defineRules = function(name, str, mappings) {
  var store = new sre.MathSimpleStore();
  store.defineRulesFromMappings(name, str, mappings);
  this.subStores_[str] = store;
};

/**
 * Makes a speech rule for Unicode characters from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addSymbolRules = function(json) {
  var key = sre.MathSimpleStore.parseUnicode_(json['key']);
  this.defineRules(json['key'], key, json['mappings']);
};

/**
 * Makes a speech rule for Function names from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addFunctionRules = function(json) {
  var names = json['names'];
  var mappings = json['mappings'];
  for (var j = 0, name; name = names[j]; j++) {
    this.defineRules(name, name, mappings);
  }
};

/**
 * Makes a speech rule for Unit descriptors from its JSON representation.
 * @param {Object} json JSON object of the speech rules.
 */
sre.MathCompoundStore.prototype.addUnitRules = function(json) {
  var names = json['names'];
  if (names) {
    json['names'] = names.map(function(name) {return name + ':' + 'unit';});
  }
  this.addFunctionRules(json);
};

/**
 * Retrieves a rule for the given node if one exists.
 * @param {Node} node A node.
 * @param {sre.DynamicCstr} dynamic Additional dynamic
 *     constraints. These are matched against properties of a rule.
 * @return {sre.SpeechRule} The speech rule if it exists.
 */
sre.MathCompoundStore.prototype.lookupRule = function(node, dynamic) {
  var store = this.subStores_[node.textContent];
  if (store) {
    // TODO: (MOSS) Fix with order parsing.
    dynamic = dynamic || store.parser.parse('default.default');
    return store.lookupRule(node, dynamic);
  }
  return null;
};

/**
 * Looks up a rule for a given string and executes its actions.
 * @param {string} text The text to be translated.
 * @param {sre.DynamicCstr} dynamic Additional dynamic
 *     constraints. These are matched against properties of a rule.
 * @return {!string} The string resulting from the action of speech rule.
 */
sre.MathCompoundStore.prototype.lookupString = function(text, dynamic) {
  var textNode = sre.XpathUtil.currentDocument ?
      sre.XpathUtil.currentDocument.createTextNode(text) :
      sre.DomUtil.createTextNode(text);
  var rule = this.lookupRule(textNode, dynamic);
  if (!rule) {
    return '';
  }
  return rule.action.components
      .map(function(comp) {
           return comp.content.slice(1, -1);})
      .join(' ');
};

/**
 * Parses a string with a hex representatino of a unicode code point into the
 * corresponding unicode character.
 * @param {string} number The code point to be parsed.
 * @return {string} The unicode character.
 * @private
 */
sre.MathSimpleStore.parseUnicode_ = function(number) {
  var keyValue = parseInt(number, 16);
  if (keyValue < 0x10000) {
    return String.fromCharCode(keyValue);
  }
  keyValue -= 0x10000;
  var hiSurrogate = (keyValue >> 10) + 0xD800;
  var lowSurrogate = (keyValue & 0x3FF) + 0xDC00;
  return String.fromCharCode(hiSurrogate, lowSurrogate);
};
<|endoftext|>


<commit_before>pref("extensions.firebug.DBG_ZIPKIN", false);
pref("extensions.zipkin.profile_site", "^((\\w+\\.)+)?(twitter)\\.com$");
pref("extensions.zipkin.zipkin_site", "https://zipkin.smf1.twitter.com");
pref("extensions.zipkin.enable_tracing", true);
pref("extensions.zipkin.trace_zipkin_ui", false);
pref("extensions.zipkin.collapse_waterfalls", false);<commit_msg>Fix preference default in new browser extension<commit_after>pref("extensions.firebug.DBG_ZIPKIN", false);
pref("extensions.zipkin.profile_site", "^((\\w+\\.)+)?(twitter)\\.com$");
pref("extensions.zipkin.zipkin_site", "");
pref("extensions.zipkin.enable_tracing", true);
pref("extensions.zipkin.trace_zipkin_ui", false);
pref("extensions.zipkin.collapse_waterfalls", false);<|endoftext|>


<commit_before>odoo.define('jim_telesale.new_order_widgets2', function (require) {
"use strict";
var Model = require('web.DataModel');
var NewOrderWidgets = require('telesale.new_order_widgets');
var core = require('web.core');
var _t = core._t;

var OrderWidget = NewOrderWidgets.OrderWidget.include({
    create_line_from_vals: function(product_id, line_vals){
        var added_line = this.create_line_empty(product_id);
        added_line.set('qty', line_vals.qty || 1.0);
        added_line.set('pvp', line_vals.price || 0.0);
        added_line.set('discount', line_vals.discount || 0.0);
        added_line.set('taxes_ids', line_vals.tax_ids || []);
        added_line.update_line_values();
        return added_line;
    },

    // Creates a line with product and unit seted
    create_line_empty: function(product_id){
        var added_line = this._super(product_id);
        var product_obj = this.ts_model.db.get_product_by_id(product_id);
        var description = product_obj.name;
        if (product_obj.description_sale){
            description = description + '\n' + product.description_sale
        }
        added_line.set('description', description);
        return added_line;
    },

});

var OrderlineWidget = NewOrderWidgets.OrderlineWidget.include({

    // Link change chained discount to method
    set_input_handlers: function() {
        this._super();
        this.$('.col-chained_discount').change(_.bind(this.set_value, this, 'chained_discount'));
        this.$('.col-chained_discount').focus(_.bind(this.click_handler, this, 'chained_discount'));

        this.$('.col-description').blur(_.bind(this.set_value, this, 'description'));
        this.$('.col-description').focus(_.bind(this.click_handler, this, 'description'));
    },

    // Convert a chained discout like (10.5+20) in a float (20.5)
    // or returns false if something wrong.
    chained_discount2float: function(value){
        if (!value){
            return 0.0
        }
        var split_disc = value.split('+')
        var discount = 0.0
        var disc = 0
        for (var i in split_disc){
            disc = split_disc[i]
            if (isNaN(disc) || disc == "") {
               return false // Break
            }
            else{
              discount = discount + parseFloat(disc);
            }
        }
        return discount;

    },

    // Manage chained_discount
    set_value: function(key) {
        this._super(key)
        if (key == 'chained_discount'){
            var value = this.$('.col-chained_discount').val();

            var discount = this.chained_discount2float(value);
            if (!discount){
                alert(value + _t("is not a valid format for chained discount. It must be something like 23+5.2+1"));
                this.model.set('discount', 0.0);
                this.model.set('chained_discount', 0.0);
            }
            else{
                this.model.set('discount', discount);
            }
            this.refresh('chained_discount');
        }
    },

    perform_onchange: function(key){
        if (key == 'pvp'){
            this.refresh('chained_discount');
        }
        this._super(key);
    },

    // OVERWRITED Get global stock available in product_id change
    call_product_id_change: function(product_id, add_qty){
        var self = this;

        if (!add_qty){
            add_qty = 1.0
        }

        var customer_id = self.ts_model.db.partner_name_id[self.order.get('partner')];
        var pricelist_id = self.ts_model.db.pricelist_name_id[self.order.get('pricelist')];
        var model = new Model("sale.order.line");
        return model.call("ts_product_id_change", [product_id, customer_id, pricelist_id])
        .then(function(result){
            var product_obj = self.ts_model.db.get_product_by_id(product_id);
            var uom_obj = self.ts_model.db.get_unit_by_id(product_obj.uom_id[0])
            var description = product_obj.name;
            if (product_obj.description_sale){
                description = description + '\n' + product.description_sale
            }
            self.model.set('description', description);
            self.model.set('code', product_obj.default_code || "");
            self.model.set('product', product_obj.display_name || "");
            self.model.set('taxes_ids', result.tax_id || []); //TODO poner impuestos de producto o vacio
            self.model.set('unit', self.model.ts_model.db.unit_by_id[result.product_uom].name);
            self.model.set('qty', add_qty);
            self.model.set('discount', 0.0);
            self.model.set('pvp', self.ts_model.my_round( result.price_unit));

            var subtotal = self.model.get('pvp') * self.model.get('qty') * (1 - self.model.get('discount') / 100.0)
            self.model.set('total', self.ts_model.my_round(subtotal || 0,2));

            // ADDED
            self.model.set('global_available_stock', result.global_available_stock || 0.0)

            self.refresh('qty');
            self.$('.col-qty').select();
        });
    },

    renderElement: function() {
        // Set lqdr route_name and global_available_stock
        var prod_name = this.model.get("product");
        // var prod_name = this.$('.col-product').val();
        var product_id = this.ts_model.db.product_name_id[prod_name];
        var product_obj = false
        if (product_id){
            product_obj = this.ts_model.db.get_product_by_id(product_id);
        }
        // Get first vatiant related
        else{
            var template_obj = this.get_template();
            if (template_obj){
                product_id = template_obj.product_variant_ids[0];
                product_obj = this.ts_model.db.get_product_by_id(product_id)
            }
        }

        // Always set lqdr route name and description.
        if (product_obj){
            var lqdr = (product_obj.lqdr)  ? _t("Yes") : _t("No")
            // var description = product_obj.name;
            // if (product_obj.description_sale){
            //     description = description + '\n' + product.description_sale
            // }

            this.model.set('lqdr', lqdr);
            this.model.set('route_name', product_obj.route_name);
            // this.model.set('description', description);
        }

        //set handler for fiscount plus field.
        this._super();
    },
    control_arrow_keys: function(){
        var self=this;
        this._super()
        this.$('.col-chained_discount').keydown(function(event){
          var keyCode = event.keyCode || event.which;
          if (keyCode == 40) {  // KEY DOWWN (40)
                event.preventDefault();
                $(this).parent().parent().next().find('.col-chained_discount').select();

            }
            else if (keyCode == 38){  //KEY UP
                event.preventDefault();
                $(this).parent().parent().prev().find('.col-chained_discount').select();
            }
        });
    },
});

var DataOrderWidget = NewOrderWidgets.DataOrderWidget.include({
    // Overwrited to show warning  orblocking menssage menssagge
    // Maybe an improvement geting warning mode and message from the customer
    // and calling super after do the warning checks
    perform_onchange: function(key, value) {
        var self=this;
        if (!value) {return;}
        if (key == "partner"){
            var partner_id = self.ts_model.db.partner_name_id[value];

            // Not partner found in backbone model
            if (value && !partner_id){
                var alert_msg = _t("Customer name '" + value + "' does not exist");
                alert(alert_msg);
                self.order_model.set('partner', "");
                self.refresh();
                self.$('#partner').focus();
            }
            else {
                var partner_obj = self.ts_model.db.get_partner_by_id(partner_id);
                var model = new Model("sale.order");
                model.call("ts_onchange_partner_id", [partner_id])
                .then(function(result){
                    var cus_name = self.ts_model.getComplexName(partner_obj);
                    self.order_model.set('partner', cus_name);
                    self.order_model.set('partner_code', partner_obj.ref ? partner_obj.ref : "");

                    self.order_model.set('customer_comment', partner_obj.comment);
                    // TODO nan_partner_risk migrar a la 10
                    // self.order_model.set('limit_credit', self.ts_model.my_round(partner_obj.credit_limit,2));
                    // self.order_model.set('customer_debt', self.ts_model.my_round(partner_obj.credit,2));

                    self.order_model.set('comercial', partner_obj.user_id ? partner_obj.user_id[1] : "");
                    var partner_shipp_obj = self.ts_model.db.get_partner_by_id(result.partner_shipping_id);
                    var shipp_addr =self.ts_model.getComplexName(partner_shipp_obj);
                    self.order_model.set('shipp_addr', shipp_addr);
                    var pricelist_obj = self.ts_model.db.pricelist_by_id[result.pricelist_id];
                    if (pricelist_obj){
                        self.order_model.set('pricelist', pricelist_obj.name);
                    }
                    // Get alert if warning is not false
                    if (result.warning){
                        alert(result.warning);
                        if (result.mode == 'block'){
                            self.order_model.set('partner', "");
                        }

                    }
                    self.refresh();
                    // New line and VUA button when chang
                    // Only do it when partner is setted
                    // if (self.order_model.get('partner')){
                    //     $('#vua-button').click();
                    // }
                    if(self.order_model.get('orderLines').length == 0 && self.order_model.get('partner')){
                        $('.add-line-button').click()
                    }
                    else{
                        self.$('#date_order').focus();
                    }

                });
            }
        }
        else if (key == "pricelist"){
            var pricelist_id = self.ts_model.db.pricelist_name_id[value];

            // Not partner found in backbone model
            if (!pricelist_id){
                var alert_msg = _t("Pricelist name '" + value + "' does not exist");
                alert(alert_msg);
                self.order_model.set('pricelist', "");
                self.refresh();
                self.$('#pricelist').focus();
            }
        }
    },
});

var TotalsOrderWidget = NewOrderWidgets.TotalsOrderWidget.include({
    renderElement: function(){
        var self=this;
        this._super();
        this.$('.proforma-button').click(function (){ self.promoCurrentOrder() });
        this.$('.print-alm-button').click(function (){ self.printAlmOrder() });
    },
    printAlmOrder: function() {
            var currentOrder = this.order_model;
            if (!currentOrder.get('erp_id')){
                alert(_t("You must save the order in the server in order to print it"));
                return;
            }
            this.do_action({
                 context: {'active_ids': [currentOrder.get('erp_id')]},
                 data: null,
                 name: 'Quotation / Order',
                 report_file: 'sale.report_saleorder',
                 report_name: 'sale.report_saleorder',
                 report_type: 'qweb-pdf',
                 type: 'ir.actions.report.xml'
            });
            // new Model('sale.order').call('print_order_from_ui',[currentOrder.get('erp_id')])
    },
    promoCurrentOrder: function() {
          var self = this;
            var currentOrder = this.order_model;
            self.saveCurrentOrder()
            $.when( self.ts_model.ready2 )
            .done(function(){
                var loaded = self.ts_model.fetch('sale.order',
                                                ['id', 'name'],
                                                [
                                                    ['chanel', '=', 'telesale']
                                                ])
                    .then(function(orders){
                       console.log('Entro')
                        if (orders[0]) {
                          // var my_id = orders[0].id
                          (new Model('sale.order')).call('ts_action_proforma',[orders[0].id])
                              .fail(function(unused, event){
                                  //don't show error popup if it fails
                                  console.error('Failed confirm order: ',orders[0].name);
                              })
                              .done(function(){
                                    console.log('Confirmado en segundo plano Yeeeeeah');
                              });

                        }
                    });
             });
        },

});

});

<commit_msg>[FIX]jim_telesale: Se establece el informe de pedido almacén para imprimir.<commit_after>odoo.define('jim_telesale.new_order_widgets2', function (require) {
"use strict";
var Model = require('web.DataModel');
var NewOrderWidgets = require('telesale.new_order_widgets');
var core = require('web.core');
var _t = core._t;

var OrderWidget = NewOrderWidgets.OrderWidget.include({
    create_line_from_vals: function(product_id, line_vals){
        var added_line = this.create_line_empty(product_id);
        added_line.set('qty', line_vals.qty || 1.0);
        added_line.set('pvp', line_vals.price || 0.0);
        added_line.set('discount', line_vals.discount || 0.0);
        added_line.set('taxes_ids', line_vals.tax_ids || []);
        added_line.update_line_values();
        return added_line;
    },

    // Creates a line with product and unit seted
    create_line_empty: function(product_id){
        var added_line = this._super(product_id);
        var product_obj = this.ts_model.db.get_product_by_id(product_id);
        var description = product_obj.name;
        if (product_obj.description_sale){
            description = description + '\n' + product.description_sale
        }
        added_line.set('description', description);
        return added_line;
    },

});

var OrderlineWidget = NewOrderWidgets.OrderlineWidget.include({

    // Link change chained discount to method
    set_input_handlers: function() {
        this._super();
        this.$('.col-chained_discount').change(_.bind(this.set_value, this, 'chained_discount'));
        this.$('.col-chained_discount').focus(_.bind(this.click_handler, this, 'chained_discount'));

        this.$('.col-description').blur(_.bind(this.set_value, this, 'description'));
        this.$('.col-description').focus(_.bind(this.click_handler, this, 'description'));
    },

    // Convert a chained discout like (10.5+20) in a float (20.5)
    // or returns false if something wrong.
    chained_discount2float: function(value){
        if (!value){
            return 0.0
        }
        var split_disc = value.split('+')
        var discount = 0.0
        var disc = 0
        for (var i in split_disc){
            disc = split_disc[i]
            if (isNaN(disc) || disc == "") {
               return false // Break
            }
            else{
              discount = discount + parseFloat(disc);
            }
        }
        return discount;

    },

    // Manage chained_discount
    set_value: function(key) {
        this._super(key)
        if (key == 'chained_discount'){
            var value = this.$('.col-chained_discount').val();

            var discount = this.chained_discount2float(value);
            if (!discount){
                alert(value + _t("is not a valid format for chained discount. It must be something like 23+5.2+1"));
                this.model.set('discount', 0.0);
                this.model.set('chained_discount', 0.0);
            }
            else{
                this.model.set('discount', discount);
            }
            this.refresh('chained_discount');
        }
    },

    perform_onchange: function(key){
        if (key == 'pvp'){
            this.refresh('chained_discount');
        }
        this._super(key);
    },

    // OVERWRITED Get global stock available in product_id change
    call_product_id_change: function(product_id, add_qty){
        var self = this;

        if (!add_qty){
            add_qty = 1.0
        }

        var customer_id = self.ts_model.db.partner_name_id[self.order.get('partner')];
        var pricelist_id = self.ts_model.db.pricelist_name_id[self.order.get('pricelist')];
        var model = new Model("sale.order.line");
        return model.call("ts_product_id_change", [product_id, customer_id, pricelist_id])
        .then(function(result){
            var product_obj = self.ts_model.db.get_product_by_id(product_id);
            var uom_obj = self.ts_model.db.get_unit_by_id(product_obj.uom_id[0])
            var description = product_obj.name;
            if (product_obj.description_sale){
                description = description + '\n' + product.description_sale
            }
            self.model.set('description', description);
            self.model.set('code', product_obj.default_code || "");
            self.model.set('product', product_obj.display_name || "");
            self.model.set('taxes_ids', result.tax_id || []); //TODO poner impuestos de producto o vacio
            self.model.set('unit', self.model.ts_model.db.unit_by_id[result.product_uom].name);
            self.model.set('qty', add_qty);
            self.model.set('discount', 0.0);
            self.model.set('pvp', self.ts_model.my_round( result.price_unit));

            var subtotal = self.model.get('pvp') * self.model.get('qty') * (1 - self.model.get('discount') / 100.0)
            self.model.set('total', self.ts_model.my_round(subtotal || 0,2));

            // ADDED
            self.model.set('global_available_stock', result.global_available_stock || 0.0)

            self.refresh('qty');
            self.$('.col-qty').select();
        });
    },

    renderElement: function() {
        // Set lqdr route_name and global_available_stock
        var prod_name = this.model.get("product");
        // var prod_name = this.$('.col-product').val();
        var product_id = this.ts_model.db.product_name_id[prod_name];
        var product_obj = false
        if (product_id){
            product_obj = this.ts_model.db.get_product_by_id(product_id);
        }
        // Get first vatiant related
        else{
            var template_obj = this.get_template();
            if (template_obj){
                product_id = template_obj.product_variant_ids[0];
                product_obj = this.ts_model.db.get_product_by_id(product_id)
            }
        }

        // Always set lqdr route name and description.
        if (product_obj){
            var lqdr = (product_obj.lqdr)  ? _t("Yes") : _t("No")
            // var description = product_obj.name;
            // if (product_obj.description_sale){
            //     description = description + '\n' + product.description_sale
            // }

            this.model.set('lqdr', lqdr);
            this.model.set('route_name', product_obj.route_name);
            // this.model.set('description', description);
        }

        //set handler for fiscount plus field.
        this._super();
    },
    control_arrow_keys: function(){
        var self=this;
        this._super()
        this.$('.col-chained_discount').keydown(function(event){
          var keyCode = event.keyCode || event.which;
          if (keyCode == 40) {  // KEY DOWWN (40)
                event.preventDefault();
                $(this).parent().parent().next().find('.col-chained_discount').select();

            }
            else if (keyCode == 38){  //KEY UP
                event.preventDefault();
                $(this).parent().parent().prev().find('.col-chained_discount').select();
            }
        });
    },
});

var DataOrderWidget = NewOrderWidgets.DataOrderWidget.include({
    // Overwrited to show warning  orblocking menssage menssagge
    // Maybe an improvement geting warning mode and message from the customer
    // and calling super after do the warning checks
    perform_onchange: function(key, value) {
        var self=this;
        if (!value) {return;}
        if (key == "partner"){
            var partner_id = self.ts_model.db.partner_name_id[value];

            // Not partner found in backbone model
            if (value && !partner_id){
                var alert_msg = _t("Customer name '" + value + "' does not exist");
                alert(alert_msg);
                self.order_model.set('partner', "");
                self.refresh();
                self.$('#partner').focus();
            }
            else {
                var partner_obj = self.ts_model.db.get_partner_by_id(partner_id);
                var model = new Model("sale.order");
                model.call("ts_onchange_partner_id", [partner_id])
                .then(function(result){
                    var cus_name = self.ts_model.getComplexName(partner_obj);
                    self.order_model.set('partner', cus_name);
                    self.order_model.set('partner_code', partner_obj.ref ? partner_obj.ref : "");

                    self.order_model.set('customer_comment', partner_obj.comment);
                    // TODO nan_partner_risk migrar a la 10
                    // self.order_model.set('limit_credit', self.ts_model.my_round(partner_obj.credit_limit,2));
                    // self.order_model.set('customer_debt', self.ts_model.my_round(partner_obj.credit,2));

                    self.order_model.set('comercial', partner_obj.user_id ? partner_obj.user_id[1] : "");
                    var partner_shipp_obj = self.ts_model.db.get_partner_by_id(result.partner_shipping_id);
                    var shipp_addr =self.ts_model.getComplexName(partner_shipp_obj);
                    self.order_model.set('shipp_addr', shipp_addr);
                    var pricelist_obj = self.ts_model.db.pricelist_by_id[result.pricelist_id];
                    if (pricelist_obj){
                        self.order_model.set('pricelist', pricelist_obj.name);
                    }
                    // Get alert if warning is not false
                    if (result.warning){
                        alert(result.warning);
                        if (result.mode == 'block'){
                            self.order_model.set('partner', "");
                        }

                    }
                    self.refresh();
                    // New line and VUA button when chang
                    // Only do it when partner is setted
                    // if (self.order_model.get('partner')){
                    //     $('#vua-button').click();
                    // }
                    if(self.order_model.get('orderLines').length == 0 && self.order_model.get('partner')){
                        $('.add-line-button').click()
                    }
                    else{
                        self.$('#date_order').focus();
                    }

                });
            }
        }
        else if (key == "pricelist"){
            var pricelist_id = self.ts_model.db.pricelist_name_id[value];

            // Not partner found in backbone model
            if (!pricelist_id){
                var alert_msg = _t("Pricelist name '" + value + "' does not exist");
                alert(alert_msg);
                self.order_model.set('pricelist', "");
                self.refresh();
                self.$('#pricelist').focus();
            }
        }
    },
});

var TotalsOrderWidget = NewOrderWidgets.TotalsOrderWidget.include({
    renderElement: function(){
        var self=this;
        this._super();
        this.$('.proforma-button').click(function (){ self.promoCurrentOrder() });
        this.$('.print-alm-button').click(function (){ self.printAlmOrder() });
    },
    printAlmOrder: function() {
            var currentOrder = this.order_model;
            if (!currentOrder.get('erp_id')){
                alert(_t("You must save the order in the server in order to print it"));
                return;
            }
            this.do_action({
                 model: 'sale.order',
                 context: {'active_ids': [currentOrder.get('erp_id')]},
                 data: null,
                 name: 'Quotation / Order',
                 report_file: 'custom_documents.custom_sale_order_report_warehouse',
                 report_name: 'custom_documents.custom_sale_order_report_warehouse',
                 report_type: 'qweb-pdf',
                 type: 'ir.actions.report.xml'
            });
            // new Model('sale.order').call('print_order_from_ui',[currentOrder.get('erp_id')])
    },
    promoCurrentOrder: function() {
          var self = this;
            var currentOrder = this.order_model;
            self.saveCurrentOrder()
            $.when( self.ts_model.ready2 )
            .done(function(){
                var loaded = self.ts_model.fetch('sale.order',
                                                ['id', 'name'],
                                                [
                                                    ['chanel', '=', 'telesale']
                                                ])
                    .then(function(orders){
                       console.log('Entro')
                        if (orders[0]) {
                          // var my_id = orders[0].id
                          (new Model('sale.order')).call('ts_action_proforma',[orders[0].id])
                              .fail(function(unused, event){
                                  //don't show error popup if it fails
                                  console.error('Failed confirm order: ',orders[0].name);
                              })
                              .done(function(){
                                    console.log('Confirmado en segundo plano Yeeeeeah');
                              });

                        }
                    });
             });
        },

});

});
<|endoftext|>


<commit_before>var ua = navigator.userAgent,
  android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
  ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
  ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
  iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
  os = {};

if (android) os.android = true, os.version = android[2];
if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
exports.os = os;

exports.isNil = function isNil(val) {
  return val==undefined || val == null || val==false;
}

exports.isFunction = function isFunction(val) {
  return typeof val=='function';
}

exports.apply = function apply(obj, config, promise) {
  var conf = isFunction(config)?config.call(obj):config;
  if (conf) {
    var attr;
    for (attr in conf) {
      obj[attr] = promise ? promise(conf[attr]) : conf[attr];
    }
  }
}

exports.el = function el(cls){
  return document.querySelector(cls);
}
<commit_msg>added html method<commit_after>var ua = navigator.userAgent,
  android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
  ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
  ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
  iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
  os = {};

if (android) os.android = true, os.version = android[2];
if (iphone && !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, '.') : null;

function isNil(val) {
  return val==undefined || val == null || val==false;
}

function isFunction(val) {
  return typeof val=='function';
}

function apply(obj, config, promise) {
  var conf = isFunction(config)?config.call(obj):config;
  if (conf) {
    var attr;
    for (attr in conf) {
      obj[attr] = promise ? promise(conf[attr]) : conf[attr];
    }
  }
}

function el(selector){
  return document.querySelector(selector);
}

function html(selector, htm){
  var ele = el(selector);
  return isNil(htm)?ele.innerHTML:(ele.innerHTML = htm);
}

exports.os = os;
exports.isNil = isNil;
exports.isFunction = isFunction;
exports.apply = apply;
exports.el = el;
exports.html = html;
<|endoftext|>


<commit_before>var id = 0,
    controls,
    btnAdd,
    tabTemplate;

$.fn.tabsControl = function () {
    var options = {
        'tabsListID': 'tabs-list',
        'tabsContainerID': 'tabs-container',
    };
    controls = initiazlizeContainers(options);
    btnAdd = initializeButtonAdd();
    tabTemplate = initializeTabTemplate();

    controls.tabMenu.append(btnAdd);
    $(this).append(controls.tabControlContainer);
    return $(this);
};

function initiazlizeContainers(options) {
    var container,
        output = {
            'tabControlContainer': $(),
            'tabMenu': $(),
            'tabContainer': $()
        };
    options.listID = options.listID ? options.listID : 'tabs-list';
    options.containerID = options.containerID ? options.containerID : 'tabs-container';
    options.container = options.container ? options.container : '#root';

    output.tabMenu = $('<ul />').attr('id', options.listID);
    output.tabContainer = $('<div />').attr('id', options.containerID);
    output.tabControlContainer = $('<div />')
        .addClass('tab-control-container')
        .append(output.tabMenu)
        .append(output.tabContainer);

    output.tabMenu.on('click', switchTabs)
    return output;
}

function switchTabs(event) {
    var clicked = $(event.target);

    if (clicked.hasClass('btn-add') || clicked.parents('.btn-add').length > 0) {
        return;
    }

    if (clicked.hasClass('tab')) {

    } else if (clicked.parents('.tab').length > 0) {
        clicked = clicked.parents('.tab').first();
    }

    console.log(clicked.data('tab-id'));
}

function initializeTabTemplate() {
    var output = {
        'idProvider': getId,
        'tabButton': null,
        'tabContent': null
    };
    output.tabButton = $('<a />').addClass('tab');
    output.tabContent = $('<div />').addClass('tab-content');
    return output;
}

function initializeButtonAdd() {
    var output = $('<a />')
        .addClass('tab')
        .addClass('btn-add')
        .html('New Tab');
    output.on('click', createNewTab);
    return output;
}

function createNewTab(options) {
    options.tabName = options.tabName ? options.tabName : 'new tab';

    var newTab = {
        'id': tabTemplate.idProvider(),
        'tabButton': tabTemplate.tabButton.clone(),
        'tabContent': tabTemplate.tabContent.clone()
    };
    newTab.tabButton
        .data('tab-id', newTab.id)
        .html(options.tabName)
        .appendTo(controls.tabMenu);
    newTab.tabContent
        .data('tab-id', newTab.id)
        .appendTo(controls.tabContainer);
    return newTab;
}

function getId() {
    id += 1;
    return id;
}<commit_msg>update<commit_after>var id = 0,
    controls,
    btnAdd,
    tabTemplate;

$.fn.tabsControl = function () {
    var options = {
        'tabsListID': 'tabs-list',
        'tabsContainerID': 'tabs-container',
    };
    controls = initiazlizeContainers(options);
    btnAdd = initializeButtonAdd();
    tabTemplate = initializeTabTemplate();

    controls.tabMenu.append(btnAdd);
    $(this).append(controls.tabControlContainer);
    return $(this);
};

function initiazlizeContainers(options) {
    var container,
        output = {
            'tabControlContainer': $(),
            'tabMenu': $(),
            'tabContainer': $()
        };
    options.listID = options.listID ? options.listID : 'tabs-list';
    options.containerID = options.containerID ? options.containerID : 'tabs-container';
    options.container = options.container ? options.container : '#root';

    output.tabMenu = $('<ul />').attr('id', options.listID);
    output.tabContainer = $('<div />').attr('id', options.containerID);
    output.tabControlContainer = $('<div />')
        .addClass('tab-control-container')
        .append(output.tabMenu)
        .append(output.tabContainer);

    output.tabMenu.on('click', switchTabs)
    return output;
}

function switchTabs(event) {
    var clicked = $(event.target);

    if (clicked.hasClass('btn-add') || clicked.parents('.btn-add').length > 0) {
        return;
    }

    if (clicked.hasClass('tab')) {

    } else if (clicked.parents('.tab').length > 0) {
        clicked = clicked.parents('.tab').first();
    }

    console.log(clicked.data('tab-id'));
}

function initializeTabTemplate() {
    var output = {
        'idProvider': getId,
        'tabButton': null,
        'removeButton': null,
        'tabName': null,
        'tabContent': null
    };
    output.tabButton = $('<div />').addClass('tab');
    output.tabName = $('<strong />')
        .addClass('tab-name')
        .appendTo(output.tabButton);
    output.removeButton = $('<a />')
        .addClass('btn-remove')
        .html('X')
        .appendTo(output.tabButton);
    output.tabContent = $('<div />').addClass('tab-content');
    return output;
}

function initializeButtonAdd() {
    var output = $('<a />')
        .addClass('tab')
        .addClass('btn-add')
        .html('New Tab');
    output.on('click', createNewTab);
    return output;
}

function createNewTab(options) {
    options.tabName = options.tabName ? options.tabName : 'new tab';

    var newTab = {
        'id': tabTemplate.idProvider(),
        'tabButton': tabTemplate.tabButton.clone(),
        'tabContent': tabTemplate.tabContent.clone()
    };
    newTab.tabButton
        .children('.tab-name')
        .first()
        .html(options.tabName);
    newTab.tabButton
        .data('tab-id', newTab.id)
        .appendTo(controls.tabMenu);
    newTab.tabContent
        .data('tab-id', newTab.id)
        .appendTo(controls.tabContainer);
    return newTab;
}

function getId() {
    id += 1;
    return id;
}<|endoftext|>