[IMP] web: add mode qweb in ace
Add a new parser in the ace for the qweb highlight. This makes it possible to visualize the qweb tags and the part of code. Used in the website and in xml fields. closes odoo/odoo#69609 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
@@ -95,6 +95,7 @@ This module provides the core of the Odoo Web Client.
|
||||
'web/static/src/scss/tooltip.scss',
|
||||
'web/static/src/scss/switch_company_menu.scss',
|
||||
'web/static/src/scss/debug_manager.scss',
|
||||
'web/static/src/scss/ace.scss',
|
||||
'web/static/src/scss/control_panel.scss',
|
||||
'web/static/src/scss/fields.scss',
|
||||
'web/static/src/scss/file_upload.scss',
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
define("ace/mode/qweb_highlight_rules", ["require", "exports", "module", "ace/lib/oop", "ace/mode/xml_highlight_rules"], function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var oop = require("../lib/oop");
|
||||
var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules;
|
||||
|
||||
var QWebHighlightRules = function () {
|
||||
XmlHighlightRules.call(this);
|
||||
const xmlRules = this.$rules;
|
||||
|
||||
const tagRegex = xmlRules.attributes[0].regex;
|
||||
|
||||
this.$rules = Object.assign({},
|
||||
xmlRules,
|
||||
{
|
||||
attributes: [{
|
||||
include: "attributes_odoo",
|
||||
}, {
|
||||
include: "attributes_qweb",
|
||||
}, {
|
||||
include: "attributes_groups",
|
||||
}, {
|
||||
include: "attributes_sample",
|
||||
}],
|
||||
|
||||
attributes_odoo: [{
|
||||
token: ["entity.other.attribute-name.xml.odoo", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml.code", "string.attribute-value.xml.end"],
|
||||
regex: '(domain|attrs|options)(=)(\\s*)(")([^"]*)(")',
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.odoo", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml.code", "string.attribute-value.xml.end"],
|
||||
regex: "(domain|attrs|options)(=)(\\s*)(')([^']*)(')",
|
||||
}],
|
||||
|
||||
attributes_qweb: [{
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: '(t-name|t-call-assets|t-js|t-css)(=)(\\s*)(")([^"]*)(")',
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: "(t-name|t-call-assets|t-js|t-css)(=)(\\s*)(')([^']*)(')",
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml", "string.attribute-value.xml.code", "string.attribute-value.xml", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: '(t-call|t-attf-(?:' + tagRegex + '))(=)(\\s*)(")([^"#{]*)(?:([#{]\\{)([^"}]+)(\\}[}]?))?([^"]*)(")',
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml", "string.attribute-value.xml.code", "string.attribute-value.xml", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: "(t-call|t-attf-(?:" + tagRegex + "))(=)(\\s*)(')([^'#{]*)(?:([#{]\\{)([^'}]+)(\\}[}]?))?([^']*)(')",
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml.code", "string.attribute-value.xml.end"],
|
||||
regex: '(t-(?:' + tagRegex + '))(=)(\\s*)(")([^"]*)(")',
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml.code", "string.attribute-value.xml.end"],
|
||||
regex: "(t-(?:" + tagRegex + "))(=)(\\s*)(')([^']*)(')",
|
||||
}],
|
||||
|
||||
attributes_groups: [{
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: '(groups)(=)(\\s*)(")([\\s\\na-zA-Z0-9,_-]*)(")',
|
||||
}, {
|
||||
token: ["entity.other.attribute-name.xml.qweb", "keyword.operator.attribute-equals.xml", "text", "string.attribute-value.xml.start", "string.attribute-value.xml", "string.attribute-value.xml.end"],
|
||||
regex: "(groups)(=)(\\s*)(')((?:[\\s\\na-zA-Z0-9,_-]*)*)(')",
|
||||
}],
|
||||
|
||||
attributes_sample: [{
|
||||
token: "entity.other.attribute-name.xml",
|
||||
regex: tagRegex,
|
||||
}, {
|
||||
token: "keyword.operator.attribute-equals.xml",
|
||||
regex: "=",
|
||||
}, {
|
||||
include: "tag_whitespace",
|
||||
}, {
|
||||
include: "attribute_value",
|
||||
}],
|
||||
|
||||
tag: [{
|
||||
token: ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"],
|
||||
regex: "(?:(<)|(</))((?:" + tagRegex + ":)?" + tagRegex + ")",
|
||||
next: [{
|
||||
include: "attributes",
|
||||
}, {
|
||||
token: ["meta.tag.punctuation.end-tag-close.xml", "meta.tag.punctuation.tag-close.xml"],
|
||||
regex: "(/>)|(>)",
|
||||
next: "start",
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
);
|
||||
|
||||
if (this.constructor === QWebHighlightRules) {
|
||||
this.normalizeRules();
|
||||
}
|
||||
};
|
||||
|
||||
oop.inherits(QWebHighlightRules, XmlHighlightRules);
|
||||
|
||||
exports.QWebHighlightRules = QWebHighlightRules;
|
||||
});
|
||||
|
||||
define("ace/mode/qweb",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/qweb_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml","ace/worker/worker_client"], function(require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var oop = require("../lib/oop");
|
||||
var lang = require("../lib/lang");
|
||||
var TextMode = require("./text").Mode;
|
||||
var QWebHighlightRules = require("./qweb_highlight_rules").QWebHighlightRules;
|
||||
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
|
||||
var XmlFoldMode = require("./folding/xml").FoldMode;
|
||||
var WorkerClient = require("../worker/worker_client").WorkerClient;
|
||||
|
||||
var Mode = function() {
|
||||
this.HighlightRules = QWebHighlightRules;
|
||||
this.$behaviour = new XmlBehaviour();
|
||||
this.foldingRules = new XmlFoldMode();
|
||||
};
|
||||
|
||||
oop.inherits(Mode, TextMode);
|
||||
|
||||
(function() {
|
||||
|
||||
this.voidElements = lang.arrayToMap([]);
|
||||
|
||||
this.blockComment = {start: "<!--", end: "-->"};
|
||||
|
||||
this.createWorker = function(session) {
|
||||
var worker = new WorkerClient(["ace"], "ace/mode/xml_worker", "Worker");
|
||||
worker.attachToDocument(session.getDocument());
|
||||
|
||||
worker.on("error", function(e) {
|
||||
session.setAnnotations(e.data);
|
||||
});
|
||||
|
||||
worker.on("terminate", function() {
|
||||
session.clearAnnotations();
|
||||
});
|
||||
|
||||
return worker;
|
||||
};
|
||||
|
||||
this.$id = "ace/mode/xml";
|
||||
}).call(Mode.prototype);
|
||||
|
||||
exports.Mode = Mode;
|
||||
});
|
||||
@@ -3520,7 +3520,8 @@ var AceEditor = DebouncedField.extend({
|
||||
'/web/static/lib/ace/ace.js',
|
||||
[
|
||||
'/web/static/lib/ace/mode-python.js',
|
||||
'/web/static/lib/ace/mode-xml.js'
|
||||
'/web/static/lib/ace/mode-xml.js',
|
||||
'/web/static/lib/ace/mode-qweb.js'
|
||||
]
|
||||
],
|
||||
events: {}, // events are triggered manually for this debounced widget
|
||||
@@ -3613,9 +3614,10 @@ var AceEditor = DebouncedField.extend({
|
||||
}
|
||||
this.aceEditor.$blockScrolling = true;
|
||||
this.aceSession = this.aceEditor.getSession();
|
||||
const mode = this.nodeOptions.mode || 'qweb';
|
||||
this.aceSession.setOptions({
|
||||
useWorker: false,
|
||||
mode: "ace/mode/" + (this.nodeOptions.mode || 'xml'),
|
||||
mode: "ace/mode/" + (mode === 'xml' ? 'qweb' : mode),
|
||||
tabSize: 2,
|
||||
useSoftTabs: true,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
.ace_editor > .ace_gutter {
|
||||
display: block !important; // display even with aria-hidden
|
||||
}
|
||||
.ace_editor .ace_qweb {
|
||||
color: orange !important;
|
||||
}
|
||||
.ace_editor .ace_code {
|
||||
color: fuchsia !important;
|
||||
}
|
||||
.ace_editor.ace-monokai .ace_qweb {
|
||||
color: lightblue !important;
|
||||
}
|
||||
.ace_editor.ace-monokai .ace_code {
|
||||
color: #c94bc9 !important;
|
||||
}
|
||||
@@ -122,6 +122,7 @@ var ViewEditor = Widget.extend({
|
||||
[
|
||||
'/web/static/lib/ace/javascript_highlight_rules.js',
|
||||
'/web/static/lib/ace/mode-xml.js',
|
||||
'/web/static/lib/ace/mode-qweb.js',
|
||||
'/web/static/lib/ace/mode-scss.js',
|
||||
'/web/static/lib/ace/mode-js.js',
|
||||
'/web/static/lib/ace/theme-monokai.js'
|
||||
@@ -349,7 +350,8 @@ var ViewEditor = Widget.extend({
|
||||
type = type || this.currentType;
|
||||
var editingSession = new window.ace.EditSession(this.resources[type][resID].arch);
|
||||
editingSession.setUseWorker(false);
|
||||
editingSession.setMode('ace/mode/' + (type || this.currentType));
|
||||
let mode = (type || this.currentType);
|
||||
editingSession.setMode('ace/mode/' + (mode === 'xml' ? 'qweb' : mode));
|
||||
editingSession.setUndoManager(new window.ace.UndoManager());
|
||||
editingSession.on('change', function () {
|
||||
_.defer(function () {
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
'website.assets_editor': [
|
||||
('include', 'web._assets_helpers'),
|
||||
'web/static/lib/bootstrap/scss/_variables.scss',
|
||||
'web/static/src/scss/ace.scss',
|
||||
'website/static/src/scss/website.editor.ui.scss',
|
||||
'website/static/src/scss/website.theme_install.scss',
|
||||
'website/static/src/js/menu/content.js',
|
||||
|
||||
@@ -965,6 +965,7 @@ options.registry.OptionsTab = options.Class.extend({
|
||||
jsLibs: [
|
||||
'/web/static/lib/ace/ace.js',
|
||||
'/web/static/lib/ace/mode-xml.js',
|
||||
'/web/static/lib/ace/mode-qweb.js',
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1163,7 +1164,7 @@ options.registry.OptionsTab = options.Class.extend({
|
||||
|
||||
const aceSession = aceEditor.getSession();
|
||||
aceSession.setOptions({
|
||||
mode: "ace/mode/xml",
|
||||
mode: "ace/mode/qweb",
|
||||
useWorker: false,
|
||||
});
|
||||
return aceEditor;
|
||||
|
||||
Reference in New Issue
Block a user