From d1429aec45904c856ad21942840cf511d7ce4615 Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Wed, 21 Oct 2020 09:15:43 +0000 Subject: [PATCH] [IMP] web_editor: update Jabberwock library to commit 0bd94881 Changelog: [FIX] formattingSpace: remove space between inline elem and block [FIX] EventNormalizer: consistently apply insertLineBreak on shift+enter [FIX] DomObjectRenderer: fix typo in comment [FIX] Bundle: change css bundler for rollup [FIX] Odoo: open the media modal in the right tab on dblclick media --- .../static/lib/jabberwock/jabberwock.css | 159 +++++++++--------- .../static/lib/jabberwock/jabberwock.js | 41 ++++- 2 files changed, 120 insertions(+), 80 deletions(-) diff --git a/addons/web_editor/static/lib/jabberwock/jabberwock.css b/addons/web_editor/static/lib/jabberwock/jabberwock.css index cccaca857f9..5349495296e 100644 --- a/addons/web_editor/static/lib/jabberwock/jabberwock.css +++ b/addons/web_editor/static/lib/jabberwock/jabberwock.css @@ -1,78 +1,3 @@ -jw-editor { - display: flex; - flex-direction: column; - position: relative; -} -jw-editor { - display: flex; - flex-direction: column; -} - -.jw-dropdown { - display: inline-block; -} -.jw-dropdown .dropdown-menu { - min-width: 250px; - border: 1px solid #000; - background-color: #141217; -} - -jw-toolbar input { - color: #C6C6C6; -} -jw-resizer{ - display: block; - height: 7px; - background-color: #eee; - border-top: 1px solid #999; - text-align: center; - width: 100%; - line-height: 6px; - position: absolute; - bottom: 0; - cursor: row-resize; -} - -jw-resizer::before { - content: "☰"; - font-size: 6px; - margin-top: 1px; - display: inline-block; - transform: scale(5,1); - color: black; - vertical-align: middle; -} -table.table-picker { - position: absolute; - background-color: white; - border: 1px solid black; - -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); - -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); - box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); -} -table.table-picker tr { - height: 1em; - padding: 0; -} -table.table-picker td { - width: 1em; - border: 1px solid black; - padding: 0; -} -table.table-picker td.highlight { - background-color: #875A7B; -} -#jw-device-preview { - border-width: 80px 14px 40px; - border-radius: 16px; - border-style: solid; - border-color: #000; - background-color: white; - width: 400px; - height: 700px; - margin: auto; - display: block; -} ul.checklist > li { list-style: none; position: relative; @@ -101,6 +26,28 @@ ul.checklist > li.checked:after { transition: opacity .5s; opacity: 1; } + +table.table-picker { + position: absolute; + background-color: white; + border: 1px solid black; + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,.4); +} +table.table-picker tr { + height: 1em; + padding: 0; +} +table.table-picker td { + width: 1em; + border: 1px solid black; + padding: 0; +} +table.table-picker td.highlight { + background-color: #875A7B; +} + jw-dialog-container { position: fixed; top: 0; @@ -145,9 +92,17 @@ jw-dialog-container jw-dialog table.form-table { jw-dialog-container jw-dialog table.form-table td { border: none; } + jw-follow-range { position: absolute; } + +jw-editor { + display: flex; + flex-direction: column; + position: relative; +} + .jw-fullscreen .jw-fullscreen { display: block; position: fixed; @@ -164,6 +119,37 @@ jw-follow-range { .jw-fullscreen jw-follow-range { z-index: 1; } + +jw-editor { + display: flex; + flex-direction: column; +} + +.jw-dropdown { + display: inline-block; +} +.jw-dropdown .dropdown-menu { + min-width: 250px; + border: 1px solid #000; + background-color: #141217; +} + +jw-toolbar input { + color: #C6C6C6; +} + +#jw-device-preview { + border-width: 80px 14px 40px; + border-radius: 16px; + border-style: solid; + border-color: #000; + background-color: white; + width: 400px; + height: 700px; + margin: auto; + display: block; +} + jw-group[name="templates"] .label { width: 90px; } @@ -219,3 +205,26 @@ jw-templates jw-template:hover jw-thumb { jw-templates jw-template img { width: 100%; } + +jw-resizer{ + display: block; + height: 7px; + background-color: #eee; + border-top: 1px solid #999; + text-align: center; + width: 100%; + line-height: 6px; + position: absolute; + bottom: 0; + cursor: row-resize; +} + +jw-resizer::before { + content: "☰"; + font-size: 6px; + margin-top: 1px; + display: inline-block; + transform: scale(5,1); + color: black; + vertical-align: middle; +} diff --git a/addons/web_editor/static/lib/jabberwock/jabberwock.js b/addons/web_editor/static/lib/jabberwock/jabberwock.js index 630dc005b0a..0f0cdc85648 100644 --- a/addons/web_editor/static/lib/jabberwock/jabberwock.js +++ b/addons/web_editor/static/lib/jabberwock/jabberwock.js @@ -7141,7 +7141,7 @@ odoo.define('web_editor.jabberwock', (function(require) { if (parent) { const markers = []; parent.childVNodes.forEach(sibling => { - // Filter and sort the ndoes. + // Filter and sort the nodes. if (setNodes.has(sibling)) { if (sibling.tangible) { renderingUnits.push(this._createUnit(cache, sibling, rendered)); @@ -8336,12 +8336,42 @@ odoo.define('web_editor.jabberwock', (function(require) { function _isAtSegmentBreak(node, side) { const siblingSide = side === 'start' ? 'previousSibling' : 'nextSibling'; const sibling = node && node[siblingSide]; - const isAgainstAnotherSegment = sibling && _isSegment(sibling); + const isAgainstAnotherSegment = _isAgainstAnotherSegment(node, side); const isAtEdgeOfOwnSegment = _isBlockEdge(node, side); // In the DOM, a space before a BR is rendered but a space after a BR isn't. const isBeforeBR = side === 'end' && sibling && nodeName(sibling) === 'BR'; return (isAgainstAnotherSegment && !isBeforeBR) || isAtEdgeOfOwnSegment; } + /** + * Return true if the given node is just before or just after another segment. + * Eg:
abc
def
-> abc is before another segment (div). + * Eg:
abc
def
-> abc is before another segment + * (div). + * + * @param {Node} node + * @param {'start'|'end'} side + * @returns {boolean} + */ + function _isAgainstAnotherSegment(node, side) { + const siblingSide = side === 'start' ? 'previousSibling' : 'nextSibling'; + const sibling = node && node[siblingSide]; + if (sibling) { + return sibling && _isSegment(sibling); + } + else { + // Look further (eg.: `
abc
def
`: the + // space should be removed). + let ancestor = node; + while (ancestor && !ancestor[siblingSide]) { + ancestor = ancestor.parentNode; + } + let cousin = ancestor && !_isSegment(ancestor) && ancestor.nextSibling; + while (cousin && isInstanceOf(cousin, Text)) { + cousin = cousin.nextSibling; + } + return cousin && _isSegment(cousin); + } + } /** * Return true if the node is a segment according to W3 formatting model. * @@ -17652,6 +17682,7 @@ odoo.define('web_editor.jabberwock', (function(require) { const inputType = (cutEvent && 'deleteByCut') || (dropEvent && 'insertFromDrop') || (pasteEvent && 'insertFromPaste') || + (key === 'Enter' && (inputEvent === null || inputEvent === void 0 ? void 0 : inputEvent.inputType) === 'insertText' && 'insertLineBreak') || (inputEvent && inputEvent.inputType); // In case of accent inserted from a Mac, check that the char before was // one of the special accent temporarily inserted in the DOM (e.g. '^', @@ -20784,7 +20815,7 @@ odoo.define('web_editor.jabberwock', (function(require) { }); }; const openMedia = () => { - this.engine.editor.execCommand('openMedia'); + this.engine.editor.execCommand('openMedia', { media: node }); }; const wrapper = { tag: 'DIV', @@ -21277,7 +21308,7 @@ odoo.define('web_editor.jabberwock', (function(require) { const savedAttach = image.attach; const savedDetach = image.detach; const handleClick = () => { - const params = { image: node }; + const params = { media: node }; this.engine.editor.execCommand('openMedia', params); }; image.attach = (el) => { @@ -21423,7 +21454,7 @@ odoo.define('web_editor.jabberwock', (function(require) { const fa = domObject.children[1] || domObject.children[0]; if ('tag' in fa) { const dbclickCallback = () => { - this.engine.editor.execCommand('openMedia'); + this.engine.editor.execCommand('openMedia', { media: node }); }; const savedAttach = fa.attach; fa.attach = (el) => {