cartodb-4.42/lib/assets/javascripts/cartodb/table/overlays/image.js

363 lines
8.1 KiB
JavaScript
Raw Normal View History

2024-04-06 13:25:13 +08:00
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("<img src='<%- url %>' style='width: <%- width %>px'/>");
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 = "<img src='" + url + "' style='width: " + boxWidth + "px'/>";
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);
};
$("<img/>")
.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;
}
});