diff options
Diffstat (limited to 'addons/web_editor/static/src')
| -rw-r--r-- | addons/web_editor/static/src/css/backend.css | 15 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/backend.js | 29 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/rte.js | 14 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/rte.summernote.js | 2 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/summernote.js | 37 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/tour.rte.js | 2 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/transcoder.js | 60 | ||||
| -rw-r--r-- | addons/web_editor/static/src/js/translator.js | 2 |
8 files changed, 110 insertions, 51 deletions
diff --git a/addons/web_editor/static/src/css/backend.css b/addons/web_editor/static/src/css/backend.css index 29871c3d305..33a7155354c 100644 --- a/addons/web_editor/static/src/css/backend.css +++ b/addons/web_editor/static/src/css/backend.css @@ -5,11 +5,17 @@ line-height: initial !important; color: initial !important; } -.oe_form_field_html_text .note-editable p { - margin: initial; +.oe_form_field_html_text iframe.o_readonly { + min-height: 1em; + width: 100%; + margin: 0; + padding: 0; + border: 0; } -.oe_form_field_html_text .note-editable a, .oe_form_field_html_text .note-editable a:hover { - color: initial; +.oe_form_field_html_text .note-editable p { + font-family: 'Lucida Grande', Helvetica, Verdana, Arial, sans-serif; + -webkit-margin-before: 0; + font-size: 13px; } .oe_form_field_html iframe { @@ -47,7 +53,6 @@ overflow: hidden !important; } - .openerp .oe_form .oe_form_field_html_translate textarea { min-width: 60px; width: 100%; diff --git a/addons/web_editor/static/src/js/backend.js b/addons/web_editor/static/src/js/backend.js index eca913e1309..becd0fe4769 100644 --- a/addons/web_editor/static/src/js/backend.js +++ b/addons/web_editor/static/src/js/backend.js @@ -62,9 +62,20 @@ var FieldTextHtmlSimple = widget.extend({ initialize_content: function() { var self = this; this.$textarea = this.$("textarea").val(this.get('value') || "<p><br/></p>"); + this.$content = $(); if (this.get("effective_readonly")) { - this.$textarea.hide().after('<div class="note-editable"/>'); + if (this.options['style-inline']) { + this.$textarea.hide().after('<iframe class="o_readonly"/>'); + setTimeout(function () { + self.$content = $("body", self.$('iframe').contents()[0]); + self.$content.html(self.text_to_html(self.get('value'))); + self.resize(); + }); + } else { + this.$content = $('<div class="note-editable o_readonly"/>'); + this.$textarea.hide().after(this.$content); + } } else { this.$textarea.summernote(this._config()); @@ -77,8 +88,10 @@ var FieldTextHtmlSimple = widget.extend({ var reset = _.bind(this.reset_history, this); this.view.on('load_record', this, reset); setTimeout(reset, 0); + + this.$content = this.$('.note-editable:first'); + transcoder.style_to_class(this.$content); } - this.$content = this.$('.note-editable:first'); $(".oe-view-manager-content").on("scroll", function () { $('.o_table_handler').remove(); @@ -98,7 +111,7 @@ var FieldTextHtmlSimple = widget.extend({ value = '<p><br/></p>'; } else { value = "<p>"+value.split(/<br\/?>/).join("<br/></p><p>")+"</p>"; - value = value.replace(/<p><\/p>/g, '').replace('<p><p>', '<p>').replace('</p></p>', '</p>'); + value = value.replace(/<p><\/p>/g, '').replace('<p><p>', '<p>').replace('<p><p ', '<p ').replace('</p></p>', '</p>'); } return value; }, @@ -111,12 +124,20 @@ var FieldTextHtmlSimple = widget.extend({ return this.$content.focusInEnd(); } catch (e) { return this.$content.focus(); - }; + } + }, + resize: function() { + this.$('iframe').css('height', '0px').css('height', Math.max(30, Math.min(this.$content[0] ? this.$content[0].scrollHeight : 0, 500)) + 'px'); }, render_value: function() { var value = this.get('value'); this.$textarea.val(value || ''); this.$content.html(this.text_to_html(value)); + if (this.get("effective_readonly")) { + this.resize(); + } else { + transcoder.style_to_class(this.$content); + } if (this.$content.is(document.activeElement)) { this.focus(); } diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js index 85721ba0387..becaf978d17 100644 --- a/addons/web_editor/static/src/js/rte.js +++ b/addons/web_editor/static/src/js/rte.js @@ -513,13 +513,21 @@ var RTE = Widget.extend({ } if ($target.is('a')) { + // add contenteditable on link to improve its editing behaviour $target.attr('contenteditable', true); setTimeout(function () { $editable.attr('contenteditable', false); }); - } else if ($editable.attr('contenteditable') === 'false') { - $target.removeAttr('contenteditable'); - $editable.attr('contenteditable', true); + // once clicked outside, remove contenteditable on link + var reactive_editable = function(e){ + if($target.is(e.target)) { + return; + } + $target.removeAttr('contenteditable'); + $editable.attr('contenteditable', true); + $(document).off('mousedown', reactive_editable); + } + $(document).on('mousedown', reactive_editable); } if (this && this.$last && (!$editable.size() || this.$last[0] != $editable[0])) { diff --git a/addons/web_editor/static/src/js/rte.summernote.js b/addons/web_editor/static/src/js/rte.summernote.js index 01020a84c22..094d13340dc 100644 --- a/addons/web_editor/static/src/js/rte.summernote.js +++ b/addons/web_editor/static/src/js/rte.summernote.js @@ -764,7 +764,7 @@ eventHandler.attach = function (oLayoutInfo, options) { .add(oLayoutInfo.handle()) .add(oLayoutInfo.popover()) .add(custom_toolbar) - .on('click keyup', function () { + .on('click content_changed', function () { $('button[data-event="undo"]', $toolbar).attr('disabled', !oLayoutInfo.editable().data('NoteHistory').hasUndo()); $('button[data-event="redo"]', $toolbar).attr('disabled', !oLayoutInfo.editable().data('NoteHistory').hasRedo()); }); diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js index 6ed7be2039f..e31faaab601 100644 --- a/addons/web_editor/static/src/js/summernote.js +++ b/addons/web_editor/static/src/js/summernote.js @@ -558,13 +558,15 @@ dom.removeBetween = function (sc, so, ec, eo, towrite) { }; }; dom.indent = function (node) { - var margin = parseFloat(node.style.marginLeft || 0)+1.5; - node.style.marginLeft = margin + "em"; + var style = dom.isCell(node) ? 'paddingLeft' : 'marginLeft'; + var margin = parseFloat(node.style[style] || 0)+1.5; + node.style[style] = margin + "em"; return margin; }; dom.outdent = function (node) { - var margin = parseFloat(node.style.marginLeft || 0)-1.5; - node.style.marginLeft = margin > 0 ? margin + "em" : ""; + var style = dom.isCell(node) ? 'paddingLeft' : 'marginLeft'; + var margin = parseFloat(node.style[style] || 0)-1.5; + node.style[style] = margin > 0 ? margin + "em" : ""; return margin; }; dom.scrollIntoViewIfNeeded = function (node) { @@ -950,9 +952,10 @@ $.summernote.pluginEvents.tab = function (event, editor, layoutInfo, outdent) { $editable.data('NoteHistory').recordUndo($editable, 'tab'); var r = range.create(); var outdent = outdent || false; + event.preventDefault(); - if (r && r.isCollapsed()) { - if (r.isOnCell() && r.isOnCellFirst()) { + if (r && (dom.ancestor(r.sc, dom.isCell) || dom.ancestor(r.ec, dom.isCell))) { + if (r.isCollapsed() && r.isOnCell() && r.isOnCellFirst()) { var td = dom.ancestor(r.sc, dom.isCell); if (!outdent && !dom.nextElementSibling(td) && !dom.nextElementSibling(td.parentNode)) { var last = dom.lastChild(td); @@ -963,10 +966,10 @@ $.summernote.pluginEvents.tab = function (event, editor, layoutInfo, outdent) { } else { editor.table.tab(r, outdent); } - event.preventDefault(); - return false; + } else { + $.summernote.pluginEvents.indent(event, editor, layoutInfo, outdent); } - + } else if (r && r.isCollapsed()) { if (!r.sc.textContent.slice(0,r.so).match(/\S/) && r.isOnList()) { if (outdent) { $.summernote.pluginEvents.outdent(event, editor, layoutInfo); @@ -993,11 +996,8 @@ $.summernote.pluginEvents.tab = function (event, editor, layoutInfo, outdent) { next.textContent = next.textContent.replace(/^(\u00A0)+/g, ''); range.create(r.sc, r.sc.textContent.length, r.sc, r.sc.textContent.length).select(); } - event.preventDefault(); - return false; } } - event.preventDefault(); return false; }; $.summernote.pluginEvents.untab = function (event, editor, layoutInfo) { @@ -1724,7 +1724,7 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent) dom.merge(parent, start, 0, end, 1, null, true); } function indentOther (p, start, end) { - if (p === start || $.contains(p, start)) { + if (p === start || $.contains(p, start) || $.contains(start, p)) { flag = true; } if (flag) { @@ -1734,7 +1734,7 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent) dom.indent(p); } } - if (p === end || $.contains(p, end)) { + if (p === end || $.contains(p, end) || $.contains(end, p)) { flag = false; } } @@ -1743,15 +1743,18 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent) var $dom = $(ancestor); if (!dom.isList(ancestor)) { - $dom = $(ancestor).children(); + $dom = $(dom.node(ancestor)).children(); } if (!$dom.length) { - $dom = $(dom.ancestor(r.sc, dom.isList)); + $dom = $(dom.ancestor(r.sc, dom.isList) || dom.ancestor(r.sc, dom.isCell)); if (!$dom.length) { $dom = $(r.sc).closest(options.styleTags.join(',')); } } + // if select tr, take the first td + $dom = $dom.map(function () { return this.tagName === "TR" ? dom.firstElementChild(this) : this; }); + $dom.each(function () { if (flag || $.contains(this, r.sc)) { if (dom.isList(this)) { @@ -1760,7 +1763,7 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent) } else { indentUL(this, r.sc, r.ec); } - } else if (isFormatNode(this)) { + } else if (isFormatNode(this) || dom.ancestor(this, dom.isCell)) { indentOther(this, r.sc, r.ec); } } diff --git a/addons/web_editor/static/src/js/tour.rte.js b/addons/web_editor/static/src/js/tour.rte.js index 5205e60eef8..8c3c494a73f 100644 --- a/addons/web_editor/static/src/js/tour.rte.js +++ b/addons/web_editor/static/src/js/tour.rte.js @@ -20,7 +20,7 @@ Tour.register({ id: 'rte', name: "Test RTE", mode: 'test', - path: '/web_editor/field/html?callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', + path: '/web_editor/field/html?debug&callback=FieldTextHtml_0&enable_editor=1&datarecord=%7B%7D', steps: [ { title: "Change html for this test", diff --git a/addons/web_editor/static/src/js/transcoder.js b/addons/web_editor/static/src/js/transcoder.js index bd7848d2e97..20779bf19aa 100644 --- a/addons/web_editor/static/src/js/transcoder.js +++ b/addons/web_editor/static/src/js/transcoder.js @@ -30,9 +30,7 @@ var getMatchedCSSRules = function (a) { var selectorText = rules[r].selectorText; if (selectorText && rules[r].cssText && - selectorText.indexOf(".") !== -1 && - selectorText.indexOf(".note-") === -1 && - + selectorText !== "*" && selectorText.indexOf(":hover") === -1 && selectorText.indexOf(":before") === -1 && selectorText.indexOf(":after") === -1 && @@ -61,6 +59,9 @@ var getMatchedCSSRules = function (a) { var style_obj = {}; for (var k=0, len=style.length; k<len; k++) { 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; } @@ -83,12 +84,37 @@ var getMatchedCSSRules = function (a) { var style = {}; _.each(css, function (v,k) { _.each(v[1], function (v,k) { - if (!style[k] || style[k].indexOf('important') === -1 || v.indexOf('important') !== -1) { + if (v && k.indexOf('-webkit') === -1 && (!style[k] || style[k].indexOf('important') === -1 || v.indexOf('important') !== -1)) { style[k] = v; } }); }); - return cache[a.tagName + "." +a.className] = style; + + _.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; + } + if (style['margin-top']) { + style.margin = (style['margin-top'] || 0) + ' ' + (style['margin-right'] || 0) + ' ' + (style['margin-bottom'] || 0) + ' ' + (style['margin-left'] || 0); + delete style['margin-top']; + delete style['margin-right']; + delete style['margin-bottom']; + delete style['margin-left']; + } + if (style['padding-top']) { + style.padding = (style['padding-top'] || 0) + ' ' + (style['padding-right'] || 0) + ' ' + (style['padding-bottom'] || 0) + ' ' + (style['padding-left'] || 0); + delete style['padding-top']; + delete style['padding-right']; + delete style['padding-bottom']; + delete style['padding-left']; + } + + return a.className ? cache[a.tagName + "." +a.className] = style : style; }; // convert font awsome into image @@ -138,13 +164,12 @@ var class_to_style = function ($editable) { if (!rulesCache.length) { getMatchedCSSRules($editable[0]); } - var selector = _.map(rulesCache, function (a) { return a.selector;}).join(","); - $editable.find(selector).each(function () { + $editable.find('*').each(function () { var $target = $(this); var css = getMatchedCSSRules(this); var style = $target.attr("style") || ""; _.each(css, function (v,k) { - if (style.indexOf(k) === -1) { + if (!(new RegExp('(^|;)\s*' + k).test(style))) { style = k+":"+v+";"+style; } }); @@ -154,23 +179,15 @@ var class_to_style = function ($editable) { // convert style into inline class from mail var style_to_class = function ($editable) { getMatchedCSSRules($editable[0]); - var classes = []; - $editable.find("[class]").each(function () { - classes = classes.concat(this.className.split(/\s+/)); - }); - classes = _.compact(classes); - - var maybe_selector = _.filter(rulesCache, function (a) { return !!_.find(classes, function (b) { return a.selector.indexOf("."+b) !== -1; } ); }); - var selector = _.map(maybe_selector, function (a) { return a.selector;}).join(","); var $c = $('<span/>').appendTo("body"); - $editable.find(selector).each(function () { + $editable.find('*').each(function () { var $target = $(this); var css = getMatchedCSSRules(this); var style = ""; _.each(css, function (v,k) { - if (style.indexOf(k) === -1) { + if (!(new RegExp('(^|;)\s*' + k).test(style))) { style = k+":"+v+";"+style; } }); @@ -179,7 +196,12 @@ var style_to_class = function ($editable) { _.each(css, function (v) { style = style.replace(v, ''); }); - $target.attr("style", style.replace(/;+(\s;)*/g, ';').replace(/^;/g, '')); + style = style.replace(/;+(\s;)*/g, ';').replace(/^;/g, ''); + if (style !== '') { + $target.attr("style", style); + } else { + $target.removeAttr("style"); + } }); $c.remove(); }; diff --git a/addons/web_editor/static/src/js/translator.js b/addons/web_editor/static/src/js/translator.js index b9ed671020d..39efbe1db2f 100644 --- a/addons/web_editor/static/src/js/translator.js +++ b/addons/web_editor/static/src/js/translator.js @@ -319,7 +319,7 @@ if (edit_translations) { this.action = this.action.replace(/[$?]edit_translations[^&?]+/, ''); }); - $('title').html($('title').html().replace(/<span data-oe-translation-id.+?>(.+?)<\/span>/, '\$1')); + $('title').html($('title').html().replace(/<span data-oe-model.+?>(.+?)<\/span>/, '\$1')); }); } |
