[MERGE] forward port branch saas-11.1 up to 7e469eb77a
This commit is contained in:
@@ -409,7 +409,19 @@ var FieldTextHtml = AbstractField.extend({
|
||||
var layoutInfo = self.editor.rte.editable().data('layoutInfo');
|
||||
$.summernote.pluginEvents.codeview(undefined, undefined, layoutInfo, false);
|
||||
}
|
||||
var $ancestors = self.$iframe.filter(':not(:visible)').parentsUntil(':visible').addBack();
|
||||
var ancestorsStyle = [];
|
||||
// temporarily force displaying iframe (needed for firefox)
|
||||
_.each($ancestors, function (el) {
|
||||
var $el = $(el);
|
||||
ancestorsStyle.unshift($el.attr('style') || null);
|
||||
$el.css({display: 'initial', visibility: 'hidden', height: 1});
|
||||
});
|
||||
self.editor.snippetsMenu && self.editor.snippetsMenu.cleanForSave();
|
||||
_.each($ancestors, function (el) {
|
||||
var $el = $(el);
|
||||
$el.attr('style', ancestorsStyle.pop());
|
||||
});
|
||||
self._setValue(self.$content.html());
|
||||
});
|
||||
},
|
||||
|
||||
@@ -281,8 +281,10 @@ var RTEWidget = Widget.extend({
|
||||
.each(function () {
|
||||
var $node = $(this);
|
||||
|
||||
// fallback for firefox iframe display:none see https://github.com/odoo/odoo/pull/22610
|
||||
var computedStyles = window.getComputedStyle(this) || window.parent.getComputedStyle(this);
|
||||
// add class to display inline-block for empty t-field
|
||||
if (window.getComputedStyle(this).display === 'inline' && $node.data('oe-type') !== 'image') {
|
||||
if (computedStyles.display === 'inline' && $node.data('oe-type') !== 'image') {
|
||||
$node.addClass('o_is_inline_editable');
|
||||
}
|
||||
});
|
||||
@@ -651,26 +653,16 @@ var RTEWidget = Widget.extend({
|
||||
self.historyRecordUndo($target, 'activate', true);
|
||||
});
|
||||
|
||||
// To Fix Google Chrome Tripleclick Issue, which selects the ending
|
||||
// whitespace characters (so Tripleclicking then typing text will remove
|
||||
// the whole paragraph instead of its content).
|
||||
// http://stackoverflow.com/questions/38467334/why-does-google-chrome-always-add-space-after-selected-text
|
||||
if ($.browser.chrome === true && ev.originalEvent.detail === 3) {
|
||||
var currentSelection = range.create();
|
||||
if (currentSelection.sc.parentNode === currentSelection.ec) {
|
||||
_selectSC(currentSelection);
|
||||
} else if (currentSelection.eo === 0) {
|
||||
var $hasNext = $(currentSelection.sc).parent();
|
||||
while (!$hasNext.next().length && !$hasNext.is('body')) {
|
||||
$hasNext = $hasNext.parent();
|
||||
}
|
||||
if ($hasNext.next()[0] === currentSelection.ec) {
|
||||
_selectSC(currentSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
function _selectSC(selection) {
|
||||
range.create(selection.sc, selection.so, selection.sc, selection.sc.length).select();
|
||||
// Browsers select different content from one to another after a
|
||||
// triple click (especially: if triple-clicking on a paragraph on
|
||||
// Chrome, blank characters of the element following the paragraph are
|
||||
// selected too)
|
||||
//
|
||||
// The triple click behavior is reimplemented for all browsers here
|
||||
if (ev.originalEvent.detail === 3) {
|
||||
// Select the whole content inside the deepest DOM element that was
|
||||
// triple-clicked
|
||||
range.create(ev.target, 0, ev.target, ev.target.childNodes.length).select();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -421,6 +421,9 @@ dom.isImg = function (node) {
|
||||
};
|
||||
var fn_is_forbidden_node = dom.isForbiddenNode || function () {};
|
||||
dom.isForbiddenNode = function (node) {
|
||||
if (node.tagName === "BR") {
|
||||
return false;
|
||||
}
|
||||
return fn_is_forbidden_node(node) || $(node).is(".media_iframe_video");
|
||||
};
|
||||
var fn_is_img_font = dom.isImgFont || function () {};
|
||||
|
||||
@@ -694,10 +694,16 @@ dom.isRemovableEmptyNode = function (node) {
|
||||
dom.isForbiddenNode = function (node) {
|
||||
return node.tagName === "BR" || $(node).is(".fa, img");
|
||||
};
|
||||
dom.listBetween = function (sc, ec) {
|
||||
/**
|
||||
* @todo 'so' and 'eo' were added as a bugfix and are not given everytime. They
|
||||
* however should be as the function may be wrong without them (for example,
|
||||
* when asking the list between an element and its parent, as there is no path
|
||||
* from the beginning of the former to the beginning of the later).
|
||||
*/
|
||||
dom.listBetween = function (sc, ec, so, eo) {
|
||||
var nodes = [];
|
||||
var ancestor = dom.commonAncestor(sc, ec);
|
||||
dom.walkPoint({'node': sc, 'offset': 0}, {'node': ec, 'offset': 0}, function (point) {
|
||||
dom.walkPoint({'node': sc, 'offset': so || 0}, {'node': ec, 'offset': eo || 0}, function (point) {
|
||||
if (ancestor !== point.node || ancestor === sc || ancestor === ec) {
|
||||
nodes.push(point.node);
|
||||
}
|
||||
@@ -1869,7 +1875,7 @@ $.summernote.pluginEvents.formatBlock = function (event, editor, layoutInfo, sTa
|
||||
}
|
||||
|
||||
// fix by odoo because if you select a style in a li with no p tag all the ul is wrapped by the style tag
|
||||
var nodes = dom.listBetween(r.sc, r.ec);
|
||||
var nodes = dom.listBetween(r.sc, r.ec, r.so, r.eo);
|
||||
for (var i=0; i<nodes.length; i++) {
|
||||
if (dom.isBR(nodes[i]) || (dom.isText(nodes[i]) && dom.isVisibleText(nodes[i])) || dom.isB(nodes[i]) || dom.isU(nodes[i]) || dom.isS(nodes[i]) || dom.isI(nodes[i]) || dom.isFont(nodes[i])) {
|
||||
var ancestor = dom.ancestor(nodes[i], isFormatNode);
|
||||
@@ -1984,6 +1990,14 @@ eventHandler.modules.editor.currentStyle = function (target) {
|
||||
if (r)
|
||||
styleInfo.image = r.isOnImg();
|
||||
}
|
||||
// Fix when the target is a link: the text-align buttons state should
|
||||
// indicate the alignment of the link in the parent, not the text inside
|
||||
// the link (which is not possible to customize with summernote). Summernote fixed
|
||||
// this in their newest version... by just not showing the active button
|
||||
// for alignments.
|
||||
if (styleInfo.anchor) {
|
||||
styleInfo['text-align'] = $(styleInfo.anchor).parent().css('text-align');
|
||||
}
|
||||
return styleInfo;
|
||||
};
|
||||
|
||||
|
||||
@@ -742,7 +742,7 @@ var ViewEditor = Widget.extend({
|
||||
|
||||
var text = data.text || '';
|
||||
if (!isSelected) {
|
||||
text = Array($elem.data('level')).join('-') + ' ' + text;
|
||||
text = Array($elem.data('level') + 1).join('-') + ' ' + text;
|
||||
}
|
||||
var $div = $('<div/>', {
|
||||
text: text,
|
||||
|
||||
@@ -136,12 +136,12 @@ QUnit.test('field html_frame widget', function (assert) {
|
||||
model: 'mass.mailing',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/test\'}"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/logo\'}"/>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
session: {user_context: {lang: "en_us"}},
|
||||
mockRPC: function (route) {
|
||||
if (_.str.startsWith(route, '/test')) {
|
||||
if (_.str.startsWith(route, '/logo')) {
|
||||
// those tests will be executed twice, once in readonly and once in edit
|
||||
assert.ok(route.search('model=mass.mailing') > 0,
|
||||
"the route should specify the correct model");
|
||||
@@ -200,7 +200,7 @@ QUnit.test('html_frame does not crash when saving in readonly', function (assert
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/test\'}"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/logo\'}"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
@@ -208,7 +208,7 @@ QUnit.test('html_frame does not crash when saving in readonly', function (assert
|
||||
if (args.method) {
|
||||
assert.step(args.method);
|
||||
}
|
||||
if (_.str.startsWith(route, '/test')) {
|
||||
if (_.str.startsWith(route, '/logo')) {
|
||||
// manually call the callback to simulate that the iframe has
|
||||
// been loaded (note: just the content, not the editor)
|
||||
window.odoo[$.deparam(route).callback + '_content'].call();
|
||||
@@ -237,7 +237,7 @@ QUnit.test('html_frame does not crash when saving in edit mode (editor not loade
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="display_name"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/test\'}"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/logo\'}"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
@@ -245,7 +245,7 @@ QUnit.test('html_frame does not crash when saving in edit mode (editor not loade
|
||||
if (args.method) {
|
||||
assert.step(args.method);
|
||||
}
|
||||
if (_.str.startsWith(route, '/test')) {
|
||||
if (_.str.startsWith(route, '/logo')) {
|
||||
// manually call the callback to simulate that the iframe has
|
||||
// been partially loaded (just the content, not the editor)
|
||||
window.odoo[$.deparam(route).callback + '_content']();
|
||||
@@ -279,7 +279,7 @@ QUnit.test('html_frame saving in edit mode (editor and content fully loaded)', f
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="display_name"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/test\'}"/>' +
|
||||
'<field name="body" widget="html_frame" options="{\'editor_url\': \'/logo\'}"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
@@ -290,7 +290,7 @@ QUnit.test('html_frame saving in edit mode (editor and content fully loaded)', f
|
||||
writeDeferred.resolve();
|
||||
}
|
||||
}
|
||||
if (_.str.startsWith(route, '/test')) {
|
||||
if (_.str.startsWith(route, '/logo')) {
|
||||
// manually call the callback to simulate that the iframe has
|
||||
// been fully loaded (content + editor)
|
||||
var callback = $.deparam(route).callback;
|
||||
|
||||
Reference in New Issue
Block a user