cdb.admin.overlays.Image = cdb.admin.overlays.Text.extend({ className: "image overlay snap", events: { "mouseenter .text": "_onMouseEnter", "click .close": "_close", "click .content": "_onClickEdit", "click .text": "_onClickEdit", "dblclick .content": "_onDblClick", "dblclick .text": "_onDblClick", "keyup .text": "_onKeyUp", "paste .text": "_onPaste" }, initialize: function() { _.bindAll(this, "_close", "_onDblClick", "_onChangeMode", "_onKeyDown", "_onLoadSuccess", "_onLoadError"); // Bind ESC key $(document).bind('keydown', this._onKeyDown); this.template = this.getTemplate('table/views/overlays/image'); this.image_template = _.template(""); this._setupModels(); this.form_data = [{ name: 'Box', form: { 'box-color': { type: 'color', value: '#000', extra: { tick: "left", picker_vertical_position: "down", picker_horizontal_position: "left" }}, 'box-opacity': { type: 'simple_opacity', value: .7, min:0, max:1, inc: .1, disable_triggering: true }, } }, { name: 'Width', form: { 'box-width': { type: 'simple_number', value: 300, min: 50, max: 2000, inc: 10, disable_triggering: true }, } }]; }, // Setup the internal and custom model _setupModels: function() { var self = this; var extra = this.model.get("extra"); this.model.set({ url: extra.url }, { silent: true }); var applyStyle = function() { self._applyStyle(true); }; // Bindings this.model.bind('remove', this.hide, this); this.model.bind('change:url', this._setURL, this); this.model.bind('change:style', applyStyle, this); this.model.bind('change:extra', this._onChangeExtra, this); this.model.bind('change:display', this._onChangeDisplay, this); this.model.bind('change:selected', this._onChangeSelected, this); // Internal model to store the editing state this.editModel = new cdb.core.Model({ mode: "" }); this.editModel.bind('change:mode', this._onChangeMode, this); this.add_related_model(this.editModel); }, // Element events _onKeyUp: function(e) { var self = this; var temp = ""; var domString = ""; if (this.timeout) clearTimeout(this.timeout); if (this.keyUpTimeout) clearTimeout(this.keyUpTimeout); if (this.savingTimeout) clearTimeout(this.savingTimeout); var value = this.$text.html(); if (cdb.Utils.stripHTML(value) == "") { this.keyUpTimeout = setTimeout(function() { self.model.set({ url: "" }, { silent: true }); self._close(); }, 600); } else { if (cdb.Utils.isURL(value)) { this.model.set({ url: value }, { silent: true }); } if (!this.$el.hasClass("hover") && this.$text.text()) { this.savingTimeout = setTimeout(function() { self._disableEditingMode(); }, 500); } } }, _onPaste: function(e) { var self = this; setTimeout(function() { var text = cdb.Utils.stripHTML(self.$text.text()); if (cdb.Utils.isURL(text)) { self.model.set("url", text); self.editModel.set("mode", "loading"); } }, 300); }, _onMouseDown: function() { }, _onMouseEnterText: function() { }, _onMouseLeaveText: function() { }, /* * Applies style to the content of the overlay */ _applyStyle: function(save) { var style = this.model.get("style"); var boxColor = style["box-color"]; var boxOpacity = style["box-opacity"]; var boxWidth = style["box-width"]; this.$text.css(style); this.$text.css("font-size", style["font-size"] + "px"); this.$el.css("z-index", style["z-index"]); var rgbaCol = 'rgba(' + parseInt(boxColor.slice(-6,-4),16) + ',' + parseInt(boxColor.slice(-4,-2),16) + ',' + parseInt(boxColor.slice(-2),16) +', ' + boxOpacity + ' )'; this.$el.css("background-color", rgbaCol); this.$("img").css("width", boxWidth); if (save) this.model.save(); }, _enableEditingMode: function() { var self = this; var text = this.model.get("url"); this.$el .removeClass("error") .addClass("editable disabled"); this.$text.attr("contenteditable", true).focus(); setTimeout(function() { var h = self.$text.outerHeight(true); var w = self.$text.width(); self.$text.html(text); self.$text.css({ minWidth: w }); }, 100); }, _disableEditingMode: function() { var url = this.model.get("url"); var style = this.model.get("style"); var boxWidth = style["box-width"]; var extra = this.model.get("extra"); var img = ""; this.$el.removeClass("editable disabled"); this.editModel.set("mode", ""); if (!this.error) this.$el.removeClass("error"); else this.$el.addClass("error"); this.$text.html(img); this.$text.attr("contenteditable", false); extra.url = url; extra.rendered_text = this.image_template({ url: url, width: boxWidth }); if (extra.url !== extra.default_image_url) { extra.has_default_image = false; } this.model.set({ extra: extra }, { silent: true }); this.model.save(); this.$text.css({ height: "auto", minHeight: "0", minWidth: "0" }); }, _setURL: function() { this._loadImage(this.model.get("url")); }, _loadImage: function(url) { var self = this; var success = function() { self._onLoadSuccess(url); }; var error = function() { self._onLoadError(url); }; $("") .load(success) .error(error) .attr("src", url); }, _onLoadError: function(url) { this.$el.addClass('error'); this.error = true; }, _onLoadSuccess: function(url) { this.$el.removeClass("error"); this.error = false; var style = this.model.get("style"); var boxWidth = style["box-width"]; var extra = this.model.get("extra"); var img = this.image_template({ url: url, width: boxWidth }); extra.rendered_text = img; this.model.set({ extra: extra }, { silent: true }); this.$el.removeClass("editable disabled"); this.$text.html(img); this.$text.attr("contenteditable", false); this.$text.css("height", "auto"); this.editModel.set("mode", ""); if (this.model.get("display")) { this.show(); } }, _addDropdown: function() { this.dropdown = new cdb.admin.OverlayPropertiesDropdown({ tick: "left", target: this.$(".edit"), model: this.model, horizontal_position: "left", horizontal_offset: 26, vertical_offset: 24, template_base: 'table/views/overlays/properties_dropdown', form_data: this.form_data }); var self = this; this.dropdown.on("saved", function() { self.dropdown.move(); }); this._bindDropdown(); this.$el.append(this.dropdown.render().el); }, _bindDropdown: function() { this.dropdown.bind("onDropdownShown", function() { this.$el.addClass("open"); }, this); this.dropdown.bind("onDropdownHidden", function() { this.$el.removeClass("open"); }, this); cdb.god.bind("closeDialogs", this.dropdown.hide, this.dropdown); }, _onChangeMode: function() { var mode = this.editModel.get("mode"); this.trigger('editing', mode === 'editable', this); if (mode === "editable") { this._enableEditingMode(); } else { this._disableEditingMode(); } }, clean: function() { $(document).unbind('keydown', this._onKeyDown, this); cdb.core.View.prototype.clean.call(this); }, render: function() { this._place(); this.$el.append(this.template()); this.$text = this.$(".content div.text"); this._setURL(); this._applyStyle(false); this.$el.addClass(this.model.get("device")); cdb.god.unbind("closeDialogs", this._onCloseDialogs, this); cdb.god.bind("closeDialogs", this._onCloseDialogs, this); return this; } });