mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
imp: qweb compiler now condenses whitespaces
This is a pretty big breaking change: the html output by qweb is now different. The main goal is to optimize the compiled templates: - condense all consecutive whitespaces into a single spaces - if possible, drop completely some text nodes, based on the following heuristic: if a text node is only composed of whitespaces, and contains at least one linebreak, then it can be dropped. This leads in my benchmark test to an improvement of about 10%, in rendering speed and in memory consuption. Note: whitespace here means anything that matches the \s regexp: newlines, tabs, ... close #8
This commit is contained in:
@@ -25,3 +25,11 @@ result = qweb.render("sometemplate", { name: "world" });
|
||||
- t-on directive
|
||||
- t-widget, t-props, t-key
|
||||
- t-ref
|
||||
|
||||
## Note on white spaces
|
||||
|
||||
White spaces in a templates are handled in a special way:
|
||||
|
||||
- consecutive whitespaces are always condensed to a single whitespace
|
||||
- if a whitespace-only text node contains a linebreak, it is ignored
|
||||
- the previous rules do not apply if we are in a `<pre>` tag
|
||||
|
||||
@@ -33,7 +33,8 @@ class TodoApp extends Component {
|
||||
}
|
||||
|
||||
get remainingText() {
|
||||
return (this.remaining < 2 ? "item" : "items") + " left";
|
||||
const items = this.remaining < 2 ? "item" : "items";
|
||||
return ` ${items} left`;
|
||||
}
|
||||
|
||||
addTodo(ev) {
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`can be rendered 1`] = `
|
||||
"<div class=\\"o_home_menu\\">
|
||||
<div class=\\"o_apps\\">
|
||||
<a href=\\"#menu_id=96&action_id=131\\" class=\\"o_app\\" data-menu=\\"96\\">
|
||||
<i class=\\"fa fa-comment o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
Discuss
|
||||
</div>
|
||||
</a><a href=\\"#menu_id=205&action_id=250\\" class=\\"o_app\\" data-menu=\\"205\\">
|
||||
<i class=\\"fa fa-pen o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
Notes
|
||||
</div>
|
||||
</a><a href=\\"#menu_id=409&action_id=597\\" class=\\"o_app\\" data-menu=\\"409\\">
|
||||
<i class=\\"fa fa-handshake o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
CRM
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered 1`] = `"<div class=\\"o_home_menu\\"><div class=\\"o_apps\\"><a href=\\"#menu_id=96&action_id=131\\" class=\\"o_app\\" data-menu=\\"96\\"><i class=\\"fa fa-comment o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">Discuss</div></a><a href=\\"#menu_id=205&action_id=250\\" class=\\"o_app\\" data-menu=\\"205\\"><i class=\\"fa fa-pen o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">Notes</div></a><a href=\\"#menu_id=409&action_id=597\\" class=\\"o_app\\" data-menu=\\"409\\"><i class=\\"fa fa-handshake o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">CRM</div></a></div></div>"`;
|
||||
|
||||
@@ -1,45 +1,9 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`can be rendered (in home menu, no app) 1`] = `
|
||||
"<div class=\\"o_navbar o_in_home\\">
|
||||
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered (in home menu, no app) 1`] = `"<div class=\\"o_navbar o_in_home\\"></div>"`;
|
||||
|
||||
exports[`can be rendered (in home menu, one active app) 1`] = `
|
||||
"<div class=\\"o_navbar o_in_home\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-chevron-left\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered (in home menu, one active app) 1`] = `"<div class=\\"o_navbar o_in_home\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-chevron-left\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a></div>"`;
|
||||
|
||||
exports[`can render one menu item 1`] = `
|
||||
"<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Discuss
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`can render one menu item 1`] = `"<div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Discuss</a><ul class=\\"o_menu_sections\\"></ul></div>"`;
|
||||
|
||||
exports[`mobile mode: navbar is different 1`] = `
|
||||
"<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Notes
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
<li>MOBILEMODE</li>
|
||||
</ul>
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`mobile mode: navbar is different 1`] = `"<div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Notes</a><ul class=\\"o_menu_sections\\"><li>MOBILEMODE</li></ul></div>"`;
|
||||
|
||||
@@ -1,27 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`can be rendered (type = warning) 1`] = `
|
||||
"<div class=\\"o_notification o_error\\">
|
||||
|
||||
<div class=\\"o_notification_title\\">
|
||||
<span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification title\\" title=\\"Notification title\\"></span>
|
||||
title
|
||||
</div>
|
||||
<div class=\\"o_notification_content\\">
|
||||
message
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered (type = warning) 1`] = `"<div class=\\"o_notification o_error\\"><div class=\\"o_notification_title\\"><span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification title\\" title=\\"Notification title\\"></span>title</div><div class=\\"o_notification_content\\">message</div></div>"`;
|
||||
|
||||
exports[`can be rendered 1`] = `
|
||||
"<div class=\\"o_notification\\">
|
||||
|
||||
<div class=\\"o_notification_title\\">
|
||||
<span class=\\"o_icon fa fa-3x fa-lightbulb\\" role=\\"img\\" aria-label=\\"Notification title\\" title=\\"Notification title\\"></span>
|
||||
title
|
||||
</div>
|
||||
<div class=\\"o_notification_content\\">
|
||||
message
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered 1`] = `"<div class=\\"o_notification\\"><div class=\\"o_notification_title\\"><span class=\\"o_icon fa fa-3x fa-lightbulb\\" role=\\"img\\" aria-label=\\"Notification title\\" title=\\"Notification title\\"></span>title</div><div class=\\"o_notification_content\\">message</div></div>"`;
|
||||
|
||||
@@ -1,257 +1,11 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`can be rendered (in home menu) 1`] = `
|
||||
"<div class=\\"o_web_client\\">
|
||||
<div class=\\"o_navbar o_in_home\\">
|
||||
|
||||
|
||||
</div>
|
||||
<div class=\\"o_home_menu\\">
|
||||
<div class=\\"o_apps\\">
|
||||
<a href=\\"#menu_id=96&action_id=131\\" class=\\"o_app\\" data-menu=\\"96\\">
|
||||
<i class=\\"fa fa-comment o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
Discuss
|
||||
</div>
|
||||
</a><a href=\\"#menu_id=205&action_id=250\\" class=\\"o_app\\" data-menu=\\"205\\">
|
||||
<i class=\\"fa fa-pen o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
Notes
|
||||
</div>
|
||||
</a><a href=\\"#menu_id=409&action_id=597\\" class=\\"o_app\\" data-menu=\\"409\\">
|
||||
<i class=\\"fa fa-handshake o_app_icon fa-3x fa-fw\\"></i>
|
||||
<div class=\\"o_caption\\">
|
||||
CRM
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_content o_hidden\\"></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
</div>
|
||||
<div class=\\"o_loading d-none\\">Loading</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`can be rendered (in home menu) 1`] = `"<div class=\\"o_web_client\\"><div class=\\"o_navbar o_in_home\\"></div><div class=\\"o_home_menu\\"><div class=\\"o_apps\\"><a href=\\"#menu_id=96&action_id=131\\" class=\\"o_app\\" data-menu=\\"96\\"><i class=\\"fa fa-comment o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">Discuss</div></a><a href=\\"#menu_id=205&action_id=250\\" class=\\"o_app\\" data-menu=\\"205\\"><i class=\\"fa fa-pen o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">Notes</div></a><a href=\\"#menu_id=409&action_id=597\\" class=\\"o_app\\" data-menu=\\"409\\"><i class=\\"fa fa-handshake o_app_icon fa-3x fa-fw\\"></i><div class=\\"o_caption\\">CRM</div></a></div></div><div class=\\"o_content o_hidden\\"></div><div class=\\"o_notification_container\\"></div><div class=\\"o_loading d-none\\">Loading</div></div>"`;
|
||||
|
||||
exports[`clicks on client action with invalid key => empty widget is rendered + warning 1`] = `
|
||||
"<div class=\\"o_web_client\\">
|
||||
<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Discuss
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
<div class=\\"o_notification o_error\\">
|
||||
|
||||
<div class=\\"o_notification_title\\">
|
||||
<span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification Invalid Client Action\\" title=\\"Notification Invalid Client Action\\"></span>
|
||||
Invalid Client Action
|
||||
</div>
|
||||
<div class=\\"o_notification_content\\">
|
||||
Cannot find widget 'mail.discuss' in the action registry
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class=\\"o_loading d-none\\">Loading</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`clicks on client action with invalid key => empty widget is rendered + warning 1`] = `"<div class=\\"o_web_client\\"><div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Discuss</a><ul class=\\"o_menu_sections\\"></ul></div><div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div><div class=\\"o_notification_container\\"><div class=\\"o_notification o_error\\"><div class=\\"o_notification_title\\"><span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification Invalid Client Action\\" title=\\"Notification Invalid Client Action\\"></span>Invalid Client Action</div><div class=\\"o_notification_content\\">Cannot find widget 'mail.discuss' in the action registry</div></div></div><div class=\\"o_loading d-none\\">Loading</div></div>"`;
|
||||
|
||||
exports[`if url has action_id, will render action and navigate to proper menu_id 1`] = `
|
||||
"<div class=\\"o_web_client\\">
|
||||
<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Discuss
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\">
|
||||
<div class=\\"o_control_panel\\">
|
||||
<ol class=\\"breadcrumb\\" role=\\"navigation\\">
|
||||
<li class=\\"breadcrumb-item active\\">
|
||||
Discuss
|
||||
</li>
|
||||
</ol>
|
||||
<div class=\\"o_cp_searchview\\" role=\\"search\\">
|
||||
<div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\">
|
||||
<span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_cp_left\\">
|
||||
<div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div>
|
||||
<aside class=\\"o_cp_sidebar\\"></aside>
|
||||
</div>
|
||||
<div class=\\"o_cp_right\\">
|
||||
<div class=\\"btn-group o_search_options\\" role=\\"search\\"></div>
|
||||
<nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav>
|
||||
<nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_content\\">
|
||||
<div class=\\"o_discuss_sidebar\\">
|
||||
<span>DISCUSS!!</span>
|
||||
</div>
|
||||
<div class=\\"o_discuss_content\\">
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 4</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 400</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span>Current Color: </span>
|
||||
red
|
||||
</div>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
</div>
|
||||
<div class=\\"o_loading d-none\\">Loading</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`if url has action_id, will render action and navigate to proper menu_id 1`] = `"<div class=\\"o_web_client\\"><div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Discuss</a><ul class=\\"o_menu_sections\\"></ul></div><div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\"><div class=\\"o_control_panel\\"><ol class=\\"breadcrumb\\" role=\\"navigation\\"><li class=\\"breadcrumb-item active\\">Discuss</li></ol><div class=\\"o_cp_searchview\\" role=\\"search\\"><div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\"><span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span></div></div><div class=\\"o_cp_left\\"><div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div><aside class=\\"o_cp_sidebar\\"></aside></div><div class=\\"o_cp_right\\"><div class=\\"btn-group o_search_options\\" role=\\"search\\"></div><nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav><nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav></div></div><div class=\\"o_content\\"><div class=\\"o_discuss_sidebar\\"><span>DISCUSS!!</span></div><div class=\\"o_discuss_content\\"><button>Reset first counter</button><button>Reset counter 2 in 3s</button><button>Toggle Clock/counters</button><button>Toggle Color</button><button>Rerender this widget</button><input><div><button>-</button><span style=\\"font-weight:bold\\">Value: 4</span><button>+</button></div><div><button>-</button><span style=\\"font-weight:bold\\">Value: 400</span><button>+</button></div><div><span>Current Color: </span>red</div><button>Add notif</button><button>Add sticky notif</button><button>Add warning</button></div></div></div></div><div class=\\"o_notification_container\\"></div><div class=\\"o_loading d-none\\">Loading</div></div>"`;
|
||||
|
||||
exports[`open act window action with invalid viewtype => empty widget is rendered + warning 1`] = `
|
||||
"<div class=\\"o_web_client\\">
|
||||
<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Notes
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
<div class=\\"o_notification o_error\\">
|
||||
|
||||
<div class=\\"o_notification_title\\">
|
||||
<span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification Invalid View type\\" title=\\"Notification Invalid View type\\"></span>
|
||||
Invalid View type
|
||||
</div>
|
||||
<div class=\\"o_notification_content\\">
|
||||
Cannot find view of type 'kanban' in the view registry
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class=\\"o_loading d-none\\">Loading</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`open act window action with invalid viewtype => empty widget is rendered + warning 1`] = `"<div class=\\"o_web_client\\"><div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Notes</a><ul class=\\"o_menu_sections\\"></ul></div><div class=\\"o_content\\"><div class=\\"o_action_controller\\"></div></div><div class=\\"o_notification_container\\"><div class=\\"o_notification o_error\\"><div class=\\"o_notification_title\\"><span class=\\"o_icon fa fa-3x fa-exclamation\\" role=\\"img\\" aria-label=\\"Notification Invalid View type\\" title=\\"Notification Invalid View type\\"></span>Invalid View type</div><div class=\\"o_notification_content\\">Cannot find view of type 'kanban' in the view registry</div></div></div><div class=\\"o_loading d-none\\">Loading</div></div>"`;
|
||||
|
||||
exports[`start with no action => clicks on client action => discuss is rendered 1`] = `
|
||||
"<div class=\\"o_web_client\\">
|
||||
<div class=\\"o_navbar\\">
|
||||
<a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a>
|
||||
|
||||
<a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">
|
||||
Discuss
|
||||
</a>
|
||||
<ul class=\\"o_menu_sections\\">
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\">
|
||||
<div class=\\"o_control_panel\\">
|
||||
<ol class=\\"breadcrumb\\" role=\\"navigation\\">
|
||||
<li class=\\"breadcrumb-item active\\">
|
||||
Discuss
|
||||
</li>
|
||||
</ol>
|
||||
<div class=\\"o_cp_searchview\\" role=\\"search\\">
|
||||
<div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\">
|
||||
<span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_cp_left\\">
|
||||
<div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div>
|
||||
<aside class=\\"o_cp_sidebar\\"></aside>
|
||||
</div>
|
||||
<div class=\\"o_cp_right\\">
|
||||
<div class=\\"btn-group o_search_options\\" role=\\"search\\"></div>
|
||||
<nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav>
|
||||
<nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"o_content\\">
|
||||
<div class=\\"o_discuss_sidebar\\">
|
||||
<span>DISCUSS!!</span>
|
||||
</div>
|
||||
<div class=\\"o_discuss_content\\">
|
||||
<button>Reset first counter</button>
|
||||
<button>Reset counter 2 in 3s</button>
|
||||
<button>Toggle Clock/counters</button>
|
||||
<button>Toggle Color</button>
|
||||
<button>Rerender this widget</button>
|
||||
<input>
|
||||
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 4</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
<div>
|
||||
<button>-</button>
|
||||
<span style=\\"font-weight:bold\\">Value: 400</span>
|
||||
<button>+</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span>Current Color: </span>
|
||||
red
|
||||
</div>
|
||||
<button>Add notif</button>
|
||||
<button>Add sticky notif</button>
|
||||
<button>Add warning</button>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class=\\"o_notification_container\\">
|
||||
|
||||
</div>
|
||||
<div class=\\"o_loading d-none\\">Loading</div>
|
||||
</div>"
|
||||
`;
|
||||
exports[`start with no action => clicks on client action => discuss is rendered 1`] = `"<div class=\\"o_web_client\\"><div class=\\"o_navbar\\"><a aria-label=\\"Applications\\" class=\\"o_title fa fa-th\\" href=\\"#\\" title=\\"Applications\\" accesskey=\\"h\\"></a><a class=\\"o_menu_brand\\" href=\\"\\" role=\\"button\\">Discuss</a><ul class=\\"o_menu_sections\\"></ul></div><div class=\\"o_content\\"><div class=\\"o_discuss o_action_controller\\"><div class=\\"o_control_panel\\"><ol class=\\"breadcrumb\\" role=\\"navigation\\"><li class=\\"breadcrumb-item active\\">Discuss</li></ol><div class=\\"o_cp_searchview\\" role=\\"search\\"><div class=\\"o_searchview\\" role=\\"search\\" aria-autocomplete=\\"list\\"><span class=\\"o_searchview_more fa\\" title=\\"Advanced Search...\\" role=\\"img\\" aria-label=\\"Advanced Search...\\"></span></div></div><div class=\\"o_cp_left\\"><div class=\\"o_cp_buttons\\" role=\\"toolbar\\" aria-label=\\"Control panel toolbar\\"></div><aside class=\\"o_cp_sidebar\\"></aside></div><div class=\\"o_cp_right\\"><div class=\\"btn-group o_search_options\\" role=\\"search\\"></div><nav class=\\"o_cp_pager\\" role=\\"search\\" aria-label=\\"Pager\\"></nav><nav class=\\"btn-group o_cp_switch_buttons\\" role=\\"toolbar\\" aria-label=\\"View switcher\\"></nav></div></div><div class=\\"o_content\\"><div class=\\"o_discuss_sidebar\\"><span>DISCUSS!!</span></div><div class=\\"o_discuss_content\\"><button>Reset first counter</button><button>Reset counter 2 in 3s</button><button>Toggle Clock/counters</button><button>Toggle Color</button><button>Rerender this widget</button><input><div><button>-</button><span style=\\"font-weight:bold\\">Value: 4</span><button>+</button></div><div><button>-</button><span style=\\"font-weight:bold\\">Value: 400</span><button>+</button></div><div><span>Current Color: </span>red</div><button>Add notif</button><button>Add sticky notif</button><button>Add warning</button></div></div></div></div><div class=\\"o_notification_container\\"></div><div class=\\"o_loading d-none\\">Loading</div></div>"`;
|
||||
|
||||
+19
@@ -32,6 +32,9 @@ const DISABLED_TAGS = [
|
||||
"optgroup"
|
||||
];
|
||||
|
||||
const lineBreakRE = /[\r\n]/;
|
||||
const whitespaceRE = /\s+/g;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Compilation Context
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -49,6 +52,7 @@ export class Context {
|
||||
shouldDefineOwner: boolean = false;
|
||||
shouldProtectContext: boolean = false;
|
||||
inLoop: boolean = false;
|
||||
inPreTag: boolean = false;
|
||||
|
||||
constructor() {
|
||||
this.rootContext = this;
|
||||
@@ -84,6 +88,12 @@ export class Context {
|
||||
return newContext;
|
||||
}
|
||||
|
||||
withInPre(): Context {
|
||||
const newContext = Object.create(this);
|
||||
newContext.inPreTag = true;
|
||||
return newContext;
|
||||
}
|
||||
|
||||
withCaller(node: Element): Context {
|
||||
const newContext = Object.create(this);
|
||||
newContext.caller = node;
|
||||
@@ -336,6 +346,12 @@ export class QWeb {
|
||||
if (!(node instanceof Element)) {
|
||||
// this is a text node, there are no directive to apply
|
||||
let text = node.textContent!;
|
||||
if (!ctx.inPreTag) {
|
||||
if (lineBreakRE.test(text) && !text.trim()) {
|
||||
return;
|
||||
}
|
||||
text = text.replace(whitespaceRE, " ");
|
||||
}
|
||||
if (ctx.parentNode) {
|
||||
ctx.addLine(`c${ctx.parentNode}.push({text: \`${text}\`});`);
|
||||
} else {
|
||||
@@ -410,6 +426,9 @@ export class QWeb {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.nodeName === "pre") {
|
||||
ctx = ctx.withInPre();
|
||||
}
|
||||
|
||||
this._compileChildren(node, ctx);
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = context['state'].numbers;
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -22,8 +20,6 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
||||
context.number_index = i;
|
||||
context.number = _3[i];
|
||||
context.number_value = _4[i];
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
//WIDGET
|
||||
let key8 = context['number'];
|
||||
let _5_index = c1.length;
|
||||
@@ -60,11 +56,7 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
||||
def6 = def6.then(()=>{if (w7.__widget__.isDestroyed) {return};let vnode;if (!w7.__widget__.vnode){vnode=w7.__widget__.pvnode} else { vnode=h(w7.__widget__.vnode.sel, {key: key8});vnode.elm=w7.el;vnode.data.hook = {insert(a){a.elm.parentNode.replaceChild(w7.el,a.elm);a.elm=w7.el;w7.__mount();},remove(){w7.destroy()}}}c1[_5_index]=vnode;});
|
||||
}
|
||||
extra.promises.push(def6);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -250,8 +250,6 @@ exports[`foreach does not pollute the rendering context 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = [1];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -269,8 +267,6 @@ exports[`foreach does not pollute the rendering context 1`] = `
|
||||
c1.push({text: e5});
|
||||
}
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -282,8 +278,6 @@ exports[`foreach iterate on items (on a element node) 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = [1, 2];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -304,8 +298,6 @@ exports[`foreach iterate on items (on a element node) 1`] = `
|
||||
c5.push({text: e6});
|
||||
}
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -317,8 +309,6 @@ exports[`foreach iterate on items 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = [3, 2, 1];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -331,8 +321,7 @@ exports[`foreach iterate on items 1`] = `
|
||||
context.item_index = i;
|
||||
context.item = _3[i];
|
||||
context.item_value = _4[i];
|
||||
c1.push({text: \`
|
||||
[\`});
|
||||
c1.push({text: \` [\`});
|
||||
let e5 = context['item_index'];
|
||||
if (e5 || e5 === 0) {
|
||||
c1.push({text: e5});
|
||||
@@ -347,11 +336,8 @@ exports[`foreach iterate on items 1`] = `
|
||||
if (e7 || e7 === 0) {
|
||||
c1.push({text: e7});
|
||||
}
|
||||
c1.push({text: \`]
|
||||
\`});
|
||||
c1.push({text: \`] \`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -363,8 +349,6 @@ exports[`foreach iterate, dict param 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = context['value'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -377,8 +361,7 @@ exports[`foreach iterate, dict param 1`] = `
|
||||
context.item_index = i;
|
||||
context.item = _3[i];
|
||||
context.item_value = _4[i];
|
||||
c1.push({text: \`
|
||||
[\`});
|
||||
c1.push({text: \` [\`});
|
||||
let e5 = context['item_index'];
|
||||
if (e5 || e5 === 0) {
|
||||
c1.push({text: e5});
|
||||
@@ -398,11 +381,8 @@ exports[`foreach iterate, dict param 1`] = `
|
||||
if (e8 || e8 === 0) {
|
||||
c1.push({text: e8});
|
||||
}
|
||||
c1.push({text: \`]
|
||||
\`});
|
||||
c1.push({text: \`] \`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -426,8 +406,7 @@ exports[`foreach iterate, integer param 1`] = `
|
||||
context.item_index = i;
|
||||
context.item = _3[i];
|
||||
context.item_value = _4[i];
|
||||
c1.push({text: \`
|
||||
[\`});
|
||||
c1.push({text: \` [\`});
|
||||
let e5 = context['item_index'];
|
||||
if (e5 || e5 === 0) {
|
||||
c1.push({text: e5});
|
||||
@@ -442,8 +421,7 @@ exports[`foreach iterate, integer param 1`] = `
|
||||
if (e7 || e7 === 0) {
|
||||
c1.push({text: e7});
|
||||
}
|
||||
c1.push({text: \`]
|
||||
\`});
|
||||
c1.push({text: \`] \`});
|
||||
}
|
||||
return vn1;
|
||||
}"
|
||||
@@ -456,8 +434,6 @@ exports[`foreach iterate, position 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = 5;
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -470,8 +446,7 @@ exports[`foreach iterate, position 1`] = `
|
||||
context.elem_index = i;
|
||||
context.elem = _3[i];
|
||||
context.elem_value = _4[i];
|
||||
c1.push({text: \`
|
||||
-\`});
|
||||
c1.push({text: \` -\`});
|
||||
if (context['elem_first']) {
|
||||
c1.push({text: \` first\`});
|
||||
}
|
||||
@@ -483,11 +458,8 @@ exports[`foreach iterate, position 1`] = `
|
||||
if (e5 || e5 === 0) {
|
||||
c1.push({text: e5});
|
||||
}
|
||||
c1.push({text: \`)
|
||||
\`});
|
||||
c1.push({text: \`) \`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -517,8 +489,6 @@ exports[`misc global 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = [4,5,6];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -531,8 +501,6 @@ exports[`misc global 1`] = `
|
||||
context.value_index = i;
|
||||
context.value = _3[i];
|
||||
context.value_value = _4[i];
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let c5 = [], p5 = {key:5,on:{}};
|
||||
let vn5 = h('span', p5, c5);
|
||||
c1.push(vn5);
|
||||
@@ -540,14 +508,10 @@ exports[`misc global 1`] = `
|
||||
if (e6 || e6 === 0) {
|
||||
c5.push({text: e6});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _7 = 'agüero';
|
||||
let c8 = [], p8 = {key:8,attrs:{\\"falló\\": _7},on:{}};
|
||||
let vn8 = h('Año', p8, c8);
|
||||
c1.push(vn8);
|
||||
c8.push({text: \`
|
||||
\`});
|
||||
let c9 = [], p9 = {key:9,on:{}};
|
||||
let vn9 = h('span', p9, c9);
|
||||
c8.push(vn9);
|
||||
@@ -557,8 +521,6 @@ exports[`misc global 1`] = `
|
||||
} else {
|
||||
c9.push({text: \`foo default\`});
|
||||
}
|
||||
c8.push({text: \`
|
||||
\`});
|
||||
let c11 = [], p11 = {key:11,on:{}};
|
||||
let vn11 = h('span', p11, c11);
|
||||
c8.push(vn11);
|
||||
@@ -568,10 +530,6 @@ exports[`misc global 1`] = `
|
||||
} else {
|
||||
c11.push({text: \`foo default\`});
|
||||
}
|
||||
c8.push({text: \`
|
||||
\`});
|
||||
c8.push({text: \`
|
||||
\`});
|
||||
let c13 = [], p13 = {key:13,on:{}};
|
||||
let vn13 = h('span', p13, c13);
|
||||
c8.push(vn13);
|
||||
@@ -581,13 +539,7 @@ exports[`misc global 1`] = `
|
||||
} else {
|
||||
c13.push({text: \`foo default\`});
|
||||
}
|
||||
c8.push({text: \`
|
||||
\`});
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let c15 = [], p15 = {key:15,on:{}};
|
||||
let vn15 = h('div', p15, c15);
|
||||
c1.push(vn15);
|
||||
@@ -602,8 +554,6 @@ exports[`misc global 1`] = `
|
||||
} else {
|
||||
c15.push({text: \`toto default\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -626,52 +576,36 @@ exports[`special cases for some boolean html attributes/properties various boole
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = 'checkbox';
|
||||
let _3 = 'checked';
|
||||
let c4 = [], p4 = {key:4,attrs:{type: _2,checked: _3},props:{checked: _3}};
|
||||
let vn4 = h('input', p4, c4);
|
||||
c1.push(vn4);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _5 = 'checked';
|
||||
let c6 = [], p6 = {key:6,attrs:{checked: _5}};
|
||||
let vn6 = h('input', p6, c6);
|
||||
c1.push(vn6);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _7 = 'checked';
|
||||
let c8 = [], p8 = {key:8,attrs:{checked: _7}};
|
||||
let vn8 = h('div', p8, c8);
|
||||
c1.push(vn8);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _9 = 'selected';
|
||||
let c10 = [], p10 = {key:10,attrs:{selected: _9}};
|
||||
let vn10 = h('div', p10, c10);
|
||||
c1.push(vn10);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _11 = 'selected';
|
||||
let _12 = '1';
|
||||
let c13 = [], p13 = {key:13,attrs:{selected: _11,other: _12},props:{selected: _11}};
|
||||
let vn13 = h('option', p13, c13);
|
||||
c1.push(vn13);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _14 = 'readonly';
|
||||
let c15 = [], p15 = {key:15,attrs:{readonly: _14},props:{readonly: _14}};
|
||||
let vn15 = h('input', p15, c15);
|
||||
c1.push(vn15);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _16 = 'disabled';
|
||||
let c17 = [], p17 = {key:17,attrs:{disabled: _16},props:{disabled: _16}};
|
||||
let vn17 = h('button', p17, c17);
|
||||
c1.push(vn17);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -751,17 +685,11 @@ exports[`t-call (template calling scoped parameters 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
c1.push({text: \`ok\`});
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let e2 = context['foo'];
|
||||
if (e2 || e2 === 0) {
|
||||
c1.push({text: e2});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -915,28 +843,20 @@ exports[`t-if boolean value condition else 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let c2 = [], p2 = {key:2};
|
||||
let vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
c2.push({text: \`begin\`});
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['condition']) {
|
||||
c1.push({text: \`ok\`});
|
||||
}
|
||||
else {
|
||||
c1.push({text: \`ok-else\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let c3 = [], p3 = {key:3};
|
||||
let vn3 = h('span', p3, c3);
|
||||
c1.push(vn3);
|
||||
c3.push({text: \`end\`});
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -1010,48 +930,30 @@ exports[`t-if can use some boolean operators in expressions 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['cond1'] && context['cond2']) {
|
||||
c1.push({text: \`and\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['cond1'] && context['cond3']) {
|
||||
c1.push({text: \`nope\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['cond1'] || context['cond3']) {
|
||||
c1.push({text: \`or\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['cond3'] || context['cond4']) {
|
||||
c1.push({text: \`nope\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['m'] > 3) {
|
||||
c1.push({text: \`mgt\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['n'] > 3) {
|
||||
c1.push({text: \`ngt\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['m'] < 3) {
|
||||
c1.push({text: \`mlt\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
if (context['n'] < 3) {
|
||||
c1.push({text: \`nlt\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -1117,8 +1019,6 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('ul', p1, c1);
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
let _2 = ['someval'];
|
||||
if (!_2) { throw new Error('QWeb error: Invalid loop expression')}
|
||||
if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())}
|
||||
@@ -1140,8 +1040,6 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = `
|
||||
p6.on['click'] = context['activate'].bind(owner, context['action']);
|
||||
c6.push({text: \`link\`});
|
||||
}
|
||||
c1.push({text: \`
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
@@ -1387,3 +1285,76 @@ exports[`t-set value priority 1`] = `
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling consecutives whitespaces are condensed into a single space 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \` abc \`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling nothing is done in pre tags 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('pre', p1, c1);
|
||||
c1.push({text: \` \`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling nothing is done in pre tags 2`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('pre', p1, c1);
|
||||
c1.push({text: \`
|
||||
some text
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling nothing is done in pre tags 3`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('pre', p1, c1);
|
||||
c1.push({text: \`
|
||||
|
||||
\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling white space only text nodes are condensed into a single space 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
c1.push({text: \` \`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`whitespace handling whitespace only text nodes with newlines are removed 1`] = `
|
||||
"function anonymous(context,extra
|
||||
) {
|
||||
let h = this.utils.h;
|
||||
let c1 = [], p1 = {key:1};
|
||||
let vn1 = h('div', p1, c1);
|
||||
let c2 = [], p2 = {key:2};
|
||||
let vn2 = h('span', p2, c2);
|
||||
c1.push(vn2);
|
||||
c2.push({text: \`abc\`});
|
||||
return vn1;
|
||||
}"
|
||||
`;
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`connecting a component to store connecting a component works 1`] = `
|
||||
"<div>
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`connecting a component to store connecting a component works 1`] = `"<div></div>"`;
|
||||
|
||||
exports[`connecting a component to store connecting a component works 2`] = `
|
||||
"<div>
|
||||
|
||||
<span>hello</span>
|
||||
|
||||
</div>"
|
||||
`;
|
||||
exports[`connecting a component to store connecting a component works 2`] = `"<div><span>hello</span></div>"`;
|
||||
|
||||
@@ -921,3 +921,48 @@ describe("special cases for some boolean html attributes/properties", () => {
|
||||
renderToString(qweb, "test", { flag: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("whitespace handling", () => {
|
||||
test("white space only text nodes are condensed into a single space", () => {
|
||||
qweb.addTemplate("test", `<div> </div>`);
|
||||
const result = renderToString(qweb, "test");
|
||||
expect(result).toBe(`<div> </div>`);
|
||||
});
|
||||
|
||||
test("consecutives whitespaces are condensed into a single space", () => {
|
||||
qweb.addTemplate("test", `<div> abc </div>`);
|
||||
const result = renderToString(qweb, "test");
|
||||
expect(result).toBe(`<div> abc </div>`);
|
||||
});
|
||||
|
||||
test("whitespace only text nodes with newlines are removed", () => {
|
||||
qweb.addTemplate(
|
||||
"test",
|
||||
`<div>
|
||||
<span>abc</span>
|
||||
</div>`
|
||||
);
|
||||
const result = renderToString(qweb, "test");
|
||||
expect(result).toBe(`<div><span>abc</span></div>`);
|
||||
});
|
||||
|
||||
test("nothing is done in pre tags", () => {
|
||||
qweb.addTemplate("test", `<pre> </pre>`);
|
||||
const result = renderToString(qweb, "test");
|
||||
expect(result).toBe(`<pre> </pre>`);
|
||||
|
||||
const pretagtext = `<pre>
|
||||
some text
|
||||
</pre>`;
|
||||
qweb.addTemplate("test2", pretagtext);
|
||||
const result2 = renderToString(qweb, "test2");
|
||||
expect(result2).toBe(pretagtext);
|
||||
|
||||
const pretagwithonlywhitespace = `<pre>
|
||||
|
||||
</pre>`;
|
||||
qweb.addTemplate("test3", pretagwithonlywhitespace);
|
||||
const result3 = renderToString(qweb, "test3");
|
||||
expect(result3).toBe(pretagwithonlywhitespace);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user