mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+5
-3
@@ -497,10 +497,10 @@ directive is there to help.
|
|||||||
Whenever a node has a `t-transition` directive, with a `name` value, the following
|
Whenever a node has a `t-transition` directive, with a `name` value, the following
|
||||||
will happen:
|
will happen:
|
||||||
|
|
||||||
At node creation:
|
At node insertion:
|
||||||
|
|
||||||
- the css classes `name-enter` and `name-enter-active` will be added before the
|
- the css classes `name-enter` and `name-enter-active` will be added directly
|
||||||
node is added to the DOM,
|
when the node is inserted into the DOM,
|
||||||
- on the next animation frame: the css class `name-enter` will be removed and the
|
- on the next animation frame: the css class `name-enter` will be removed and the
|
||||||
class `name-enter-to` will be added (so they can be used to trigger css
|
class `name-enter-to` will be added (so they can be used to trigger css
|
||||||
transition effects),
|
transition effects),
|
||||||
@@ -535,6 +535,8 @@ For example, a simple fade in/out effect can be done with this:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `t-transition` directive can be combined with `t-widget`.
|
||||||
|
|
||||||
Note: more information on animations are available [here](doc/animations.md).
|
Note: more information on animations are available [here](doc/animations.md).
|
||||||
|
|
||||||
### `t-mounted` directive
|
### `t-mounted` directive
|
||||||
|
|||||||
@@ -269,6 +269,9 @@ export class QWeb {
|
|||||||
// pollute the rendering context by adding some keys in it.
|
// pollute the rendering context by adding some keys in it.
|
||||||
ctx.code.unshift(" let owner = context;");
|
ctx.code.unshift(" let owner = context;");
|
||||||
}
|
}
|
||||||
|
if (ctx.shouldDefineUtils) {
|
||||||
|
ctx.code.unshift(" let utils = this.utils;");
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx.rootNode) {
|
if (!ctx.rootNode) {
|
||||||
throw new Error("A template should have one root node");
|
throw new Error("A template should have one root node");
|
||||||
@@ -613,6 +616,7 @@ export class Context {
|
|||||||
rootContext: Context;
|
rootContext: Context;
|
||||||
caller: Element | undefined;
|
caller: Element | undefined;
|
||||||
shouldDefineOwner: boolean = false;
|
shouldDefineOwner: boolean = false;
|
||||||
|
shouldDefineUtils: boolean = false;
|
||||||
shouldProtectContext: boolean = false;
|
shouldProtectContext: boolean = false;
|
||||||
inLoop: boolean = false;
|
inLoop: boolean = false;
|
||||||
inPreTag: boolean = false;
|
inPreTag: boolean = false;
|
||||||
|
|||||||
+37
-10
@@ -192,7 +192,10 @@ QWeb.addDirective({
|
|||||||
* explanation of the code generated by the t-widget directive for the following
|
* explanation of the code generated by the t-widget directive for the following
|
||||||
* situation:
|
* situation:
|
||||||
* ```xml
|
* ```xml
|
||||||
* <t t-widget="child" t-key="'somestring'" t-props="{flag:state.flag}"/>
|
* <t t-widget="child"
|
||||||
|
* t-key="'somestring'"
|
||||||
|
* t-props="{flag:state.flag}"
|
||||||
|
* t-transition="fade"/>
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
@@ -252,6 +255,8 @@ QWeb.addDirective({
|
|||||||
* }
|
* }
|
||||||
* w4 = new W4(owner, props4);
|
* w4 = new W4(owner, props4);
|
||||||
*
|
*
|
||||||
|
* let utils = this.utils;
|
||||||
|
*
|
||||||
* // Whenever we rerender the parent widget, we need to be sure that we
|
* // Whenever we rerender the parent widget, we need to be sure that we
|
||||||
* // are able to find the widget instance. To do that, we register it to
|
* // are able to find the widget instance. To do that, we register it to
|
||||||
* // the parent cmap (children map). Note that the 'template' key is
|
* // the parent cmap (children map). Note that the 'template' key is
|
||||||
@@ -281,15 +286,21 @@ QWeb.addDirective({
|
|||||||
* // to synchronise the pvnode elm with the resulting elm
|
* // to synchronise the pvnode elm with the resulting elm
|
||||||
* let nvn = w4._mount(vnode, vn.elm);
|
* let nvn = w4._mount(vnode, vn.elm);
|
||||||
* pvnode.elm = nvn.elm;
|
* pvnode.elm = nvn.elm;
|
||||||
|
* // what follows is only present if there are animations on the widget
|
||||||
|
* utils.transitionInsert(vn.elm, "fade");
|
||||||
* },
|
* },
|
||||||
* remove() {
|
* remove() {
|
||||||
* // apparently, in some cases, it is necessary to call the destroy
|
* // override with empty function to prevent from removing the node
|
||||||
* // method here
|
* // directly. It will be removed when destroy is called anyway, which
|
||||||
* w4.destroy();
|
* // delays the removal if there are animations.
|
||||||
* },
|
* },
|
||||||
* destroy() {
|
* destroy() {
|
||||||
* // and here...
|
* // if there are animations, we delay the call to destroy on the
|
||||||
|
* // widget, if not, we call it directly.
|
||||||
|
* let finalize = () => {
|
||||||
* w4.destroy();
|
* w4.destroy();
|
||||||
|
* };
|
||||||
|
* utils.transitionRemove(vn.elm, "fade", finalize);
|
||||||
* }
|
* }
|
||||||
* };
|
* };
|
||||||
* // the pvnode is inserted at the correct position in the div's children
|
* // the pvnode is inserted at the correct position in the div's children
|
||||||
@@ -332,16 +343,20 @@ QWeb.addDirective({
|
|||||||
atNodeEncounter({ ctx, value, node }): boolean {
|
atNodeEncounter({ ctx, value, node }): boolean {
|
||||||
ctx.addLine("//WIDGET");
|
ctx.addLine("//WIDGET");
|
||||||
ctx.rootContext.shouldDefineOwner = true;
|
ctx.rootContext.shouldDefineOwner = true;
|
||||||
|
ctx.rootContext.shouldDefineUtils = true;
|
||||||
let props = node.getAttribute("t-props");
|
let props = node.getAttribute("t-props");
|
||||||
let keepAlive = node.getAttribute("t-keepalive") ? true : false;
|
let keepAlive = node.getAttribute("t-keepalive") ? true : false;
|
||||||
|
|
||||||
// t-on- events...
|
// t-on- events and t-transition
|
||||||
const events: [string, string][] = [];
|
const events: [string, string][] = [];
|
||||||
|
let transition: string = "";
|
||||||
const attributes = (<Element>node).attributes;
|
const attributes = (<Element>node).attributes;
|
||||||
for (let i = 0; i < attributes.length; i++) {
|
for (let i = 0; i < attributes.length; i++) {
|
||||||
const name = attributes[i].name;
|
const name = attributes[i].name;
|
||||||
if (name.startsWith("t-on-")) {
|
if (name.startsWith("t-on-")) {
|
||||||
events.push([name.slice(5), attributes[i].textContent!]);
|
events.push([name.slice(5), attributes[i].textContent!]);
|
||||||
|
} else if (name === "t-transition") {
|
||||||
|
transition = attributes[i].textContent!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,13 +393,23 @@ QWeb.addDirective({
|
|||||||
ctx.addLine(`const ${refKey} = ${ctx.formatExpression(ref)}`);
|
ctx.addLine(`const ${refKey} = ${ctx.formatExpression(ref)}`);
|
||||||
refExpr = `context.refs[${refKey}] = w${widgetID};`;
|
refExpr = `context.refs[${refKey}] = w${widgetID};`;
|
||||||
}
|
}
|
||||||
|
let transitionsInsertCode = "";
|
||||||
|
if (transition) {
|
||||||
|
transitionsInsertCode = `utils.transitionInsert(vn.elm, '${transition}');`;
|
||||||
|
}
|
||||||
let finalizeWidgetCode = `w${widgetID}.${
|
let finalizeWidgetCode = `w${widgetID}.${
|
||||||
keepAlive ? "unmount" : "destroy"
|
keepAlive ? "unmount" : "destroy"
|
||||||
}()`;
|
}();`;
|
||||||
if (ref) {
|
if (ref) {
|
||||||
finalizeWidgetCode += `;delete context.refs[${refKey}]`;
|
finalizeWidgetCode += `delete context.refs[${refKey}];`; // FIXME: shouldn't we keep ref if keepAlive is true?
|
||||||
}
|
}
|
||||||
|
if (transition) {
|
||||||
|
finalizeWidgetCode = `let finalize = () => {
|
||||||
|
${finalizeWidgetCode}
|
||||||
|
};
|
||||||
|
utils.transitionRemove(vn.elm, '${transition}', finalize);`;
|
||||||
|
}
|
||||||
|
|
||||||
let createHook = "";
|
let createHook = "";
|
||||||
let classAttr = node.getAttribute("class");
|
let classAttr = node.getAttribute("class");
|
||||||
let tattClass = node.getAttribute("t-att-class");
|
let tattClass = node.getAttribute("t-att-class");
|
||||||
@@ -447,8 +472,10 @@ QWeb.addDirective({
|
|||||||
ctx.addLine(`w${widgetID}.on('${event}', owner, owner['${method}'])`);
|
ctx.addLine(`w${widgetID}.on('${event}', owner, owner['${method}'])`);
|
||||||
}
|
}
|
||||||
ctx.addLine(`def${defID} = w${widgetID}._prepare();`);
|
ctx.addLine(`def${defID} = w${widgetID}._prepare();`);
|
||||||
|
// hack: specify empty remove hook to prevent the node from being removed from the DOM
|
||||||
|
// FIXME: click to re-add widget during remove transition -> leak
|
||||||
ctx.addLine(
|
ctx.addLine(
|
||||||
`def${defID} = def${defID}.then(vnode=>{${createHook}let pvnode=h(vnode.sel, {key: ${templateID}, hook: {insert(vn){let nvn=w${widgetID}._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;${refExpr}},remove(){${finalizeWidgetCode}},destroy(){${finalizeWidgetCode}}}});c${
|
`def${defID} = def${defID}.then(vnode=>{${createHook}let pvnode=h(vnode.sel, {key: ${templateID}, hook: {insert(vn) {let nvn=w${widgetID}._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;${refExpr}${transitionsInsertCode}},remove() {},destroy(vn) {${finalizeWidgetCode}}}});c${
|
||||||
ctx.parentNode
|
ctx.parentNode
|
||||||
}[_${dummyID}_index]=pvnode;w${widgetID}.__owl__.pvnode = pvnode;});`
|
}[_${dummyID}_index]=pvnode;w${widgetID}.__owl__.pvnode = pvnode;});`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,85 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`animations t-transition combined with t-widget 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
|
let owner = context;
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('div', p1, c1);
|
||||||
|
//WIDGET
|
||||||
|
let _2_index = c1.length;
|
||||||
|
c1.push(null);
|
||||||
|
let def3;
|
||||||
|
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
||||||
|
let props4 = {};
|
||||||
|
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
||||||
|
w4.destroy();
|
||||||
|
w4 = false
|
||||||
|
}
|
||||||
|
if (!w4) {
|
||||||
|
let W4 = context.widgets['Child'];
|
||||||
|
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
||||||
|
w4 = new W4(owner, props4);
|
||||||
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
|
def3 = w4._prepare();
|
||||||
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
||||||
|
w4.destroy();
|
||||||
|
};
|
||||||
|
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
|
} else {
|
||||||
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
}
|
||||||
|
extra.promises.push(def3);
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`animations t-transition combined with t-widget and t-if 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
|
let owner = context;
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('div', p1, c1);
|
||||||
|
if (context['state'].display) {
|
||||||
|
//WIDGET
|
||||||
|
let _2_index = c1.length;
|
||||||
|
c1.push(null);
|
||||||
|
let def3;
|
||||||
|
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
||||||
|
let props4 = {};
|
||||||
|
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
||||||
|
w4.destroy();
|
||||||
|
w4 = false
|
||||||
|
}
|
||||||
|
if (!w4) {
|
||||||
|
let W4 = context.widgets['Child'];
|
||||||
|
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
||||||
|
w4 = new W4(owner, props4);
|
||||||
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
|
def3 = w4._prepare();
|
||||||
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
||||||
|
w4.destroy();
|
||||||
|
};
|
||||||
|
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
|
} else {
|
||||||
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
}
|
||||||
|
extra.promises.push(def3);
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`class and style attributes with t-widget dynamic t-att-style is properly added and updated on widget root el 1`] = `
|
exports[`class and style attributes with t-widget dynamic t-att-style is properly added and updated on widget root el 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
let owner = context;
|
let owner = context;
|
||||||
var h = this.utils.h;
|
var h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
@@ -24,7 +101,7 @@ exports[`class and style attributes with t-widget dynamic t-att-style is properl
|
|||||||
w4 = new W4(owner, props4);
|
w4 = new W4(owner, props4);
|
||||||
context.__owl__.cmap[4] = w4.__owl__.id;
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
def3 = w4._prepare();
|
def3 = w4._prepare();
|
||||||
def3 = def3.then(vnode=>{vnode.data.hook = {create(_, vn){vn.elm.style = _5}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn){let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
def3 = def3.then(vnode=>{vnode.data.hook = {create(_, vn){vn.elm.style = _5}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
} else {
|
} else {
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};w4.el.style=_5;let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};w4.el.style=_5;let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
@@ -37,6 +114,7 @@ exports[`class and style attributes with t-widget dynamic t-att-style is properl
|
|||||||
exports[`class and style attributes with t-widget t-att-class is properly added/removed on widget root el 1`] = `
|
exports[`class and style attributes with t-widget t-att-class is properly added/removed on widget root el 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
let owner = context;
|
let owner = context;
|
||||||
var h = this.utils.h;
|
var h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
@@ -62,7 +140,7 @@ exports[`class and style attributes with t-widget t-att-class is properly added/
|
|||||||
if (_5[k]) {
|
if (_5[k]) {
|
||||||
vn.elm.classList.add(k);
|
vn.elm.classList.add(k);
|
||||||
}
|
}
|
||||||
}}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn){let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
}}};let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
} else {
|
} else {
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let cl=w4.el.classList;for (let k in _5) {if (_5[k]) {cl.add(k)} else {cl.remove(k)}}let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let cl=w4.el.classList;for (let k in _5) {if (_5[k]) {cl.add(k)} else {cl.remove(k)}}let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
@@ -75,6 +153,7 @@ exports[`class and style attributes with t-widget t-att-class is properly added/
|
|||||||
exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
let owner = context;
|
let owner = context;
|
||||||
context = Object.create(context);
|
context = Object.create(context);
|
||||||
var h = this.utils.h;
|
var h = this.utils.h;
|
||||||
@@ -109,7 +188,7 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
|||||||
w7 = new W7(owner, props7);
|
w7 = new W7(owner, props7);
|
||||||
context.__owl__.cmap[key8] = w7.__owl__.id;
|
context.__owl__.cmap[key8] = w7.__owl__.id;
|
||||||
def6 = w7._prepare();
|
def6 = w7._prepare();
|
||||||
def6 = def6.then(vnode=>{let pvnode=h(vnode.sel, {key: key8, hook: {insert(vn){let nvn=w7._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove(){w7.destroy()},destroy(){w7.destroy()}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;});
|
def6 = def6.then(vnode=>{let pvnode=h(vnode.sel, {key: key8, hook: {insert(vn) {let nvn=w7._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w7.destroy();}}});c1[_5_index]=pvnode;w7.__owl__.pvnode = pvnode;});
|
||||||
} else {
|
} else {
|
||||||
def6 = w7._updateProps(props7, extra.forceUpdate, extra.patchQueue);
|
def6 = w7._updateProps(props7, extra.forceUpdate, extra.patchQueue);
|
||||||
def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;c1[_5_index]=pvnode;});
|
def6 = def6.then(()=>{if (w7.__owl__.isDestroyed) {return};let pvnode=w7.__owl__.pvnode;c1[_5_index]=pvnode;});
|
||||||
@@ -123,6 +202,7 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = `
|
|||||||
exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
let owner = context;
|
let owner = context;
|
||||||
var h = this.utils.h;
|
var h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
@@ -144,7 +224,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
|||||||
w4 = new W4(owner, props4);
|
w4 = new W4(owner, props4);
|
||||||
context.__owl__.cmap[key5] = w4.__owl__.id;
|
context.__owl__.cmap[key5] = w4.__owl__.id;
|
||||||
def3 = w4._prepare();
|
def3 = w4._prepare();
|
||||||
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: key5, hook: {insert(vn){let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: key5, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
} else {
|
} else {
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
@@ -157,6 +237,7 @@ exports[`random stuff/miscellaneous snapshotting compiled code 1`] = `
|
|||||||
exports[`random stuff/miscellaneous t-props should not be undefined (snapshotting) 1`] = `
|
exports[`random stuff/miscellaneous t-props should not be undefined (snapshotting) 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
let owner = context;
|
let owner = context;
|
||||||
var h = this.utils.h;
|
var h = this.utils.h;
|
||||||
let c1 = [], p1 = {key:1};
|
let c1 = [], p1 = {key:1};
|
||||||
@@ -177,7 +258,7 @@ exports[`random stuff/miscellaneous t-props should not be undefined (snapshottin
|
|||||||
w4 = new W4(owner, props4);
|
w4 = new W4(owner, props4);
|
||||||
context.__owl__.cmap[4] = w4.__owl__.id;
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
def3 = w4._prepare();
|
def3 = w4._prepare();
|
||||||
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn){let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove(){w4.destroy()},destroy(){w4.destroy()}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;},remove() {},destroy(vn) {w4.destroy();}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
} else {
|
} else {
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
function anonymous(context, extra) {
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('div', p1, c1);
|
||||||
|
if (context['state'].display) {
|
||||||
|
//WIDGET
|
||||||
|
let _2_index = c1.length;
|
||||||
|
c1.push(null);
|
||||||
|
let def3;
|
||||||
|
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
||||||
|
let props4 = {};
|
||||||
|
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
||||||
|
w4.destroy();
|
||||||
|
w4 = false
|
||||||
|
}
|
||||||
|
if (!w4) {
|
||||||
|
let W4 = context.widgets['Child'];
|
||||||
|
if (!W4) {throw new Error(`Cannot find the definition of widget "Child"`)}
|
||||||
|
w4 = new W4(owner, props4);
|
||||||
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
|
def3 = w4._prepare();
|
||||||
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert: (vn) => {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;this.utils.transitionInsert(vn.elm, 'chimay');},remove: () => {},destroy: (vn) => {let finalize = () => {
|
||||||
|
w4.destroy();
|
||||||
|
};
|
||||||
|
this.utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
|
} else {
|
||||||
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
}
|
||||||
|
extra.promises.push(def3);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+97
-2
@@ -1778,7 +1778,6 @@ describe("random stuff/miscellaneous", () => {
|
|||||||
"C:_patch",
|
"C:_patch",
|
||||||
"E:willUnmount",
|
"E:willUnmount",
|
||||||
"E:destroy",
|
"E:destroy",
|
||||||
"E:destroy", // maybe should look into this
|
|
||||||
"F:_patch(from _mount)",
|
"F:_patch(from _mount)",
|
||||||
"F:mounted",
|
"F:mounted",
|
||||||
"D:_patch",
|
"D:_patch",
|
||||||
@@ -2281,7 +2280,7 @@ describe("t-mounted directive", () => {
|
|||||||
widget.f = jest.fn();
|
widget.f = jest.fn();
|
||||||
await widget.mount(fixture);
|
await widget.mount(fixture);
|
||||||
|
|
||||||
patchNextFrame((cb) => cb());
|
patchNextFrame(cb => cb());
|
||||||
expect(widget.f).toHaveBeenCalledTimes(0);
|
expect(widget.f).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
widget.state.flag = true;
|
widget.state.flag = true;
|
||||||
@@ -2426,4 +2425,100 @@ describe("animations", () => {
|
|||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
expect(spanNode.className).toBe("");
|
expect(spanNode.className).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-widget", async () => {
|
||||||
|
expect.assertions(5);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"Parent",
|
||||||
|
`<div><t t-widget="Child" t-transition="chimay"/></div>`
|
||||||
|
);
|
||||||
|
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||||
|
class Parent extends Widget {
|
||||||
|
widgets = { Child: Child };
|
||||||
|
}
|
||||||
|
class Child extends Widget {}
|
||||||
|
const widget = new Parent(env);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb(performance.now());
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
|
||||||
|
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-widget and t-if", async () => {
|
||||||
|
expect.assertions(8);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"Parent",
|
||||||
|
`<div><t t-if="state.display" t-widget="Child" t-transition="chimay"/></div>`
|
||||||
|
);
|
||||||
|
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||||
|
class Parent extends Widget {
|
||||||
|
widgets = { Child: Child };
|
||||||
|
state = { display: true };
|
||||||
|
}
|
||||||
|
class Child extends Widget {}
|
||||||
|
const widget = new Parent(env);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb(performance.now());
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
|
||||||
|
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||||
|
|
||||||
|
// remove span from the DOM
|
||||||
|
def = makeDeferred();
|
||||||
|
widget.state.display = false;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-leave chimay-leave-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb(performance.now());
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-leave-active chimay-leave-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user