Skip to content

Do not start all plugins in translate mode #4598

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

Merged
merged 1 commit into from
May 14, 2025
Merged
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
8 changes: 5 additions & 3 deletions addons/html_builder/static/src/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { CustomizeTab } from "./sidebar/customize_tab";
import { ThemeTab } from "@html_builder/website_builder/plugins/theme/theme_tab";
import { CORE_PLUGINS } from "./core/core_plugins";
import { EDITOR_COLOR_CSS_VARIABLES, getCSSVariableValue } from "./utils/utils_css";
import { withSequence } from "@html_editor/utils/resource";

export class Builder extends Component {
static template = "html_builder.Builder";
Expand Down Expand Up @@ -76,7 +77,8 @@ export class Builder extends Component {
"BannerPlugin",
]
);
const Plugins = [...mainPlugins, ...CORE_PLUGINS, ...(this.props.Plugins || [])];
const corePlugins = this.props.isTranslation ? [] : CORE_PLUGINS;
const Plugins = [...mainPlugins, ...corePlugins, ...(this.props.Plugins || [])];
// TODO: maybe do a different config for the translate mode and the
// "regular" mode.
this.editor = new Editor(
Expand All @@ -103,9 +105,9 @@ export class Builder extends Component {
trigger_dom_updated: () => {
editorBus.trigger("DOM_UPDATED");
},
on_mobile_preview_clicked: () => {
on_mobile_preview_clicked: withSequence(20, () => {
editorBus.trigger("DOM_UPDATED");
},
}),
change_current_options_containers_listeners: (currentOptionsContainers) => {
this.state.currentOptionsContainers = currentOptionsContainers;
if (!currentOptionsContainers.length) {
Expand Down
3 changes: 2 additions & 1 deletion addons/html_builder/static/src/builder.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
<BlockTab />
</t>
<t t-if="state.activeTab === 'customize'">
<CustomizeTab currentOptionsContainers="state.currentOptionsContainers" snippetModel="snippetModel"/>
<t t-if="props.isTranslation" t-call="html_builder.CustomizeTranslationTab"/>
<CustomizeTab t-else="" currentOptionsContainers="state.currentOptionsContainers" snippetModel="snippetModel"/>
</t>
<t t-if="state.activeTab === 'theme'">
<ThemeTab/>
Expand Down
5 changes: 5 additions & 0 deletions addons/html_builder/static/src/core/builder_options_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class BuilderOptionsPlugin extends Plugin {
"getContainers",
"updateContainers",
"deactivateContainers",
"getTarget",
"getPageContainers",
"getRemoveDisabledReason",
"getCloneDisabledReason",
Expand Down Expand Up @@ -150,6 +151,10 @@ export class BuilderOptionsPlugin extends Plugin {
this.dispatchTo("change_current_options_containers_listeners", this.lastContainers);
}

getTarget() {
return this.target;
}

deactivateContainers() {
this.target = null;
this.lastContainers = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";

export class BuilderOptionsPlugin extends Plugin {
static id = "builder-options";
static shared = ["deactivateContainers", "getTarget"];

deactivateContainers() {}
getTarget() {}
}

registry.category("translation-plugins").add(BuilderOptionsPlugin.id, BuilderOptionsPlugin);
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { throttleForAnimation } from "@web/core/utils/timing";
import { getScrollingElement, getScrollingTarget } from "@web/core/utils/scrolling";
import { checkElement } from "../builder_options_plugin";
import { BuilderOverlay, sizingY, sizingX, sizingGrid } from "./builder_overlay";
import { withSequence } from "@html_editor/utils/resource";

function isResizable(el) {
const isResizableY = el.matches(sizingY.selector) && !el.matches(sizingY.exclude);
Expand All @@ -18,7 +19,7 @@ export class BuilderOverlayPlugin extends Plugin {
resources = {
step_added_handlers: this.refreshOverlays.bind(this),
change_current_options_containers_listeners: this.openBuilderOverlays.bind(this),
on_mobile_preview_clicked: this.refreshOverlays.bind(this),
on_mobile_preview_clicked: withSequence(20, this.refreshOverlays.bind(this)),
has_overlay_options: { hasOption: (el) => isResizable(el) },
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { omit } from "@web/core/utils/objects";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";

export class DisableSnippetsPlugin extends Plugin {
static id = "disableSnippets";
static dependencies = ["setup_editor_plugin", "dropzone", "dropzone_selector"];
static shared = ["disableUndroppableSnippets"];
resources = {
after_remove_handlers: this.disableUndroppableSnippets.bind(this),
on_mobile_preview_clicked: this.disableUndroppableSnippets.bind(this),
post_undo_handlers: this.disableUndroppableSnippets.bind(this),
post_redo_handlers: this.disableUndroppableSnippets.bind(this),
on_mobile_preview_clicked: withSequence(20, this.disableUndroppableSnippets.bind(this)),
};

setup() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";

export class DisableSnippetsPlugin extends Plugin {
static id = "disableSnippets";
static shared = ["disableUndroppableSnippets"];

disableUndroppableSnippets() {}
}

registry.category("translation-plugins").add(DisableSnippetsPlugin.id, DisableSnippetsPlugin);
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { throttleForAnimation } from "@web/core/utils/timing";
import { getScrollingElement, getScrollingTarget } from "@web/core/utils/scrolling";
import { checkElement } from "../builder_options_plugin";
import { OverlayButtons } from "./overlay_buttons";
import { withSequence } from "@html_editor/utils/resource";

export class OverlayButtonsPlugin extends Plugin {
static id = "overlayButtons";
Expand All @@ -17,7 +18,7 @@ export class OverlayButtonsPlugin extends Plugin {
resources = {
step_added_handlers: this.refreshButtons.bind(this),
change_current_options_containers_listeners: this.addOverlayButtons.bind(this),
on_mobile_preview_clicked: this.refreshButtons.bind(this),
on_mobile_preview_clicked: withSequence(20, this.refreshButtons.bind(this)),
};

setup() {
Expand Down
2 changes: 2 additions & 0 deletions addons/html_builder/static/src/core/save_plugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Plugin } from "@html_editor/plugin";
import { rpc } from "@web/core/network/rpc";
import { registry } from "@web/core/registry";

const oeStructureSelector = "#wrapwrap .oe_structure[data-oe-xpath][data-oe-id]";
const oeFieldSelector = "#wrapwrap [data-oe-field]:not([data-oe-sanitize-prevent-edition])";
Expand Down Expand Up @@ -222,3 +223,4 @@ export class SavePlugin extends Plugin {
}
}
}
registry.category("translation-plugins").add(SavePlugin.id, SavePlugin);
2 changes: 2 additions & 0 deletions addons/html_builder/static/src/core/setup_editor_plugin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Plugin } from "@html_editor/plugin";
import { _t } from "@web/core/l10n/translation";
import { getTranslationEditableEls } from "@html_builder/website_builder/plugins/translation_plugin";
import { registry } from "@web/core/registry";

export class SetupEditorPlugin extends Plugin {
static id = "setup_editor_plugin";
Expand Down Expand Up @@ -103,3 +104,4 @@ export class SetupEditorPlugin extends Plugin {
return editablesAreaEls;
}
}
registry.category("translation-plugins").add(SetupEditorPlugin.id, SetupEditorPlugin);
35 changes: 19 additions & 16 deletions addons/html_builder/static/src/core/visibility_plugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Plugin } from "@html_editor/plugin";
import { isMobileView } from "@html_builder/utils/utils";
import { registry } from "@web/core/registry";
import { withSequence } from "@html_editor/utils/resource";

export class VisibilityPlugin extends Plugin {
static id = "visibility";
Expand All @@ -10,7 +12,7 @@ export class VisibilityPlugin extends Plugin {
"onOptionVisibilityUpdate",
];
resources = {
on_mobile_preview_clicked: this.onMobilePreviewClicked.bind(this),
on_mobile_preview_clicked: withSequence(10, this.onMobilePreviewClicked.bind(this)),
system_attributes: ["data-invisible"],
system_classes: ["o_snippet_override_invisible"],
};
Expand Down Expand Up @@ -60,17 +62,21 @@ export class VisibilityPlugin extends Plugin {
}

onMobilePreviewClicked() {
const isMobilePreview = isMobileView(this.editable);
const invisibleOverrideEls = this.editable.querySelectorAll(
".o_snippet_mobile_invisible, .o_snippet_desktop_invisible"
);
for (const invisibleOverrideEl of [...invisibleOverrideEls]) {
const isMobileHidden = invisibleOverrideEl.classList.contains(
"o_snippet_mobile_invisible"
);
invisibleOverrideEl.classList.remove("o_snippet_override_invisible");
const show = isMobilePreview !== isMobileHidden;
this.toggleVisibilityStatus(invisibleOverrideEl, show);
const show = this.toggleVisibilityStatus({
editingEl: invisibleOverrideEl,
considerDeviceVisibility: true,
});
if (
!show &&
invisibleOverrideEl.contains(this.dependencies["builder-options"].getTarget())
) {
this.dependencies["builder-options"].deactivateContainers();
}
}
}

Expand All @@ -83,7 +89,7 @@ export class VisibilityPlugin extends Plugin {
* @returns {Boolean}
*/
toggleTargetVisibility(editingEl, show, considerDeviceVisibility) {
show = this.toggleVisibilityStatus(editingEl, show, considerDeviceVisibility);
show = this.toggleVisibilityStatus({ editingEl, show, considerDeviceVisibility });
const dispatchName = show ? "target_show" : "target_hide";
this.dispatchTo(dispatchName, editingEl);
return show;
Expand All @@ -96,8 +102,7 @@ export class VisibilityPlugin extends Plugin {
* @param {Boolean} show true/false if the element was shown/hidden
*/
onOptionVisibilityUpdate(editingEl, show) {
const isShown = this.toggleVisibilityStatus(editingEl, show);

const isShown = this.toggleVisibilityStatus({ editingEl, show });
if (!isShown) {
this.dependencies["builder-options"].deactivateContainers();
}
Expand All @@ -114,18 +119,14 @@ export class VisibilityPlugin extends Plugin {
* @param {Boolean} considerDeviceVisibility
* @returns {Boolean}
*/
toggleVisibilityStatus(editingEl, show, considerDeviceVisibility) {
toggleVisibilityStatus({ editingEl, show, considerDeviceVisibility = false }) {
if (
considerDeviceVisibility &&
editingEl.matches(".o_snippet_mobile_invisible, .o_snippet_desktop_invisible")
) {
const isMobilePreview = isMobileView(editingEl);
const isMobileHidden = editingEl.classList.contains("o_snippet_mobile_invisible");
if (isMobilePreview === isMobileHidden) {
// If the preview mode and the hidden type are the same, the
// element is considered as hidden.
show = false;
}
show = isMobilePreview !== isMobileHidden;
}

if (show === undefined) {
Expand All @@ -143,3 +144,5 @@ export class VisibilityPlugin extends Plugin {
function isTargetVisible(editingEl) {
return editingEl.dataset.invisible !== "1";
}

registry.category("translation-plugins").add(VisibilityPlugin.id, VisibilityPlugin);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">

<t t-name="html_builder.CustomizeTranslationTab">
<div class="o_customize_tab h-100">
<div class="text-center pt-5">
Select content on your page to translate it.
</div>
</div>
</t>

</templates>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const COOKIES_BAR = SNIPPET_SPECIFIC_END;

class PopupOptionPlugin extends Plugin {
static id = "PopupOption";
static dependencies = ["anchor", "visibility", "history"];
static dependencies = ["anchor", "visibility", "history", "popupVisibilityPlugin"];

resources = {
builder_options: [
Expand All @@ -34,24 +34,8 @@ class PopupOptionPlugin extends Plugin {
on_cloned_handlers: this.onCloned.bind(this),
on_remove_handlers: this.onRemove.bind(this),
on_snippet_dropped_handlers: this.onSnippetDropped.bind(this),
target_show: this.onTargetShow.bind(this),
target_hide: this.onTargetHide.bind(this),
clean_for_save_handlers: this.cleanForSave.bind(this),
};

setup() {
this.addDomListener(this.editable, "click", (ev) => {
// Note: links are excluded here so that internal modal buttons do
// not close the popup as we want to allow edition of those buttons.
if (ev.target.matches(".s_popup .js_close_popup:not(a, .btn)")) {
ev.stopPropagation();
const popupEl = ev.target.closest(".s_popup");
this.onTargetHide(popupEl);
this.dependencies.visibility.onOptionVisibilityUpdate(popupEl, false);
}
});
}

getActions() {
return {
// Moves the snippet in #o_shared_blocks to be common to all pages
Expand Down Expand Up @@ -115,11 +99,11 @@ class PopupOptionPlugin extends Plugin {
}

onRemove(el) {
this.onTargetHide(el);
this.dependencies.popupVisibilityPlugin.onTargetHide(el);
this.dependencies.history.addCustomMutation({
apply: () => {},
revert: () => {
this.onTargetShow(el);
this.dependencies.popupVisibilityPlugin.onTargetShow(el);
},
});
}
Expand All @@ -129,10 +113,10 @@ class PopupOptionPlugin extends Plugin {
this.assignUniqueID(snippetEl);
this.dependencies.history.addCustomMutation({
apply: () => {
this.onTargetShow(snippetEl);
this.dependencies.popupVisibilityPlugin.onTargetShow(snippetEl);
},
revert: () => {
this.onTargetHide(snippetEl);
this.dependencies.popupVisibilityPlugin.onTargetHide(snippetEl);
},
});
}
Expand All @@ -142,32 +126,6 @@ class PopupOptionPlugin extends Plugin {
);
}

onTargetShow(target) {
// Check if the popup is within the editable, because it is cloned on
// save (see save plugin) and Bootstrap moves it if it is not within the
// document (see Bootstrap Modal's _showElement).
if (target.matches(".s_popup") && this.editable.contains(target)) {
this.window.Modal.getOrCreateInstance(target.querySelector(".modal")).show();
}
}

onTargetHide(target) {
if (target.matches(".s_popup")) {
this.window.Modal.getOrCreateInstance(target.querySelector(".modal")).hide();
}
}

cleanForSave({ root }) {
for (const modalEl of root.querySelectorAll(".s_popup .modal.show")) {
modalEl.parentElement.dataset.invisible = "1";
// Do not call .hide() directly, because it is queued whereas
// .dispose() is not.
modalEl.classList.remove("show");
this.window.Modal.getOrCreateInstance(modalEl)._hideModal();
this.window.Modal.getInstance(modalEl).dispose();
}
}

assignUniqueID(editingElement) {
editingElement.closest(".s_popup").id = `sPopup${Date.now()}`;
}
Expand Down
Loading