[FIX] web_editor: should select only selected node in destroyLinkTools
Before this commit:
`destroyLinkTools` function sets the selection to entire link. However, in
case where a website snippet had a structure like
```html
<a>
<div>
<i class=fa-xxx></i>
<div>
<h4>Text</h4>
<font>Text</font>
</div>
</div>
</a>
```
selecting the complete link caused problem. The toolbar couldn't be
updated correctly, also one could not change the a tag of a single element
within the link.
After this commit:
`destroyLinkTools` selects the `anchorNode` and the `focusnode` of the
selection instead of entire link.
task-3245819
closes odoo/odoo#151752
X-original-commit: e88ffecc4bdb0480fc1d47af14558f28f72a665d
Signed-off-by: Antoine Guenet (age) <age@odoo.com>
This commit is contained in:
@@ -60,6 +60,8 @@ const hasValidSelection = OdooEditorLib.hasValidSelection;
|
||||
const parseHTML = OdooEditorLib.parseHTML;
|
||||
const closestBlock = OdooEditorLib.closestBlock;
|
||||
const getRangePosition = OdooEditorLib.getRangePosition;
|
||||
const getCursorDirection = OdooEditorLib.getCursorDirection;
|
||||
const DIRECTIONS = OdooEditorLib.DIRECTIONS;
|
||||
|
||||
function getJqueryFromDocument(doc) {
|
||||
if (doc.defaultView && doc.defaultView.$) {
|
||||
@@ -1562,8 +1564,17 @@ export class Wysiwyg extends Component {
|
||||
anchorOffset = focusOffset = index;
|
||||
}
|
||||
} else {
|
||||
anchorNode = link;
|
||||
focusNode = link;
|
||||
const isDirectionRight = getCursorDirection(selection.anchorNode, 0, selection.focusNode, 0) === DIRECTIONS.RIGHT;
|
||||
if (
|
||||
closestElement(selection.anchorNode, 'a') === link &&
|
||||
closestElement(selection.focusNode, 'a') === link
|
||||
) {
|
||||
[anchorNode, focusNode] = isDirectionRight
|
||||
? [selection.anchorNode, selection.focusNode]
|
||||
: [selection.focusNode, selection.anchorNode];
|
||||
} else {
|
||||
[anchorNode, focusNode] = [link, link];
|
||||
}
|
||||
}
|
||||
if (!focusOffset) {
|
||||
focusOffset = focusNode.childNodes.length || focusNode.length;
|
||||
|
||||
@@ -94,3 +94,86 @@ wTourUtils.registerWebsitePreviewTour('edit_megamenu', {
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
]);
|
||||
wTourUtils.registerWebsitePreviewTour('edit_megamenu_big_icons_subtitles', {
|
||||
test: true,
|
||||
url: '/',
|
||||
edition: true,
|
||||
}, () => [
|
||||
// Add a megamenu item to the top menu.
|
||||
{
|
||||
content: "Click on a menu item",
|
||||
trigger: 'iframe #top_menu .nav-item a',
|
||||
},
|
||||
{
|
||||
content: "Click on 'Link' to open Link Dialog",
|
||||
trigger: 'iframe .o_edit_menu_popover a.js_edit_menu',
|
||||
},
|
||||
{
|
||||
content: "Trigger the link dialog (click 'Add Mega Menu Item')",
|
||||
extra_trigger: ".o_website_dialog",
|
||||
trigger: '.modal-body a:eq(1)',
|
||||
},
|
||||
{
|
||||
content: "Write a label for the new menu item",
|
||||
trigger: '.modal-dialog .o_website_dialog input',
|
||||
run: 'text Megaaaaa2!',
|
||||
},
|
||||
{
|
||||
content: "Confirm the mega menu label",
|
||||
trigger: '.modal-footer .btn-primary',
|
||||
},
|
||||
{
|
||||
content: "Save the website menu with a new mega menu",
|
||||
trigger: '.modal-footer .btn-primary',
|
||||
extra_trigger: '.oe_menu_editor [data-is-mega-menu="true"] .js_menu_label:contains("Megaaaaa2!")',
|
||||
},
|
||||
{
|
||||
trigger: '#oe_snippets.o_loaded',
|
||||
run() {},
|
||||
},
|
||||
{
|
||||
content: "Check for the new mega menu",
|
||||
trigger: 'iframe #top_menu:has(.nav-item a.o_mega_menu_toggle:contains("Megaaaaa2!"))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
// Edit a menu item
|
||||
wTourUtils.clickOnExtraMenuItem({extra_trigger: ".o_website_preview.editor_enable.editor_has_snippets:not(.o_is_blocked)"}, true),
|
||||
toggleMegaMenu({extra_trigger: 'iframe #top_menu .nav-item a.o_mega_menu_toggle:contains("Megaaaaa2!")'}),
|
||||
{
|
||||
content: "Select the first menu link of the first column",
|
||||
trigger: 'iframe .s_mega_menu_odoo_menu .row > div:first-child .nav > :first-child',
|
||||
},
|
||||
wTourUtils.changeOption("MegaMenuLayout", "we-toggler"),
|
||||
{
|
||||
content: "Select Big Icons Subtitles mega menu",
|
||||
trigger: '[data-select-label="Big Icons Subtitles"]',
|
||||
},
|
||||
{
|
||||
content: "Select the h4 of first menu link of the first column",
|
||||
trigger: 'iframe .s_mega_menu_big_icons_subtitles .row > div:first-child .nav > :first-child h4',
|
||||
run: function (actions) {
|
||||
// Clicking on the h4 element first time leads to the selection of
|
||||
// the entire a.nav-link, due to presence of `o_default_snippet_text` class
|
||||
// hence, specify the selection on the h4 element
|
||||
actions.click();
|
||||
const iframeDocument = document.querySelector('.o_iframe').contentDocument;
|
||||
const range = iframeDocument.createRange();
|
||||
range.selectNodeContents(this.$anchor[0]);
|
||||
const sel = iframeDocument.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
},
|
||||
},
|
||||
{
|
||||
content: "Convert it to Bold",
|
||||
trigger: '#oe_snippets #toolbar #bold',
|
||||
},
|
||||
...wTourUtils.clickOnSave(),
|
||||
wTourUtils.clickOnExtraMenuItem({}, true),
|
||||
toggleMegaMenu(),
|
||||
{
|
||||
content: "The menu item should only convert selected text to Bold.",
|
||||
trigger: 'iframe .s_mega_menu_big_icons_subtitles .row > div:first-child .nav > :first-child span:not(:has(strong))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -450,6 +450,9 @@ class TestUi(odoo.tests.HttpCase):
|
||||
def test_30_website_text_animations(self):
|
||||
self.start_tour("/", 'text_animations', login='admin')
|
||||
|
||||
def test_31_website_edit_megamenu_big_icons_subtitles(self):
|
||||
self.start_tour(self.env['website'].get_client_action_url('/'), 'edit_megamenu_big_icons_subtitles', login='admin')
|
||||
|
||||
def test_website_media_dialog_image_shape(self):
|
||||
self.start_tour("/", 'website_media_dialog_image_shape', login='admin')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user