mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
ed4ab51c17
This is a really interesting problem: there was a situation where a component would not have an event handler properly bound. The reason was that we were in a situation where the scheduler task queue was flushed at an unfortunate timing: - parent component template is rendered - subcomponent is prepared: - sub component is willStarted - it is rendered (so, fiber counter is set to 0) - scheduler task queue is flushed => we patch the DOM - the code registered in the __prepare.then(handler) is executed, which add the createHook to the vnode (but after the dom is patched) Usually, the last two steps happen in a different order, but in an environment with connected components, we sometimes flush the task queue at various moments, so some code could be executed between the end of __prepare and the registered handler. The fix is interesting: we give a callback to the __prepare function instead of registering a .then handler to the deferred. This callback is then guaranteed to be called at exactly the proper timing. Thanks seb for the hard work of finding the root cause of this issue closes #520
178 lines
6.6 KiB
Plaintext
178 lines
6.6 KiB
Plaintext
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
|
|
exports[`animations t-transition combined with component 1`] = `
|
|
"function anonymous(context,extra
|
|
) {
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
let owner = context;
|
|
var h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
var vn1 = h('div', p1, c1);
|
|
//COMPONENT
|
|
let k3 = \`__4__\`;
|
|
let w2 = k3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[k3]] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined, undefined);
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`Child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| context['Child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
const __patch2 = w2.__patch;
|
|
w2.__patch = fiber => {__patch2.call(w2, fiber); if(!w2.__owl__.transitionInserted){w2.__owl__.transitionInserted = true;utils.transitionInsert(w2.__owl__.vnode, 'chimay');}};
|
|
parent.__owl__.cmap[k3] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; });
|
|
let pvnode = h('dummy', {key: k3, hook: {remove() {},destroy(vn) {let finalize = () => {
|
|
w2.destroy();
|
|
};
|
|
delete w2.__owl__.transitionInserted;
|
|
utils.transitionRemove(vn, 'chimay', finalize);}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`animations t-transition combined with t-component and t-if 1`] = `
|
|
"function anonymous(context,extra
|
|
) {
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
let owner = context;
|
|
var h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
var vn1 = h('div', p1, c1);
|
|
if (context['state'].display) {
|
|
//COMPONENT
|
|
let k3 = \`__4__\`;
|
|
let w2 = k3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[k3]] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined, undefined);
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`Child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| context['Child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
const __patch2 = w2.__patch;
|
|
w2.__patch = fiber => {__patch2.call(w2, fiber); if(!w2.__owl__.transitionInserted){w2.__owl__.transitionInserted = true;utils.transitionInsert(w2.__owl__.vnode, 'chimay');}};
|
|
parent.__owl__.cmap[k3] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; });
|
|
let pvnode = h('dummy', {key: k3, hook: {remove() {},destroy(vn) {let finalize = () => {
|
|
w2.destroy();
|
|
};
|
|
delete w2.__owl__.transitionInserted;
|
|
utils.transitionRemove(vn, 'chimay', finalize);}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
}
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`animations t-transition combined with t-component, remove and re-add before transitionend 1`] = `
|
|
"function anonymous(context,extra
|
|
) {
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
let owner = context;
|
|
var h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
var vn1 = h('div', p1, c1);
|
|
if (context['state'].flag) {
|
|
//COMPONENT
|
|
let k3 = \`__4__\`;
|
|
let w2 = k3 in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap[k3]] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined, undefined);
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`Child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| context['Child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
const __patch2 = w2.__patch;
|
|
w2.__patch = fiber => {__patch2.call(w2, fiber); if(!w2.__owl__.transitionInserted){w2.__owl__.transitionInserted = true;utils.transitionInsert(w2.__owl__.vnode, 'chimay');}};
|
|
parent.__owl__.cmap[k3] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; });
|
|
let pvnode = h('dummy', {key: k3, hook: {remove() {},destroy(vn) {let finalize = () => {
|
|
w2.destroy();
|
|
};
|
|
delete w2.__owl__.transitionInserted;
|
|
utils.transitionRemove(vn, 'chimay', finalize);}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
}
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`animations t-transition with no delay/duration 1`] = `
|
|
"function anonymous(context,extra
|
|
) {
|
|
let utils = this.constructor.utils;
|
|
var h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
var vn1 = h('span', p1, c1);
|
|
p1.hook = {
|
|
insert: vn => {
|
|
utils.transitionInsert(vn, 'jupiler');
|
|
},
|
|
remove: (vn, rm) => {
|
|
utils.transitionRemove(vn, 'jupiler', rm);
|
|
},
|
|
};
|
|
c1.push({text: \`blue\`});
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`animations t-transition, on a simple node (insert) 1`] = `
|
|
"function anonymous(context,extra
|
|
) {
|
|
let utils = this.constructor.utils;
|
|
var h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
var vn1 = h('span', p1, c1);
|
|
p1.hook = {
|
|
insert: vn => {
|
|
utils.transitionInsert(vn, 'chimay');
|
|
},
|
|
remove: (vn, rm) => {
|
|
utils.transitionRemove(vn, 'chimay', rm);
|
|
},
|
|
};
|
|
c1.push({text: \`blue\`});
|
|
return vn1;
|
|
}"
|
|
`;
|