Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master phoenix massmailing fge #3447

Open
wants to merge 6 commits into
base: master-phoenix-massmailing
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion addons/html_editor/static/src/core/selection_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "@html_editor/utils/dom_info";
import { closestElement, descendants } from "@html_editor/utils/dom_traversal";
import { Plugin } from "../plugin";
import { DIRECTIONS, childNodeIndex, endPos, nodeSize } from "../utils/position";
import { DIRECTIONS, childNodeIndex, endPos, nodeSize, startPos } from "../utils/position";
import {
getAdjacentCharacter,
normalizeCursorPosition,
Expand Down Expand Up @@ -122,6 +122,9 @@ export class SelectionPlugin extends Plugin {
"rectifySelection",
// "collapseIfZWS",
];
static resources = (p) => ({
shortcuts: [{ hotkey: "control+a", command: "SELECT_ALL" }],
});

setup() {
this.resetSelection();
Expand All @@ -147,6 +150,22 @@ export class SelectionPlugin extends Plugin {
});
}

handleCommand(command, payload) {
switch (command) {
case "SELECT_ALL":
{
const selection = this.getEditableSelection();
const containerSelector = "#wrap>*, .oe_structure>*, [contenteditable]";
const container =
selection && closestElement(selection.anchorNode, containerSelector);
const [anchorNode, anchorOffset] = startPos(container);
const [focusNode, focusOffset] = endPos(container);
this.setSelection({ anchorNode, anchorOffset, focusNode, focusOffset });
}
break;
}
}

resetSelection() {
this.activeSelection = this.makeSelection();
}
Expand Down
1 change: 1 addition & 0 deletions addons/html_editor/static/src/main/link/link_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class LinkPlugin extends Plugin {
static resources = (p) => ({
split_element_block: { callback: p.handleSplitBlock.bind(p) },
handle_insert_line_break_element: { callback: p.handleInsertLineBreak.bind(p) },
powerboxCategory: { id: "navigation", name: _t("Navigation"), sequence: 50 },
});
setup() {
this.addDomListener(this.editable, "keydown", (ev) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ export class LinkPopoverPlugin extends Plugin {
isAvailable: isSelectionHasLink,
},
],

powerboxCategory: { id: "navigation", name: _t("Navigation"), sequence: 50 },
powerboxItems: [
{
name: _t("Link"),
Expand Down
18 changes: 17 additions & 1 deletion addons/html_editor/static/tests/selection.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from "@odoo/hoot";
import { queryFirst } from "@odoo/hoot-dom";
import { press, queryFirst } from "@odoo/hoot-dom";
import { animationFrame, tick } from "@odoo/hoot-mock";
import { patchWithCleanup } from "@web/../tests/web_test_helpers";
import { Plugin } from "../src/plugin";
Expand Down Expand Up @@ -142,3 +142,19 @@ test("setSelection should not set the selection outside the editable", async ()
const selection = editor.shared.setSelection(editor.shared.getEditableSelection());
expect(el.contains(selection.anchorNode)).toBe(true);
});

test("press 'ctrl+a' in 'oe_structure' child should only select his content", async () => {
const { el } = await setupEditor(`<div class="oe_structure"><p>a[]b</p><p>cd</p></div>`);
press(["ctrl", "a"]);
expect(getContent(el)).toBe(`<div class="oe_structure"><p>[ab]</p><p>cd</p></div>`);
});

test("press 'ctrl+a' in 'contenteditable' should only select his content", async () => {
const { el } = await setupEditor(
`<div contenteditable="false"><p contenteditable="true">a[]b</p><p contenteditable="true">cd</p></div>`
);
press(["ctrl", "a"]);
expect(getContent(el)).toBe(
`<div contenteditable="false"><p contenteditable="true">[ab]</p><p contenteditable="true">cd</p></div>`
);
});
1 change: 0 additions & 1 deletion addons/mass_mailing/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@
],
'web.assets_unit_tests': [
'mass_mailing/static/tests/mass_mailing_html_field.test.js',
'mass_mailing/static/tests/mass_mailing_favorite_filter.test.js',
],
'web.qunit_suite_tests': [
'mass_mailing/static/tests/mass_mailing_favourite_filter_tests.js',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</div>
<div class="d-inline-block w-100">
<a t-foreach="this.state.themes" t-as="theme" t-key="theme.name"
role="menuitem" href="#" class="dropdown-item px-4"
role="menuitem" href="#" class="dropdown-item px-4" t-att-name="theme.name"
t-on-click.stop.prevent="() => this.selectTemplate(theme)">
<div class="o_thumb small mb-2" t-attf-style="background-image: url(#{theme.img}_small.png)"/>
<div class="o_thumb large mb-2" t-attf-style="background-image: url(#{theme.img}_large.png)"/>
Expand Down
4 changes: 2 additions & 2 deletions addons/mass_mailing/static/src/js/tours/mass_mailing_tour.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@
run: 'click',
}, {
isActive: ["enterprise"],
trigger: 'div[name="body_arch"] :iframe #newsletter',
trigger: 'div[name="body_arch"] .o_mail_theme_selector_new [name="newsletter"]',
content: markup(_t('Choose this <b>theme</b>.')),
tooltipPosition: 'left',
run: 'click',
}, {
isActive: ["community"],
trigger: 'div[name="body_arch"] :iframe #default',
trigger: 'div[name="body_arch"] .o_mail_theme_selector_new [name="default"]',
content: markup(_t('Choose this <b>theme</b>.')),
tooltipPosition: 'right',
run: 'click',
Expand Down
2 changes: 1 addition & 1 deletion addons/mass_mailing/static/tests/tours/mailing_campaign.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ registry.category('web_tour.tours').add('mailing_campaign', {
},
{
content: 'Pick the basic theme',
trigger: ":iframe #basic",
trigger: ".o_mail_theme_selector_new [name='basic']",
run: "click",
},
{
Expand Down
2 changes: 1 addition & 1 deletion addons/mass_mailing/static/tests/tours/mailing_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ registry.category("web_tour.tours").add('mailing_editor', {
run: "click",
}, {
content: 'choose the theme "empty" to edit the mailing with snippets',
trigger: '[name="body_arch"] :iframe #empty',
trigger: '[name="body_arch"] .o_mail_theme_selector_new [name="empty]',
run() {
this.anchor.click();
}
Expand Down
10 changes: 5 additions & 5 deletions addons/mass_mailing/static/tests/tours/mailing_editor_theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ registry.category("web_tour.tours").add('mailing_editor_theme', {
run: "click",
},
{
trigger: ":iframe .o_mail_theme_selector_new",
trigger: ".o_mail_theme_selector_new",
},
{
content: "Pick the basic theme",
trigger: ':iframe #basic',
trigger: '.o_mail_theme_selector_new [name="basic"]',
run: "click",
},
{
trigger: ":iframe html:not(:has(.o_mail_theme_selector_new))",
trigger: ":not(:has(.o_mail_theme_selector_new))",
},
{
content: "Make sure the snippets menu is hidden",
Expand All @@ -56,7 +56,7 @@ registry.category("web_tour.tours").add('mailing_editor_theme', {
run: "click",
},
{
trigger: ":iframe .o_mail_theme_selector_new",
trigger: ".o_mail_theme_selector_new",
},
{
content: "Fill in Subject",
Expand All @@ -75,7 +75,7 @@ registry.category("web_tour.tours").add('mailing_editor_theme', {
},
{
content: "Pick the newsletter theme",
trigger: ':iframe #newsletter',
trigger: ':iframe [name="newsletter"]',
run: "click",
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ registry.category("web_tour.tours").add('mass_mailing_code_view_tour', {
content: 'Select item from dropdown',
run: 'click',
}, {
trigger: 'div[name="body_arch"] :iframe #default',
trigger: 'div[name="body_arch"] .o_mail_theme_selector_new [name="default"]',
content: markup('Choose this <b>theme</b>.'),
run: 'click',
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ registry.category("web_tour.tours").add('snippets_mailing_menu_tabs', {
},
{
content: "Click on the 'Start From Scratch' template.",
trigger: ':iframe #empty',
trigger: '.o_mail_theme_selector_new [name="empty"]',
run: "click",
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ registry.category("web_tour.tours").add('snippets_mailing_menu_toolbar', {
},
{
content: "Wait for the theme selector to load.",
trigger: ':iframe .o_mail_theme_selector_new',
trigger: '.o_mail_theme_selector_new',
run: "click",
},
{
Expand All @@ -34,12 +34,12 @@ registry.category("web_tour.tours").add('snippets_mailing_menu_toolbar', {
},
{
content: "Make sure the empty template is an option on non-mobile devices.",
trigger: ':iframe #empty',
trigger: '.o_mail_theme_selector_new [name="empty"]',
run: () => null,
},
{
content: "Click on the default 'welcome' template.",
trigger: ':iframe #default',
trigger: '.o_mail_theme_selector_new [name="default"]',
run: "click",
},
{ // necessary to wait for the cursor to be placed in the first p
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ registry.category("web_tour.tours").add('snippets_mailing_menu_toolbar_mobile',
{
isActive: ["mobile"],
content: "Check templates available in theme selector",
trigger: ':iframe .o_mail_theme_selector_new',
trigger: '.o_mail_theme_selector_new',
run: function () {
if (this.anchor.querySelector("#empty")) {
if (this.anchor.querySelector("[name='empty']")) {
console.error('The empty template should not be visible on mobile.');
}
},
Expand Down
1 change: 1 addition & 0 deletions addons/mass_mailing/views/mailing_mailing_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@
<notebook>
<page string="Mail Body" name="mail_body">
<div class="position-relative">
<field name="body_html" invisible="1"/>
<field name="body_arch" class="o_mail_body" widget="mass_mailing_html"
options="{
'snippets': 'mass_mailing.email_designer_snippets',
Expand Down
2 changes: 1 addition & 1 deletion addons/web_editor/static/src/js/editor/snippets.editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ var SnippetEditor = Widget.extend({
elements: elementsSelector,
handle: handle,
scrollingElement: $scrollable[0],
enable: () => (!!this.$el.find('.o_move_handle:visible').length || this.dragStarted) && this.isDraggable,
enable: () => (!!this.$el.find('.o_move_handle:visible').length || this.dragStarted),
helper: () => {
const cloneEl = this.$el[0].cloneNode(true);
cloneEl.style.width = "24px";
Expand Down