diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-02-12 18:08:27 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-02-12 18:08:27 +0100 |
| commit | 0f02dcb63918228d48df50f2d5805b7fda25c14a (patch) | |
| tree | 9f83e1687755404c5cd7b5e1a12ae85d29f2d483 /addons/web_editor/static/src/js | |
| parent | 83354c2b24bc6c9db1fb63440115d2d4db5bd4ef (diff) | |
| parent | c69d00157ed2162b873a07a9f317016f109f802a (diff) | |
[MERGE] forward port branch saas-11.1 up to c69d00157ed
Diffstat (limited to 'addons/web_editor/static/src/js')
8 files changed, 138 insertions, 60 deletions
diff --git a/addons/web_editor/static/src/js/backend/fields.js b/addons/web_editor/static/src/js/backend/fields.js index b84fcd21c91..d3d601bac73 100644 --- a/addons/web_editor/static/src/js/backend/fields.js +++ b/addons/web_editor/static/src/js/backend/fields.js @@ -118,6 +118,7 @@ var FieldTextHtmlSimple = basic_fields.DebouncedField.extend(TranslatableFieldMi */ _getValue: function () { if (this.nodeOptions['style-inline']) { + transcoder.linkImgToAttachmentThumbnail(this.$content); transcoder.classToStyle(this.$content); transcoder.fontToImg(this.$content); } @@ -133,6 +134,8 @@ var FieldTextHtmlSimple = basic_fields.DebouncedField.extend(TranslatableFieldMi this.$textarea.summernote(this._getSummernoteConfig()); this.$content = this.$('.note-editable:first'); this.$content.html(this._textToHtml(this.value)); + this.$content.data('oe-id', this.recordData.res_id || this.res_id); + this.$content.data('oe-model', this.recordData.model || this.model); // trigger a mouseup to refresh the editor toolbar this.$content.trigger('mouseup'); if (this.nodeOptions['style-inline']) { diff --git a/addons/web_editor/static/src/js/editor/rte.summernote.js b/addons/web_editor/static/src/js/editor/rte.summernote.js index d2613f42635..fb4d6fc7206 100644 --- a/addons/web_editor/static/src/js/editor/rte.summernote.js +++ b/addons/web_editor/static/src/js/editor/rte.summernote.js @@ -1084,8 +1084,12 @@ var SummernoteManager = Class.extend(mixins.EventDispatcherMixin, { return; } data.__alreadyDone = true; + var mediaDialog = new weWidgets.MediaDialog(this, - data.options || {}, + _.extend({ + res_model: data.$editable.data('oe-model'), + res_id: data.$editable.data('oe-id'), + }, data.options), data.$editable, data.media ); diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 24d9663a058..188b563f238 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -813,9 +813,12 @@ registry.background = SnippetOption.extend({ // Put fake image in the DOM, edit it and use it as background-image var $image = $('<img/>', {class: 'hidden', src: value}).appendTo(this.$target); + var $editable = this.$target.closest('.o_editable'); var _editor = new weWidgets.MediaDialog(this, { onlyImages: true, firstFilters: ['background'], + res_model: $editable.data('oe-model'), + res_id: $editable.data('oe-id'), }, null, $image[0]).open(); _editor.on('save', this, function () { diff --git a/addons/web_editor/static/src/js/editor/summernote.js b/addons/web_editor/static/src/js/editor/summernote.js index 59609eab8a5..121a1a6d3d7 100644 --- a/addons/web_editor/static/src/js/editor/summernote.js +++ b/addons/web_editor/static/src/js/editor/summernote.js @@ -913,15 +913,21 @@ range.WrappedRange.prototype.deleteContents = function (towrite) { return this; } - var prevBP = dom.removeBetween(this.sc, this.so, this.ec, this.eo, towrite); + var r; + var image = this.isOnImg(); + if (image) { + // If the range matches/is in an image, then the image is to be removed + // and the cursor moved to its previous position + var parentNode = image.parentNode; + var index = _.indexOf(parentNode.childNodes, image); + parentNode.removeChild(image); + r = new range.WrappedRange(parentNode, index, parentNode, index); + } else { + r = dom.removeBetween(this.sc, this.so, this.ec, this.eo, towrite); + } - $(dom.node(prevBP.sc)).trigger("click"); // trigger click to disable and reanable editor and image handler - return new range.WrappedRange( - prevBP.sc, - prevBP.so, - prevBP.ec, - prevBP.eo - ); + $(dom.node(r.sc)).trigger("click"); // trigger click to disable and reanable editor and image handler + return new range.WrappedRange(r.sc, r.so, r.ec, r.eo); }; range.WrappedRange.prototype.clean = function (mergeFilter, all) { var node = dom.node(this.sc === this.ec ? this.sc : this.commonAncestor()); @@ -1258,7 +1264,7 @@ $.summernote.pluginEvents.visible = function (event, editor, layoutInfo) { }; function remove_table_content(r) { - var nodes = dom.listBetween(r.sc, r.ec); + var nodes = dom.listBetween(r.sc, r.ec, r.so, r.eo); if (dom.isText(r.sc)) { r.sc.textContent = r.sc.textContent.slice(0, r.so); } diff --git a/addons/web_editor/static/src/js/editor/transcoder.js b/addons/web_editor/static/src/js/editor/transcoder.js index 058ea8ebcc7..6fd57c0330b 100644 --- a/addons/web_editor/static/src/js/editor/transcoder.js +++ b/addons/web_editor/static/src/js/editor/transcoder.js @@ -18,7 +18,7 @@ function getMatchedCSSRules(a) { var sheets = document.styleSheets; for (i = sheets.length-1 ; i >= 0 ; i--) { var rules; - if (sheets[i].rules) { + if (sheets[i].hasOwnProperty('rules')) { rules = sheets[i].rules; } else { // try...catch because Firefox not able to enumerate @@ -259,10 +259,40 @@ function styleToClass($editable) { $c.remove(); } +/** + * Converts css display for attachment link to real image. + * Without this post process, the display depends on the css and the picture + * does not appear when we use the html without css (to send by email for e.g.) + * + * @param {jQuery} $editable + */ +function attachmentThumbnailToLinkImg($editable) { + $editable.find('a[href*="/web/content/"][data-mimetype]:empty').each(function () { + var $link = $(this); + var $img = $('<img/>') + .attr('src', $link.css('background-image').replace(/(^url\(['"])|(['"]\)$)/g, '')) + .css('height', Math.max(1, $link.height()) + 'px') + .css('width', Math.max(1, $link.width()) + 'px'); + $link.append($img); + }); +} + +/** + * Revert attachmentThumbnailToLinkImg changes + * + * @see attachmentThumbnailToLinkImg + * @param {jQuery} $editable + */ +function linkImgToAttachmentThumbnail($editable) { + $editable.find('a[href*="/web/content/"][data-mimetype] > img').remove(); +} + return { fontToImg: fontToImg, imgToFont: imgToFont, classToStyle: classToStyle, styleToClass: styleToClass, + attachmentThumbnailToLinkImg: attachmentThumbnailToLinkImg, + linkImgToAttachmentThumbnail: linkImgToAttachmentThumbnail, }; }); diff --git a/addons/web_editor/static/src/js/inline.js b/addons/web_editor/static/src/js/inline.js index 7480b2228fa..b1de23cb293 100644 --- a/addons/web_editor/static/src/js/inline.js +++ b/addons/web_editor/static/src/js/inline.js @@ -53,6 +53,7 @@ snippet_editor.Class.include({ this._super.apply(this, arguments); var $editable = $('#editable_area'); + transcoder.linkImgToAttachmentThumbnail($editable); transcoder.fontToImg($editable); transcoder.classToStyle($editable); diff --git a/addons/web_editor/static/src/js/widgets/ace.js b/addons/web_editor/static/src/js/widgets/ace.js index 6c28c1e2332..0a89d0d8ce7 100644 --- a/addons/web_editor/static/src/js/widgets/ace.js +++ b/addons/web_editor/static/src/js/widgets/ace.js @@ -742,7 +742,7 @@ var ViewEditor = Widget.extend({ var text = data.text || ''; if (!isSelected) { - text = Array($elem.data('level') + 1).join('-') + ' ' + text; + text = Array(($elem.data('level') || 0) + 1).join('-') + ' ' + text; } var $div = $('<div/>', { text: text, diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js index 6791a21f721..c9659e04eab 100644 --- a/addons/web_editor/static/src/js/widgets/widgets.js +++ b/addons/web_editor/static/src/js/widgets/widgets.js @@ -206,13 +206,16 @@ var ImageWidget = MediaWidget.extend({ this.IMAGES_PER_PAGE = this.IMAGES_PER_ROW * this.IMAGES_ROWS; + this.options = options; this.accept = options.accept || (options.document ? '*/*' : 'image/*'); - this.domain = options.domain - || [ - '|', - ['mimetype', '=', false], - ['mimetype', options.document ? 'not in' : 'in', ['image/gif', 'image/jpe', 'image/jpeg', 'image/jpg', 'image/gif', 'image/png']] - ]; + if (options.res_id) { + this.domain = ['|', + '&', ['res_model', '=', options.res_model], ['res_id', '=', options.res_id], + ['res_model', '=', 'ir.ui.view']]; + } else { + this.domain = [['res_model', '=', 'ir.ui.view']]; + } + this.multiImages = options.multiImages; this.firstFilters = options.firstFilters || []; @@ -279,32 +282,55 @@ var ImageWidget = MediaWidget.extend({ * @override */ save: function () { + var self = this; if (this.multiImages) { return this.images; } var img = this.images[0]; - if (!img.isDocument) { - if (!this.$media.is('img')) { - this._replaceMedia($('<img/>')); - } - this.$media.attr('src', img.src); - } else { - if (!this.$media.is('a')) { - $('.note-control-selection').hide(); - this._replaceMedia($('<a/>')); - } - this.$media.attr('href', '/web/content/' + img.id + '?unique=' + img.checksum + '&download=true'); - this.$media.addClass('o_image').attr('title', img.name).attr('data-mimetype', img.mimetype); + var def = $.when(); + if (!img.access_token) { + def = this._rpc({ + model: 'ir.attachment', + method: 'generate_access_token', + args: [[img.id]] + }).then(function (access_token) { + img.access_token = access_token[0]; + }); } - this.$media.attr('alt', img.alt); - var style = this.style; - if (style) { - this.$media.css(style); - } + return def.then(function () { + if (!img.isDocument) { + if (img.access_token && self.options.res_model !== 'ir.ui.view') { + img.src += _.str.sprintf('?access_token=%s', img.access_token); + } + if (!self.$media.is('img')) { + self._replaceMedia($('<img/>')); + } + self.$media.attr('src', img.src); - return this.media; + } else { + if (!self.$media.is('a')) { + $('.note-control-selection').hide(); + self._replaceMedia($('<a/>')); + } + var href = '/web/content/' + img.id + '?'; + if (img.access_token && self.options.res_model !== 'ir.ui.view') { + href += _.str.sprintf('access_token=%s&', img.access_token); + } + href += 'unique=' + img.checksum + '&download=true'; + self.$media.attr('href', href); + self.$media.addClass('o_image').attr('title', img.name).attr('data-mimetype', img.mimetype); + } + + self.$media.attr('alt', img.alt); + var style = self.style; + if (style) { + self.$media.css(style); + } + + return self.media; + }); }, /** * @override @@ -314,7 +340,7 @@ var ImageWidget = MediaWidget.extend({ if (!noRender) { this.$('input.url').val('').trigger('input').trigger('change'); } - var domain = [['res_model', '=', 'ir.ui.view']].concat(this.domain); + var domain = this.domain.concat(['|', ['mimetype', '=', false], ['mimetype', this.options.document ? 'not in' : 'in', ['image/gif', 'image/jpe', 'image/jpeg', 'image/jpg', 'image/gif', 'image/png']]]); if (needle && needle.length) { domain.push('|', ['datas_fname', 'ilike', needle], ['name', 'ilike', needle]); } @@ -324,7 +350,7 @@ var ImageWidget = MediaWidget.extend({ args: [], kwargs: { domain: domain, - fields: ['name', 'datas_fname', 'mimetype', 'checksum', 'url', 'type'], + fields: ['name', 'datas_fname', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'access_token'], order: [{name: 'id', asc: false}], context: weContext.get(), }, @@ -354,7 +380,7 @@ var ImageWidget = MediaWidget.extend({ .value(); _.each(self.records, function (record) { - record.src = record.url || _.str.sprintf('/web/image/%s/%s', record.id, record.name); // Name is added for SEO purposes + record.src = record.url || _.str.sprintf('/web/image/%s/%s', record.id, encodeURI(record.name)); // Name is added for SEO purposes record.isDocument = !(/gif|jpe|jpg|png/.test(record.mimetype)); }); if (!noRender) { @@ -1143,11 +1169,15 @@ var MediaDialog = Dialog.extend({ */ save: function () { var self = this; + var args = arguments; + var _super = this._super; if (this.multiImages) { // In the case of multi images selection we suppose this was not to // replace an old media, so we only retrieve the images and save. - this.final_data = this.active.save(); - return this._super.apply(this, arguments); + return $.when(this.active.save()).then(function (data) { + self.final_data = data; + return _super.apply(self, args); + }); } if (this.rte) { @@ -1164,28 +1194,29 @@ var MediaDialog = Dialog.extend({ } }); } - var media = this.active.save(); - if (!this.media) { - this.range.insertNode(media, true); - } - this.media = media; - this.$media = $(media); - this.final_data = this.media; - $(this.final_data).trigger('input').trigger('save'); - $(document.body).trigger("media-saved", this.final_data); // TODO get rid of this - - // Update editor bar after image edition (in case the image change to icon or other) - _.defer(function () { - if (!self.media.parentNode) { - return; + return $.when(this.active.save()).then(function (media) { + if (!self.media) { + self.range.insertNode(media, true); } - range.createFromNode(self.media).select(); - simulateMouseEvent(self.media, 'mousedown'); - simulateMouseEvent(self.media, 'mouseup'); - }); + self.media = media; + self.$media = $(media); - return this._super.apply(this, arguments); + self.final_data = self.media; + $(self.final_data).trigger('input').trigger('save'); + $(document.body).trigger("media-saved", self.final_data); // TODO get rid of this + + // Update editor bar after image edition (in case the image change to icon or other) + _.defer(function () { + if (!self.media.parentNode) { + return; + } + range.createFromNode(self.media).select(); + simulateMouseEvent(self.media, 'mousedown'); + simulateMouseEvent(self.media, 'mouseup'); + }); + return _super.apply(self, args); + }); }, //-------------------------------------------------------------------------- |
