diff --git a/addons/web/static/lib/qweb/qweb-test-call.xml b/addons/web/static/lib/qweb/qweb-test-call.xml
index b0c5deb9fe6..45a65eabce9 100644
--- a/addons/web/static/lib/qweb/qweb-test-call.xml
+++ b/addons/web/static/lib/qweb/qweb-test-call.xml
@@ -57,7 +57,7 @@
-
+
ok
diff --git a/addons/web/static/lib/qweb/qweb-test-global.xml b/addons/web/static/lib/qweb/qweb-test-global.xml
index bfcca8c1eba..1db3e5920fb 100644
--- a/addons/web/static/lib/qweb/qweb-test-global.xml
+++ b/addons/web/static/lib/qweb/qweb-test-global.xml
@@ -18,7 +18,7 @@
- i
+ i
@@ -49,6 +49,6 @@
toto default
- i
+ i
]]>
diff --git a/addons/web/static/lib/qweb/qweb-test.js.html b/addons/web/static/lib/qweb/qweb-test.js.html
new file mode 100644
index 00000000000..0ee5f27c3bd
--- /dev/null
+++ b/addons/web/static/lib/qweb/qweb-test.js.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/web/static/lib/qweb/qweb2.js b/addons/web/static/lib/qweb/qweb2.js
index 8058cb7745f..c4bb7128e9b 100644
--- a/addons/web/static/lib/qweb/qweb2.js
+++ b/addons/web/static/lib/qweb/qweb2.js
@@ -28,10 +28,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var QWeb2 = {
expressions_cache: { },
RESERVED_WORDS: 'true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,typeof,eval,void,Math,RegExp,Array,Object,Date'.split(','),
- ACTIONS_PRECEDENCE: 'foreach,if,elif,else,call,set,js,debug,log'.split(','),
+ ACTIONS_PRECEDENCE: 'foreach,if,elif,else,call,set,esc,raw,js,debug,log'.split(','),
WORD_REPLACEMENT: {
- // FUCKING CHM FOR FUCK'S SAKE
- 'not': '!',
'and': '&&',
'or': '||',
'gt': '>',
@@ -78,9 +76,9 @@ var QWeb2 = {
return s;
},
gen_attribute: function(o) {
- if (o) {
+ if (o !== null && o !== undefined) {
if (o.constructor === Array) {
- if (o[1]) {
+ if (o[1] !== null && o[1] !== undefined) {
return this.format_attribute(o[0], o[1]);
}
} else if (typeof o === 'object') {
@@ -720,52 +718,36 @@ QWeb2.Element = (function() {
},
compile_element : function() {
for (var i = 0, ilen = this.engine.actions_precedence.length; i < ilen; i++) {
- var compiled_action = this.engine.actions_precedence[i];
- if (compiled_action in this.actions) {
- var value = this.actions[compiled_action];
- var key = 'compile_action_' + compiled_action;
+ var a = this.engine.actions_precedence[i];
+ if (a in this.actions) {
+ var value = this.actions[a];
+ var key = 'compile_action_' + a;
if (this[key]) {
this[key](value);
} else if (this.engine[key]) {
this.engine[key].call(this, value);
} else {
- this.engine.tools.exception("No handler method for action '" + compiled_action + "'");
+ this.engine.tools.exception("No handler method for action '" + a + "'");
}
}
}
- function print_contents(self) {
- var expr, esc, raw;
- if (esc = self.actions['esc']) {
- expr = "context.engine.tools.html_escape(" + self.format_str(esc) + ");";
- } else if(raw = self.actions['raw']) {
- expr = self.format_str(raw);
- }
- // print non-empty result of t-esc or t-raw, otherwise
- // print/process body
- if (expr) {
- self.top('var expr_result = ' + expr + ';');
- self.top('if (expr_result) {');
- self.top(' r.push(expr_result);');
- self.top('} else {');
- self.bottom('}');
- }
- }
if (this.tag.toLowerCase() !== this.engine.prefix) {
var tag = "<" + this.tag;
- for (var att in this.attributes) {
- tag += this.engine.tools.gen_attribute([att, this.attributes[att]]);
+ for (var a in this.attributes) {
+ tag += this.engine.tools.gen_attribute([a, this.attributes[a]]);
}
this.top_string(tag);
if (this.actions.att) {
-
+ this.top("r.push(context.engine.tools.gen_attribute(" + (this.format_expression(this.actions.att)) + "));");
}
for (var a in this.actions) {
- var m, v = this.actions[a];
- if (a === 'att') {
- this.top("r.push(context.engine.tools.gen_attribute(" + (this.format_expression(v)) + "));");
- } else if (m = a.match(/att-(.+)/)) {
+ var v = this.actions[a];
+ var m = a.match(/att-(.+)/);
+ if (m) {
this.top("r.push(context.engine.tools.gen_attribute(['" + m[1] + "', (" + (this.format_expression(v)) + ")]));");
- } else if (m = a.match(/attf-(.+)/)) {
+ }
+ var m = a.match(/attf-(.+)/);
+ if (m) {
this.top("r.push(context.engine.tools.gen_attribute(['" + m[1] + "', (" + (this.string_interpolation(v)) + ")]));");
}
}
@@ -773,13 +755,11 @@ QWeb2.Element = (function() {
// We do not enforce empty content on void elements
// because QWeb rendering is not necessarily html.
this.top_string("/>");
- return; // ensure we skip processing content
} else {
this.top_string(">");
this.bottom_string("" + this.tag + ">");
}
}
- print_contents(this);
},
compile_action_if : function(value) {
this.top("if (" + (this.format_expression(value)) + ") {");
@@ -837,6 +817,14 @@ QWeb2.Element = (function() {
}
}
},
+ compile_action_esc : function(value) {
+ this.top("r.push(context.engine.tools.html_escape("
+ + this.format_expression(value)
+ + "));");
+ },
+ compile_action_raw : function(value) {
+ this.top("r.push(" + (this.format_str(value)) + ");");
+ },
compile_action_js : function(value) {
this.top("(function(" + value + ") {");
this.bottom("})(dict);");
diff --git a/addons/web/static/lib/qweb/tests.js b/addons/web/static/lib/qweb/tests.js
deleted file mode 100644
index 5b961acd427..00000000000
--- a/addons/web/static/lib/qweb/tests.js
+++ /dev/null
@@ -1,77 +0,0 @@
-odoo.define('qweb.tests', function () {
-'use strict';
-
-function trim(s) {
- return s.replace(/(^\s+|\s+$)/g, '');
-}
-
-/**
- * Generates a QUnit.module hook object loading the specified test file
- * (from /web/static/lib/qweb) and setting ``this.qweb`` (the qweb
- * instance for this module) and ``this.doc`` (the loaded XML file).
- *
- * Note that test files mix template elements , params elements
- * and result elements . A result and an optional params
- * object are linked to the corresponding template via the ``id``
- * attribute (result and params have the template name as id).
- */
-function hooks(testfile) {
- var template = '/web/static/lib/qweb/' + testfile;
- return {
- before: function () {
- var self = this;
- this.qweb = new QWeb2.Engine();
- var p = $.Deferred();
- this.qweb.add_template(template, function (_, doc) {
- self.doc = doc;
- p.resolve(doc);
- });
- return p.promise();
- }
- }
-}
-// can't get generative QUnit.test (e.g. QUnit.test in a for(;;)
-// or Array#forEach() loop) to work, so each test file has a single test,
-// that seems to work
-function runtest() {
- QUnit.test('', function (assert) {
- var templates = this.qweb.templates;
- assert.expect(_.reduce(templates, function (acc, _, k) {
- return acc + (/^_/.test(k) ? 0 : 1);
- }, 0));
- for (var template in templates) {
- if (!templates.hasOwnProperty(template)) { continue; }
- // ignore templates whose name starts with _, they're
- // helpers/internal
- if (/^_/.test(template)) { continue; }
-
- var params = this.doc.querySelector('params#' + template);
- var args = params ? JSON.parse(params.textContent) : {};
-
- var results = this.doc.querySelector('result#' + template);
- assert.equal(
- trim(this.qweb.render(template, args)),
- trim(results.textContent),
- template);
- }
- });
-}
-
-var TEMPLATES = [
- ["Output", 'qweb-test-output.xml'],
- ["Context-setting", 'qweb-test-set.xml'],
- ["Conditionals", 'qweb-test-conditionals.xml'],
- ["Attributes manipulation", 'qweb-test-attributes.xml'],
- ["Template calling (to the faraway pages)", 'qweb-test-call.xml'],
- ["Foreach", 'qweb-test-foreach.xml'],
- ["Global", 'qweb-test-global.xml'],
- ['Template inheritance', 'qweb-test-extend.xml']
-];
-
-QUnit.module('qweb', {}, function () {
- TEMPLATES.forEach(function (it) {
- QUnit.module(it[0], hooks(it[1]), runtest);
- })
-});
-
-});
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 605003443d0..4f69ed286b3 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -448,9 +448,6 @@
display: inherit;
}
-
-
-