mirror of https://github.com/OCA/web.git
[MIG] web_editor_class_selector: Migration to version 18.0
parent
fa26af9fa2
commit
e871d8a88e
|
@ -17,13 +17,13 @@ Web editor class selector
|
||||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||||
:alt: License: AGPL-3
|
:alt: License: AGPL-3
|
||||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
|
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
|
||||||
:target: https://github.com/OCA/web/tree/17.0/web_editor_class_selector
|
:target: https://github.com/OCA/web/tree/18.0/web_editor_class_selector
|
||||||
:alt: OCA/web
|
:alt: OCA/web
|
||||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||||
:target: https://translation.odoo-community.org/projects/web-17-0/web-17-0-web_editor_class_selector
|
:target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_editor_class_selector
|
||||||
:alt: Translate me on Weblate
|
:alt: Translate me on Weblate
|
||||||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
||||||
:target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=17.0
|
:target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0
|
||||||
:alt: Try me on Runboat
|
:alt: Try me on Runboat
|
||||||
|
|
||||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||||
|
@ -60,7 +60,7 @@ Bug Tracker
|
||||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_editor_class_selector%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_editor_class_selector%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||||
|
|
||||||
Do not contact contributors directly about support or help with technical issues.
|
Do not contact contributors directly about support or help with technical issues.
|
||||||
|
|
||||||
|
@ -85,6 +85,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||||
mission is to support the collaborative development of Odoo features and
|
mission is to support the collaborative development of Odoo features and
|
||||||
promote its widespread use.
|
promote its widespread use.
|
||||||
|
|
||||||
This module is part of the `OCA/web <https://github.com/OCA/web/tree/17.0/web_editor_class_selector>`_ project on GitHub.
|
.. |maintainer-carlos-lopez-tecnativa| image:: https://github.com/carlos-lopez-tecnativa.png?size=40px
|
||||||
|
:target: https://github.com/carlos-lopez-tecnativa
|
||||||
|
:alt: carlos-lopez-tecnativa
|
||||||
|
|
||||||
|
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
||||||
|
|
||||||
|
|maintainer-carlos-lopez-tecnativa|
|
||||||
|
|
||||||
|
This module is part of the `OCA/web <https://github.com/OCA/web/tree/18.0/web_editor_class_selector>`_ project on GitHub.
|
||||||
|
|
||||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Web editor class selector",
|
"name": "Web editor class selector",
|
||||||
"version": "17.0.1.1.0",
|
"version": "18.0.1.0.0",
|
||||||
"summary": "",
|
"summary": "",
|
||||||
"author": "Tecnativa, Odoo Community Association (OCA)",
|
"author": "Tecnativa, Odoo Community Association (OCA)",
|
||||||
"website": "https://github.com/OCA/web",
|
"website": "https://github.com/OCA/web",
|
||||||
|
@ -17,15 +17,14 @@
|
||||||
],
|
],
|
||||||
"assets": {
|
"assets": {
|
||||||
"web.assets_backend": [
|
"web.assets_backend": [
|
||||||
"web_editor_class_selector/static/src/js/backend/**/*",
|
"web_editor_class_selector/static/src/js/css_selector/**/*",
|
||||||
],
|
|
||||||
"web_editor.backend_assets_wysiwyg": [
|
|
||||||
"web_editor_class_selector/static/src/js/odoo-editor/**/*",
|
|
||||||
"web_editor_class_selector/static/src/js/wysiwyg/**/*",
|
|
||||||
"web_editor_class_selector/static/src/scss/demo_styles.scss",
|
"web_editor_class_selector/static/src/scss/demo_styles.scss",
|
||||||
"web_editor_class_selector/static/src/xml/**/",
|
"web_editor_class_selector/static/src/js/fields/**/*",
|
||||||
|
"web_editor_class_selector/static/src/js/utils/**/*",
|
||||||
|
"web_editor_class_selector/static/src/js/wysiwyg/**/*",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
"maintainers": ["carlos-lopez-tecnativa"],
|
||||||
"installable": True,
|
"installable": True,
|
||||||
"auto_install": False,
|
"auto_install": False,
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
|
|
|
@ -369,7 +369,7 @@ ul.auto-toc {
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
!! source digest: sha256:53a338e09db97f68da45d08f963625f60a4069424d8d2f75bcca9887a201824b
|
!! source digest: sha256:53a338e09db97f68da45d08f963625f60a4069424d8d2f75bcca9887a201824b
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/web/tree/17.0/web_editor_class_selector"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/web-17-0/web-17-0-web_editor_class_selector"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/web/tree/18.0/web_editor_class_selector"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_editor_class_selector"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||||
<p>This module allows users to create custom CSS class records, which can
|
<p>This module allows users to create custom CSS class records, which can
|
||||||
then be selected and applied directly in the HTML editor. Note: The
|
then be selected and applied directly in the HTML editor. Note: The
|
||||||
actual CSS file containing the class definitions is not provided by this
|
actual CSS file containing the class definitions is not provided by this
|
||||||
|
@ -408,7 +408,7 @@ supported)</p>
|
||||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
|
||||||
In case of trouble, please check there if your issue has already been reported.
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||||
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_editor_class_selector%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_editor_class_selector%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="credits">
|
<div class="section" id="credits">
|
||||||
|
@ -428,7 +428,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||||
mission is to support the collaborative development of Odoo features and
|
mission is to support the collaborative development of Odoo features and
|
||||||
promote its widespread use.</p>
|
promote its widespread use.</p>
|
||||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/17.0/web_editor_class_selector">OCA/web</a> project on GitHub.</p>
|
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
|
||||||
|
<p><a class="reference external image-reference" href="https://github.com/carlos-lopez-tecnativa"><img alt="carlos-lopez-tecnativa" src="https://github.com/carlos-lopez-tecnativa.png?size=40px" /></a></p>
|
||||||
|
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/18.0/web_editor_class_selector">OCA/web</a> project on GitHub.</p>
|
||||||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import {Component, useState} from "@odoo/owl";
|
||||||
|
import {Dropdown} from "@web/core/dropdown/dropdown";
|
||||||
|
import {DropdownItem} from "@web/core/dropdown/dropdown_item";
|
||||||
|
import {toolbarButtonProps} from "@html_editor/main/toolbar/toolbar";
|
||||||
|
|
||||||
|
export class CssSelector extends Component {
|
||||||
|
static template = "web_editor_class_selector.CssSelector";
|
||||||
|
static props = {
|
||||||
|
getItems: Function,
|
||||||
|
getDisplay: Function,
|
||||||
|
onSelected: Function,
|
||||||
|
...toolbarButtonProps,
|
||||||
|
};
|
||||||
|
static components = {Dropdown, DropdownItem};
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
this.items = this.props.getItems();
|
||||||
|
this.state = useState(this.props.getDisplay());
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelected(item) {
|
||||||
|
this.props.onSelected(item);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<templates xml:space="preserve">
|
||||||
|
<t t-name="web_editor_class_selector.CssSelector">
|
||||||
|
<Dropdown>
|
||||||
|
<button class="btn btn-light" t-att-title="props.title">
|
||||||
|
<span class="px-1" t-esc="state.displayName" />
|
||||||
|
</button>
|
||||||
|
<t t-set-slot="content">
|
||||||
|
<t t-foreach="items" t-as="item" t-key="item_index">
|
||||||
|
<DropdownItem
|
||||||
|
class="item.class_name"
|
||||||
|
onSelected="() => this.onSelected(item)"
|
||||||
|
t-on-pointerdown.prevent="() => {}"
|
||||||
|
>
|
||||||
|
<t t-esc="item.name" />
|
||||||
|
</DropdownItem>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</Dropdown>
|
||||||
|
</t>
|
||||||
|
</templates>
|
|
@ -0,0 +1,71 @@
|
||||||
|
import {CssSelector} from "./css_selector.esm";
|
||||||
|
import {Plugin} from "@html_editor/plugin";
|
||||||
|
import {_t} from "@web/core/l10n/translation";
|
||||||
|
import {reactive} from "@odoo/owl";
|
||||||
|
import {closestElement} from "@html_editor/utils/dom_traversal";
|
||||||
|
import {isVisibleTextNode} from "@html_editor/utils/dom_info";
|
||||||
|
import {withSequence} from "@html_editor/utils/resource";
|
||||||
|
|
||||||
|
export class CssSelectorPlugin extends Plugin {
|
||||||
|
static id = "css_selector_plugin";
|
||||||
|
static dependencies = ["selection", "format"];
|
||||||
|
resources = {
|
||||||
|
toolbar_groups: [withSequence(60, {id: "css-selector"})],
|
||||||
|
toolbar_items: [
|
||||||
|
{
|
||||||
|
id: "css-selector",
|
||||||
|
groupId: "css-selector",
|
||||||
|
title: _t("Custom CSS"),
|
||||||
|
Component: CssSelector,
|
||||||
|
props: {
|
||||||
|
getItems: () => this.custom_class_css,
|
||||||
|
getDisplay: () => this.custom_css,
|
||||||
|
onSelected: (item) => {
|
||||||
|
this.dependencies.format.formatSelection(item.class_name, {
|
||||||
|
formatProps: {className: item.class_name},
|
||||||
|
applyStyle: true,
|
||||||
|
});
|
||||||
|
this.updateCustomCssSelectorParams();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
/** Handlers */
|
||||||
|
selectionchange_handlers: [this.updateCustomCssSelectorParams.bind(this)],
|
||||||
|
post_undo_handlers: [this.updateCustomCssSelectorParams.bind(this)],
|
||||||
|
post_redo_handlers: [this.updateCustomCssSelectorParams.bind(this)],
|
||||||
|
};
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
this.custom_css = reactive({displayName: this.defaultCustomCssName});
|
||||||
|
this.custom_class_css = this.config.custom_class_css;
|
||||||
|
}
|
||||||
|
updateCustomCssSelectorParams() {
|
||||||
|
this.custom_css.displayName = this.customCssName;
|
||||||
|
}
|
||||||
|
get defaultCustomCssName() {
|
||||||
|
return _t("Custom CSS");
|
||||||
|
}
|
||||||
|
get customCssName() {
|
||||||
|
const selectedNodes = this.dependencies.selection
|
||||||
|
.getSelectedNodes()
|
||||||
|
.filter(
|
||||||
|
(n) =>
|
||||||
|
n.nodeType === Node.TEXT_NODE &&
|
||||||
|
closestElement(n).isContentEditable &&
|
||||||
|
isVisibleTextNode(n)
|
||||||
|
);
|
||||||
|
let activeLabel = this.defaultCustomCssName;
|
||||||
|
for (const selectedTextNode of selectedNodes) {
|
||||||
|
const parentNode = selectedTextNode.parentElement;
|
||||||
|
for (const customCss of this.custom_class_css) {
|
||||||
|
const isActive = parentNode.classList.contains(customCss.class_name);
|
||||||
|
if (isActive) {
|
||||||
|
activeLabel = customCss.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeLabel;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/** @odoo-module **/
|
import {CssSelectorPlugin} from "../css_selector/css_selector_plugin.esm";
|
||||||
import {HtmlField} from "@web_editor/js/backend/html_field";
|
import {HtmlField} from "@html_editor/fields/html_field";
|
||||||
import {patch} from "@web/core/utils/patch";
|
import {patch} from "@web/core/utils/patch";
|
||||||
import {useService} from "@web/core/utils/hooks";
|
import {useService} from "@web/core/utils/hooks";
|
||||||
|
|
||||||
|
@ -18,14 +18,12 @@ patch(HtmlField.prototype, {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
get wysiwygOptions() {
|
getConfig() {
|
||||||
// Provide the custom_class_css to the toolbar through the toolbarOptions.
|
// Add the new Plugin to the list of plugins.
|
||||||
return {
|
// Provide the custom_class_css to the toolbar.
|
||||||
...super.wysiwygOptions,
|
const config = super.getConfig(...arguments);
|
||||||
toolbarOptions: {
|
config.Plugins.push(CssSelectorPlugin);
|
||||||
...super.wysiwygOptions.toolbarOptions,
|
config.custom_class_css = this.custom_class_css;
|
||||||
custom_class_css: this.custom_class_css,
|
return config;
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
|
@ -1,68 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
import {
|
|
||||||
closestElement,
|
|
||||||
getSelectedNodes,
|
|
||||||
isVisibleTextNode,
|
|
||||||
} from "@web_editor/js/editor/odoo-editor/src/utils/utils";
|
|
||||||
import {OdooEditor} from "@web_editor/js/editor/odoo-editor/src/OdooEditor";
|
|
||||||
import {_t} from "@web/core/l10n/translation";
|
|
||||||
import {patch} from "@web/core/utils/patch";
|
|
||||||
|
|
||||||
patch(OdooEditor.prototype, {
|
|
||||||
_updateToolbar(show) {
|
|
||||||
const res = super._updateToolbar(show);
|
|
||||||
if (!this.toolbar || !this.custom_class_css) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
const sel = this.document.getSelection();
|
|
||||||
if (!this.isSelectionInEditable(sel)) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
// Get selected nodes within td to handle non-p elements like h1, h2...
|
|
||||||
// Targeting <br> to ensure span stays inside its corresponding block node.
|
|
||||||
const selectedNodesInTds = [
|
|
||||||
...this.editable.querySelectorAll(".o_selected_td"),
|
|
||||||
].map((node) => closestElement(node).querySelector("br"));
|
|
||||||
const selectedNodes = getSelectedNodes(this.editable).filter(
|
|
||||||
(n) =>
|
|
||||||
n.nodeType === Node.TEXT_NODE &&
|
|
||||||
closestElement(n).isContentEditable &&
|
|
||||||
isVisibleTextNode(n)
|
|
||||||
);
|
|
||||||
const selectedTextNodes = selectedNodes.length
|
|
||||||
? selectedNodes
|
|
||||||
: selectedNodesInTds;
|
|
||||||
let activeLabel = "";
|
|
||||||
for (const selectedTextNode of selectedTextNodes) {
|
|
||||||
const parentNode = selectedTextNode.parentElement;
|
|
||||||
for (const customCss of this.custom_class_css) {
|
|
||||||
const button = this.toolbar.querySelector("#" + customCss.class_name);
|
|
||||||
if (button) {
|
|
||||||
const isActive = parentNode.classList.contains(
|
|
||||||
customCss.class_name
|
|
||||||
);
|
|
||||||
button.classList.toggle("active", isActive);
|
|
||||||
|
|
||||||
if (isActive) {
|
|
||||||
activeLabel = button.textContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Show current class active in the toolbar
|
|
||||||
// or remove active class if nothing is selected
|
|
||||||
const styleSection = this.toolbar.querySelector("#custom_class");
|
|
||||||
if (styleSection) {
|
|
||||||
if (!activeLabel) {
|
|
||||||
const css_selectors = this.toolbar.querySelectorAll(".css_selector");
|
|
||||||
for (const node of css_selectors) {
|
|
||||||
node.classList.toggle("active", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
styleSection.querySelector("button span").textContent = activeLabel
|
|
||||||
? activeLabel
|
|
||||||
: _t("Custom CSS");
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,12 +0,0 @@
|
||||||
/** @odoo-module **/
|
|
||||||
import {editorCommands} from "@web_editor/js/editor/odoo-editor/src/commands/commands";
|
|
||||||
import {formatSelection} from "@web_editor/js/editor/odoo-editor/src/utils/utils";
|
|
||||||
|
|
||||||
const newCommands = {
|
|
||||||
setCustomCss: (editor, ...args) => {
|
|
||||||
const selectedId = parseInt(args[0], 10);
|
|
||||||
const record = editor.custom_class_css.find((item) => item.id === selectedId);
|
|
||||||
formatSelection(editor, record.class_name);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Object.assign(editorCommands, newCommands);
|
|
|
@ -1,13 +0,0 @@
|
||||||
/** @odoo-module */
|
|
||||||
|
|
||||||
import {Toolbar} from "@web_editor/js/editor/toolbar";
|
|
||||||
import {patch} from "@web/core/utils/patch";
|
|
||||||
|
|
||||||
patch(Toolbar.props, {
|
|
||||||
...Toolbar.props,
|
|
||||||
custom_class_css: {type: Array, optional: true},
|
|
||||||
});
|
|
||||||
patch(Toolbar.defaultProps, {
|
|
||||||
...Toolbar.defaultProps,
|
|
||||||
custom_class_css: [],
|
|
||||||
});
|
|
|
@ -1,10 +1,7 @@
|
||||||
/** @odoo-module **/
|
import {closestElement} from "@html_editor/utils/dom_traversal";
|
||||||
import {
|
import {formatsSpecs} from "@html_editor/utils/formatting";
|
||||||
closestElement,
|
|
||||||
formatsSpecs,
|
|
||||||
} from "@web_editor/js/editor/odoo-editor/src/utils/utils";
|
|
||||||
|
|
||||||
// This function is called in the _configureToolbar method of the Wysiwyg class
|
// This function is called in the getEditorConfig method of the Wysiwyg class
|
||||||
// It generates the new formatsSpecs object with the custom CSS class
|
// It generates the new formatsSpecs object with the custom CSS class
|
||||||
export function createCustomCssFormats(custom_class_css) {
|
export function createCustomCssFormats(custom_class_css) {
|
||||||
const newformatsSpecs = {};
|
const newformatsSpecs = {};
|
|
@ -1,17 +1,16 @@
|
||||||
/** @odoo-module **/
|
import {Wysiwyg} from "@html_editor/wysiwyg";
|
||||||
import {Wysiwyg} from "@web_editor/js/wysiwyg/wysiwyg";
|
import {createCustomCssFormats} from "../utils/utils.esm";
|
||||||
import {createCustomCssFormats} from "../odoo-editor/utils.esm";
|
|
||||||
import {patch} from "@web/core/utils/patch";
|
import {patch} from "@web/core/utils/patch";
|
||||||
|
|
||||||
patch(Wysiwyg.prototype, {
|
patch(Wysiwyg.prototype, {
|
||||||
_configureToolbar(options) {
|
getEditorConfig() {
|
||||||
super._configureToolbar(options);
|
const res = super.getEditorConfig(...arguments);
|
||||||
if (
|
if (
|
||||||
options.toolbarOptions.custom_class_css &&
|
this.props.config.custom_class_css &&
|
||||||
options.toolbarOptions.custom_class_css.length > 0
|
this.props.config.custom_class_css.length > 0
|
||||||
) {
|
) {
|
||||||
this.odooEditor.custom_class_css = options.toolbarOptions.custom_class_css;
|
createCustomCssFormats(this.props.config.custom_class_css);
|
||||||
createCustomCssFormats(options.toolbarOptions.custom_class_css);
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<templates id="template" xml:space="preserve">
|
|
||||||
<t t-inherit="web_editor.toolbar" t-inherit-mode="extension">
|
|
||||||
<xpath expr="//div[@id='chatgpt']" position="after">
|
|
||||||
<div
|
|
||||||
id="custom_class"
|
|
||||||
class="btn-group dropdown"
|
|
||||||
t-if="props.custom_class_css and props.custom_class_css.length"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn dropdown-toggle"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
title="Custom CSS"
|
|
||||||
tabindex="-1"
|
|
||||||
data-bs-original-title="Custom CSS"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
<span>Custom CSS</span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li t-foreach="props.custom_class_css" t-as="line" t-key="line.id">
|
|
||||||
<a
|
|
||||||
class="dropdown-item css_selector"
|
|
||||||
t-att-id="line.class_name"
|
|
||||||
href="#"
|
|
||||||
data-call="setCustomCss"
|
|
||||||
t-att-data-arg1="line.id"
|
|
||||||
>
|
|
||||||
<span t-att-class="line.class_name" t-out="line.name" />
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</xpath>
|
|
||||||
</t>
|
|
||||||
</templates>
|
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="view_web_editor_class_tree" model="ir.ui.view">
|
<record id="view_web_editor_class_tree" model="ir.ui.view">
|
||||||
<field name="name">view.web.editor.class.tree</field>
|
<field name="name">view.web.editor.class.list</field>
|
||||||
<field name="model">web.editor.class</field>
|
<field name="model">web.editor.class</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree>
|
<list>
|
||||||
<field name="sequence" widget="handle" />
|
<field name="sequence" widget="handle" />
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="class_name" />
|
<field name="class_name" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
<field name="name">Web Editor Class</field>
|
<field name="name">Web Editor Class</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">web.editor.class</field>
|
<field name="res_model">web.editor.class</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">list,form</field>
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p class="o_view_nocontent_smiling_face">
|
<p class="o_view_nocontent_smiling_face">
|
||||||
Click here to add new Web Editor Class.
|
Click here to add new Web Editor Class.
|
||||||
|
|
Loading…
Reference in New Issue