From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- addons/web_editor/static/src/img/curved_arrow.svg | 14 + .../web_editor/static/src/img/snippet_disabled.svg | 7 + .../static/src/img/snippets_options/bg_shape.svg | 11 + .../img/snippets_options/o_overlay_move_drag.svg | 12 + .../static/src/js/backend/convert_inline.js | 485 ++ .../web_editor/static/src/js/backend/field_html.js | 536 +++ addons/web_editor/static/src/js/base.js | 173 + addons/web_editor/static/src/js/common/ace.js | 944 ++++ addons/web_editor/static/src/js/common/utils.js | 266 ++ .../static/src/js/editor/custom_colors.js | 0 addons/web_editor/static/src/js/editor/editor.js | 289 ++ .../static/src/js/editor/image_processing.js | 335 ++ addons/web_editor/static/src/js/editor/rte.js | 816 ++++ .../static/src/js/editor/rte.summernote.js | 1280 +++++ .../static/src/js/editor/snippets.editor.js | 2776 +++++++++++ .../static/src/js/editor/snippets.options.js | 4908 ++++++++++++++++++++ .../web_editor/static/src/js/editor/summernote.js | 2527 ++++++++++ addons/web_editor/static/src/js/frontend/loader.js | 28 + .../static/src/js/frontend/loader_loading.js | 33 + addons/web_editor/static/src/js/wysiwyg/fonts.js | 99 + addons/web_editor/static/src/js/wysiwyg/root.js | 91 + .../static/src/js/wysiwyg/widgets/alt_dialog.js | 62 + .../static/src/js/wysiwyg/widgets/color_palette.js | 410 ++ .../static/src/js/wysiwyg/widgets/dialog.js | 81 + .../src/js/wysiwyg/widgets/image_crop_widget.js | 213 + .../static/src/js/wysiwyg/widgets/link_dialog.js | 339 ++ .../static/src/js/wysiwyg/widgets/media.js | 1463 ++++++ .../static/src/js/wysiwyg/widgets/media_dialog.js | 279 ++ .../static/src/js/wysiwyg/widgets/widgets.js | 29 + addons/web_editor/static/src/js/wysiwyg/wysiwyg.js | 274 ++ .../static/src/js/wysiwyg/wysiwyg_iframe.js | 132 + .../static/src/js/wysiwyg/wysiwyg_snippets.js | 56 + .../src/js/wysiwyg/wysiwyg_translate_attributes.js | 0 ...3_0_color_system_support_primary_variables.scss | 1 + .../static/src/scss/bootstrap_overridden.scss | 76 + .../src/scss/bootstrap_overridden_backend.scss | 14 + .../static/src/scss/secondary_variables.scss | 137 + .../static/src/scss/web_editor.backend.scss | 69 + .../static/src/scss/web_editor.common.scss | 782 ++++ .../static/src/scss/web_editor.frontend.scss | 74 + .../static/src/scss/web_editor.variables.scss | 728 +++ addons/web_editor/static/src/scss/wysiwyg.scss | 522 +++ .../web_editor/static/src/scss/wysiwyg_iframe.scss | 27 + .../static/src/scss/wysiwyg_snippets.scss | 1951 ++++++++ addons/web_editor/static/src/xml/ace.xml | 63 + addons/web_editor/static/src/xml/backend.xml | 20 + addons/web_editor/static/src/xml/editor.xml | 42 + addons/web_editor/static/src/xml/snippets.xml | 102 + addons/web_editor/static/src/xml/wysiwyg.xml | 579 +++ .../static/src/xml/wysiwyg_colorpicker.xml | 33 + 50 files changed, 24188 insertions(+) create mode 100644 addons/web_editor/static/src/img/curved_arrow.svg create mode 100644 addons/web_editor/static/src/img/snippet_disabled.svg create mode 100644 addons/web_editor/static/src/img/snippets_options/bg_shape.svg create mode 100644 addons/web_editor/static/src/img/snippets_options/o_overlay_move_drag.svg create mode 100644 addons/web_editor/static/src/js/backend/convert_inline.js create mode 100644 addons/web_editor/static/src/js/backend/field_html.js create mode 100644 addons/web_editor/static/src/js/base.js create mode 100644 addons/web_editor/static/src/js/common/ace.js create mode 100644 addons/web_editor/static/src/js/common/utils.js create mode 100644 addons/web_editor/static/src/js/editor/custom_colors.js create mode 100644 addons/web_editor/static/src/js/editor/editor.js create mode 100644 addons/web_editor/static/src/js/editor/image_processing.js create mode 100644 addons/web_editor/static/src/js/editor/rte.js create mode 100644 addons/web_editor/static/src/js/editor/rte.summernote.js create mode 100644 addons/web_editor/static/src/js/editor/snippets.editor.js create mode 100644 addons/web_editor/static/src/js/editor/snippets.options.js create mode 100644 addons/web_editor/static/src/js/editor/summernote.js create mode 100644 addons/web_editor/static/src/js/frontend/loader.js create mode 100644 addons/web_editor/static/src/js/frontend/loader_loading.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/fonts.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/root.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/alt_dialog.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/color_palette.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/dialog.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/image_crop_widget.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/media.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/media_dialog.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/widgets/widgets.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/wysiwyg.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/wysiwyg_iframe.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/wysiwyg_snippets.js create mode 100644 addons/web_editor/static/src/js/wysiwyg/wysiwyg_translate_attributes.js create mode 100644 addons/web_editor/static/src/scss/13_0_color_system_support_primary_variables.scss create mode 100644 addons/web_editor/static/src/scss/bootstrap_overridden.scss create mode 100644 addons/web_editor/static/src/scss/bootstrap_overridden_backend.scss create mode 100644 addons/web_editor/static/src/scss/secondary_variables.scss create mode 100644 addons/web_editor/static/src/scss/web_editor.backend.scss create mode 100644 addons/web_editor/static/src/scss/web_editor.common.scss create mode 100644 addons/web_editor/static/src/scss/web_editor.frontend.scss create mode 100644 addons/web_editor/static/src/scss/web_editor.variables.scss create mode 100644 addons/web_editor/static/src/scss/wysiwyg.scss create mode 100644 addons/web_editor/static/src/scss/wysiwyg_iframe.scss create mode 100644 addons/web_editor/static/src/scss/wysiwyg_snippets.scss create mode 100644 addons/web_editor/static/src/xml/ace.xml create mode 100644 addons/web_editor/static/src/xml/backend.xml create mode 100644 addons/web_editor/static/src/xml/editor.xml create mode 100644 addons/web_editor/static/src/xml/snippets.xml create mode 100644 addons/web_editor/static/src/xml/wysiwyg.xml create mode 100644 addons/web_editor/static/src/xml/wysiwyg_colorpicker.xml (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/img/curved_arrow.svg b/addons/web_editor/static/src/img/curved_arrow.svg new file mode 100644 index 00000000..a8ed9acd --- /dev/null +++ b/addons/web_editor/static/src/img/curved_arrow.svg @@ -0,0 +1,14 @@ + + + + + diff --git a/addons/web_editor/static/src/img/snippet_disabled.svg b/addons/web_editor/static/src/img/snippet_disabled.svg new file mode 100644 index 00000000..1d506689 --- /dev/null +++ b/addons/web_editor/static/src/img/snippet_disabled.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/addons/web_editor/static/src/img/snippets_options/bg_shape.svg b/addons/web_editor/static/src/img/snippets_options/bg_shape.svg new file mode 100644 index 00000000..838ddc53 --- /dev/null +++ b/addons/web_editor/static/src/img/snippets_options/bg_shape.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/addons/web_editor/static/src/img/snippets_options/o_overlay_move_drag.svg b/addons/web_editor/static/src/img/snippets_options/o_overlay_move_drag.svg new file mode 100644 index 00000000..7d701fa3 --- /dev/null +++ b/addons/web_editor/static/src/img/snippets_options/o_overlay_move_drag.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/addons/web_editor/static/src/js/backend/convert_inline.js b/addons/web_editor/static/src/js/backend/convert_inline.js new file mode 100644 index 00000000..071caa3f --- /dev/null +++ b/addons/web_editor/static/src/js/backend/convert_inline.js @@ -0,0 +1,485 @@ +odoo.define('web_editor.convertInline', function (require) { +'use strict'; + +var FieldHtml = require('web_editor.field.html'); + +/** + * Returns the css rules which applies on an element, tweaked so that they are + * browser/mail client ok. + * + * @param {DOMElement} a + * @returns {Object} css property name -> css property value + */ +function getMatchedCSSRules(a) { + var i, r, k; + var doc = a.ownerDocument; + var rulesCache = a.ownerDocument._rulesCache || (a.ownerDocument._rulesCache = []); + + if (!rulesCache.length) { + var sheets = doc.styleSheets; + for (i = sheets.length-1 ; i >= 0 ; i--) { + var rules; + // try...catch because browser may not able to enumerate rules for cross-domain sheets + try { + rules = sheets[i].rules || sheets[i].cssRules; + } catch (e) { + console.warn("Can't read the css rules of: " + sheets[i].href, e); + continue; + } + if (rules) { + for (r = rules.length-1; r >= 0; r--) { + var selectorText = rules[r].selectorText; + if (selectorText && + rules[r].cssText && + selectorText !== '*' && + selectorText.indexOf(':hover') === -1 && + selectorText.indexOf(':before') === -1 && + selectorText.indexOf(':after') === -1 && + selectorText.indexOf(':active') === -1 && + selectorText.indexOf(':link') === -1 && + selectorText.indexOf('::') === -1 && + selectorText.indexOf("'") === -1) { + var st = selectorText.split(/\s*,\s*/); + for (k = 0 ; k < st.length ; k++) { + rulesCache.push({ 'selector': st[k], 'style': rules[r].style }); + } + } + } + } + } + rulesCache.reverse(); + } + + var css = []; + var style; + a.matches = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.msMatchesSelector || a.oMatchesSelector; + for (r = 0; r < rulesCache.length; r++) { + if (a.matches(rulesCache[r].selector)) { + style = rulesCache[r].style; + if (style.parentRule) { + var style_obj = {}; + var len; + for (k = 0, len = style.length ; k < len ; k++) { + if (style[k].indexOf('animation') !== -1) { + continue; + } + style_obj[style[k]] = style[style[k].replace(/-(.)/g, function (a, b) { return b.toUpperCase(); })]; + if (new RegExp(style[k] + '\s*:[^:;]+!important' ).test(style.cssText)) { + style_obj[style[k]] += ' !important'; + } + } + rulesCache[r].style = style = style_obj; + } + css.push([rulesCache[r].selector, style]); + } + } + + function specificity(selector) { + // http://www.w3.org/TR/css3-selectors/#specificity + var a = 0; + selector = selector.replace(/#[a-z0-9_-]+/gi, function () { a++; return ''; }); + var b = 0; + selector = selector.replace(/(\.[a-z0-9_-]+)|(\[.*?\])/gi, function () { b++; return ''; }); + var c = 0; + selector = selector.replace(/(^|\s+|:+)[a-z0-9_-]+/gi, function (a) { if (a.indexOf(':not(')===-1) c++; return ''; }); + return a*100 + b*10 + c; + } + css.sort(function (a, b) { return specificity(a[0]) - specificity(b[0]); }); + + style = {}; + _.each(css, function (v,k) { + _.each(v[1], function (v,k) { + if (v && _.isString(v) && k.indexOf('-webkit') === -1 && (!style[k] || style[k].indexOf('important') === -1 || v.indexOf('important') !== -1)) { + style[k] = v; + } + }); + }); + + _.each(style, function (v,k) { + if (v.indexOf('important') !== -1) { + style[k] = v.slice(0, v.length-11); + } + }); + + if (style.display === 'block') { + delete style.display; + } + + // The css generates all the attributes separately and not in simplified form. + // In order to have a better compatibility (outlook for example) we simplify the css tags. + // e.g. border-left-style: none; border-bottom-s .... will be simplified in border-style = none + _.each([ + {property: 'margin'}, + {property: 'padding'}, + {property: 'border', propertyEnd: '-style', defaultValue: 'none'}, + ], function (propertyInfo) { + var p = propertyInfo.property; + var e = propertyInfo.propertyEnd || ''; + var defVal = propertyInfo.defaultValue || 0; + + if (style[p+'-top'+e] || style[p+'-right'+e] || style[p+'-bottom'+e] || style[p+'-left'+e]) { + if (style[p+'-top'+e] === style[p+'-right'+e] && style[p+'-top'+e] === style[p+'-bottom'+e] && style[p+'-top'+e] === style[p+'-left'+e]) { + // keep => property: [top/right/bottom/left value]; + style[p+e] = style[p+'-top'+e]; + } + else { + // keep => property: [top value] [right value] [bottom value] [left value]; + style[p+e] = (style[p+'-top'+e] || defVal) + ' ' + (style[p+'-right'+e] || defVal) + ' ' + (style[p+'-bottom'+e] || defVal) + ' ' + (style[p+'-left'+e] || defVal); + if (style[p+e].indexOf('inherit') !== -1 || style[p+e].indexOf('initial') !== -1) { + // keep => property-top: [top value]; property-right: [right value]; property-bottom: [bottom value]; property-left: [left value]; + delete style[p+e]; + return; + } + } + delete style[p+'-top'+e]; + delete style[p+'-right'+e]; + delete style[p+'-bottom'+e]; + delete style[p+'-left'+e]; + } + }); + + if (style['border-bottom-left-radius']) { + style['border-radius'] = style['border-bottom-left-radius']; + delete style['border-bottom-left-radius']; + delete style['border-bottom-right-radius']; + delete style['border-top-left-radius']; + delete style['border-top-right-radius']; + } + + // if the border styling is initial we remove it to simplify the css tags for compatibility. + // Also, since we do not send a css style tag, the initial value of the border is useless. + _.each(_.keys(style), function (k) { + if (k.indexOf('border') !== -1 && style[k] === 'initial') { + delete style[k]; + } + }); + + // text-decoration rule is decomposed in -line, -color and -style. This is + // however not supported by many browser/mail clients and the editor does + // not allow to change -color and -style rule anyway + if (style['text-decoration-line']) { + style['text-decoration'] = style['text-decoration-line']; + delete style['text-decoration-line']; + delete style['text-decoration-color']; + delete style['text-decoration-style']; + delete style['text-decoration-thickness']; + } + + // text-align inheritance does not seem to get past elements on some + // mail clients + if (style['text-align'] === 'inherit') { + var $el = $(a).parent(); + do { + var align = $el.css('text-align'); + if (_.indexOf(['left', 'right', 'center', 'justify'], align) >= 0) { + style['text-align'] = align; + break; + } + $el = $el.parent(); + } while ($el.length && !$el.is('html')); + } + + return style; +} + +/** + * Converts font icons to images. + * + * @param {jQuery} $editable - the element in which the font icons have to be + * converted to images + */ +function fontToImg($editable) { + var fonts = odoo.__DEBUG__.services["wysiwyg.fonts"]; + + $editable.find('.fa').each(function () { + var $font = $(this); + var icon, content; + _.find(fonts.fontIcons, function (font) { + return _.find(fonts.getCssSelectors(font.parser), function (data) { + if ($font.is(data.selector.replace(/::?before/g, ''))) { + icon = data.names[0].split('-').shift(); + content = data.css.match(/content:\s*['"]?(.)['"]?/)[1]; + return true; + } + }); + }); + if (content) { + var color = $font.css('color').replace(/\s/g, ''); + $font.replaceWith($('', { + src: _.str.sprintf('/web_editor/font_to_img/%s/%s/%s', content.charCodeAt(0), window.encodeURI(color), Math.max(1, Math.round($font.height()))), + 'data-class': $font.attr('class'), + 'data-style': $font.attr('style'), + class: $font.attr('class').replace(new RegExp('(^|\\s+)' + icon + '(-[^\\s]+)?', 'gi'), ''), // remove inline font-awsome style + style: $font.attr('style'), + }).css({height: 'auto', width: 'auto'})); + } else { + $font.remove(); + } + }); +} + +/** + * Converts images which were the result of a font icon convertion to a font + * icon again. + * + * @param {jQuery} $editable - the element in which the images will be converted + * back to font icons + */ +function imgToFont($editable) { + $editable.find('img[src*="/web_editor/font_to_img/"]').each(function () { + var $img = $(this); + $img.replaceWith($('', { + class: $img.data('class'), + style: $img.data('style') + })); + }); +} + +/* + * Utility function to apply function over descendants elements + * + * This is needed until the following issue of jQuery is solved: + * https://github.com./jquery/sizzle/issues/403 + * + * @param {Element} node The root Element node + * @param {Function} func The function applied over descendants + */ +function applyOverDescendants(node, func) { + node = node.firstChild; + while (node) { + if (node.nodeType === 1) { + func(node); + applyOverDescendants(node, func); + } + var $node = $(node); + if (node.nodeName === 'A' && $node.hasClass('btn') && !$node.children().length && $(node).parents('.o_outlook_hack').length) { + node = $(node).parents('.o_outlook_hack')[0]; + } + else if (node.nodeName === 'IMG' && $node.parent('p').hasClass('o_outlook_hack')) { + node = $node.parent()[0]; + } + node = node.nextSibling; + } +} + +/** + * Converts css style to inline style (leave the classes on elements but forces + * the style they give as inline style). + * + * @param {jQuery} $editable + */ +function classToStyle($editable) { + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); + var style = $target.attr('style') || ''; + _.each(css, function (v,k) { + if (!(new RegExp('(^|;)\s*' + k).test(style))) { + style = k+':'+v+';'+style; + } + }); + if (_.isEmpty(style)) { + $target.removeAttr('style'); + } else { + $target.attr('style', style); + } + // Apple Mail + if (node.nodeName === 'TD' && !node.childNodes.length) { + node.innerHTML = ' '; + } + + // Outlook + if (node.nodeName === 'A' && $target.hasClass('btn') && !$target.hasClass('btn-link') && !$target.children().length) { + var $hack = $('
'); + $hack.find('td') + .attr('height', $target.outerHeight()) + .css({ + 'text-align': $target.parent().css('text-align'), + 'margin': $target.css('padding'), + 'border-radius': $target.css('border-radius'), + 'background-color': $target.css('background-color'), + }); + $target.after($hack); + $target.appendTo($hack.find('td')); + // the space add a line when it's a table but it's invisible when it's a link + node = $hack[0].previousSibling; + if (node && node.nodeType === Node.TEXT_NODE && !node.textContent.match(/\S/)) { + $(node).remove(); + } + node = $hack[0].nextSibling; + if (node && node.nodeType === Node.TEXT_NODE && !node.textContent.match(/\S/)) { + $(node).remove(); + } + } + else if (node.nodeName === 'IMG' && $target.is('.mx-auto.d-block')) { + $target.wrap('

'); + } + }); +} + +/** + * Removes the inline style which is not necessary (because, for example, a + * class on an element will induce the same style). + * + * @param {jQuery} $editable + */ +function styleToClass($editable) { + // Outlook revert + $editable.find('.o_outlook_hack').each(function () { + $(this).after($('a,img', this)); + }).remove(); + + var $c = $('').appendTo($editable[0].ownerDocument.body); + + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); + var style = ''; + _.each(css, function (v,k) { + if (!(new RegExp('(^|;)\s*' + k).test(style))) { + style = k+':'+v+';'+style; + } + }); + css = ($c.attr('style', style).attr('style') || '').split(/\s*;\s*/); + style = ($target.attr('style') || '').replace(/\s*:\s*/, ':').replace(/\s*;\s*/, ';'); + _.each(css, function (v) { + style = style.replace(v, ''); + }); + style = style.replace(/;+(\s;)*/g, ';').replace(/^;/g, ''); + if (style !== '') { + $target.attr('style', style); + } else { + $target.removeAttr('style'); + } + }); + $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]').filter(':empty, :containsExact( )').each(function () { + var $link = $(this); + var $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.prepend($img); + }); +} + +/** + * Revert attachmentThumbnailToLinkImg changes + * + * @see attachmentThumbnailToLinkImg + * @param {jQuery} $editable + */ +function linkImgToAttachmentThumbnail($editable) { + $editable.find('a[href*="/web/content/"][data-mimetype] > img').remove(); +} + + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- + + +FieldHtml.include({ + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @override + */ + commitChanges: function () { + if (this.nodeOptions['style-inline'] && this.mode === "edit") { + this._toInline(); + } + return this._super(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Converts CSS dependencies to CSS-independent HTML. + * - CSS display for attachment link -> real image + * - Font icons -> images + * - CSS styles -> inline styles + * + * @private + */ + _toInline: function () { + var $editable = this.wysiwyg.getEditable(); + var html = this.wysiwyg.getValue({'style-inline': true}); + $editable.html(html); + + attachmentThumbnailToLinkImg($editable); + fontToImg($editable); + classToStyle($editable); + + // fix outlook image rendering bug + _.each(['width', 'height'], function(attribute) { + $editable.find('img[style*="width"], img[style*="height"]').attr(attribute, function(){ + return $(this)[attribute](); + }).css(attribute, function(){ + return $(this).get(0).style[attribute] || 'auto'; + }); + }); + + this.wysiwyg.setValue($editable.html(), { + notifyChange: false, + }); + }, + /** + * Revert _toInline changes. + * + * @private + */ + _fromInline: function () { + var $editable = this.wysiwyg.getEditable(); + var html = this.wysiwyg.getValue(); + $editable.html(html); + + styleToClass($editable); + imgToFont($editable); + linkImgToAttachmentThumbnail($editable); + + // fix outlook image rendering bug + $editable.find('img[style*="width"], img[style*="height"]').removeAttr('height width'); + + this.wysiwyg.setValue($editable.html(), { + notifyChange: false, + }); + }, + + //-------------------------------------------------------------------------- + // Handler + //-------------------------------------------------------------------------- + + /** + * @override + */ + _onLoadWysiwyg: function () { + if (this.nodeOptions['style-inline'] && this.mode === "edit") { + this._fromInline(); + } + this._super(); + }, +}); + +return { + fontToImg: fontToImg, + imgToFont: imgToFont, + classToStyle: classToStyle, + styleToClass: styleToClass, + attachmentThumbnailToLinkImg: attachmentThumbnailToLinkImg, + linkImgToAttachmentThumbnail: linkImgToAttachmentThumbnail, +}; +}); \ No newline at end of file diff --git a/addons/web_editor/static/src/js/backend/field_html.js b/addons/web_editor/static/src/js/backend/field_html.js new file mode 100644 index 00000000..37f2a8ba --- /dev/null +++ b/addons/web_editor/static/src/js/backend/field_html.js @@ -0,0 +1,536 @@ +odoo.define('web_editor.field.html', function (require) { +'use strict'; + +var ajax = require('web.ajax'); +var basic_fields = require('web.basic_fields'); +var config = require('web.config'); +var core = require('web.core'); +var Wysiwyg = require('web_editor.wysiwyg.root'); +var field_registry = require('web.field_registry'); +// must wait for web/ to add the default html widget, otherwise it would override the web_editor one +require('web._field_registry'); + +var _lt = core._lt; +var TranslatableFieldMixin = basic_fields.TranslatableFieldMixin; +var QWeb = core.qweb; +var assetsLoaded; + +var jinjaRegex = /(^|\n)\s*%\s(end|set\s)/; + +/** + * FieldHtml Widget + * Intended to display HTML content. This widget uses the wysiwyg editor + * improved by odoo. + * + * nodeOptions: + * - style-inline => convert class to inline style (no re-edition) => for sending by email + * - no-attachment + * - cssEdit + * - cssReadonly + * - snippets + * - wrapper + */ +var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { + description: _lt("Html"), + className: 'oe_form_field oe_form_field_html', + supportedFieldTypes: ['html'], + + custom_events: { + wysiwyg_focus: '_onWysiwygFocus', + wysiwyg_blur: '_onWysiwygBlur', + wysiwyg_change: '_onChange', + wysiwyg_attachment: '_onAttachmentChange', + }, + + /** + * @override + */ + willStart: function () { + var self = this; + this.isRendered = false; + this._onUpdateIframeId = 'onLoad_' + _.uniqueId('FieldHtml'); + var defAsset; + if (this.nodeOptions.cssReadonly) { + defAsset = ajax.loadAsset(this.nodeOptions.cssReadonly); + } + + if (!assetsLoaded) { // avoid flickering when begin to edit + assetsLoaded = new Promise(function (resolve) { + var wysiwyg = new Wysiwyg(self, {}); + wysiwyg.attachTo($('