mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
0290f63ba3
The initial problem solved by this commit is that it was possible to get into a situation where a mounting/rendering was started, then the component was updated, but then another mounting operation begins, and it tries to reuse the previous rendering operation, which is no longer uptodate. The underlying issue is that Owl did not track properly the various internal state change of a component. These issue should be solved by the introduction of the status enum, which currently tracks 6 possible states: - CREATED - WILLSTARTED - RENDERED - MOUNTED - UNMOUNTED - DESTROYED This status number replaces the isMounted and isDestroyed boolean flags. It has the advantage of making sure that the component is in a consistent state (it is no longer possible to be destroyed and mounted, for example) Another advantage is that it gives us an easy way to track the fact that a component has been rendered, but is not in the DOM. This is a subtle situation where some various events can happen, and we need to be able to react to that case. Note that there is a change of behaviour: if a component is mounted in a specific target, then before the mounting is complete, the component is mounted in another target, we no longer reject the first mounting operation.
157 lines
6.3 KiB
Plaintext
157 lines
6.3 KiB
Plaintext
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
|
|
exports[`class and style attributes with t-component dynamic t-att-style is properly added and updated on widget root el 1`] = `
|
|
"function anonymous(context, extra
|
|
) {
|
|
// Template name: \\"ParentWidget\\"
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
let scope = Object.create(context);
|
|
let h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
let vn1 = h('div', p1, c1);
|
|
// Component 'child'
|
|
const _4 = scope['state'].style;
|
|
let w2 = '__3__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__3__']] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined).then(()=>{if (w2.__owl__.status === 5) {return};w2.el.style=_4;});;
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| scope['child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){vn.elm.style = _4;}});});
|
|
let pvnode = h('dummy', {key: '__3__', hook: {remove() {},destroy(vn) {w2.destroy();}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`class and style attributes with t-component t-att-class is properly added/removed on widget root el (v2) 1`] = `
|
|
"function anonymous(context, extra
|
|
) {
|
|
// Template name: \\"ParentWidget\\"
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
context.__owl__.refs = context.__owl__.refs || {};
|
|
let scope = Object.create(context);
|
|
let h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
let vn1 = h('div', p1, c1);
|
|
// Component 'Child'
|
|
const ref4 = \`child\`;
|
|
let _5 = {'a':true};
|
|
Object.assign(_5, {b:scope['state'].b})
|
|
let w2 = '__3__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__3__']] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined);
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`Child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| scope['Child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){}});});
|
|
let pvnode = h('dummy', {key: '__3__', hook: {insert(vn) {context.__owl__.refs[ref4] = w2;},remove() {},destroy(vn) {w2.destroy();delete context.__owl__.refs[ref4];}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.classObj=_5;
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`class and style attributes with t-component t-att-class is properly added/removed on widget root el (v2) 2`] = `
|
|
"function anonymous(context, extra
|
|
) {
|
|
// Template name: \\"Child\\"
|
|
let utils = this.constructor.utils;
|
|
let scope = Object.create(context);
|
|
let h = this.h;
|
|
let _7 = {'c':true};
|
|
Object.assign(_7, utils.toObj({d:scope['state'].d}))
|
|
let c8 = [], p8 = {key:8,class:_7};
|
|
let vn8 = h('span', p8, c8);
|
|
return vn8;
|
|
}"
|
|
`;
|
|
|
|
exports[`class and style attributes with t-component t-att-class is properly added/removed on widget root el (v3) 1`] = `
|
|
"function anonymous(context, extra
|
|
) {
|
|
// Template name: \\"ParentWidget\\"
|
|
let utils = this.constructor.utils;
|
|
let QWeb = this.constructor;
|
|
let parent = context;
|
|
context.__owl__.refs = context.__owl__.refs || {};
|
|
let scope = Object.create(context);
|
|
let h = this.h;
|
|
let c1 = [], p1 = {key:1};
|
|
let vn1 = h('div', p1, c1);
|
|
// Component 'Child'
|
|
const ref4 = \`child\`;
|
|
let _5 = {'a':true};
|
|
Object.assign(_5, utils.toObj(scope['state'].b?'b':''))
|
|
let w2 = '__3__' in parent.__owl__.cmap ? parent.__owl__.children[parent.__owl__.cmap['__3__']] : false;
|
|
let props2 = {};
|
|
if (w2 && w2.__owl__.currentFiber && !w2.__owl__.vnode) {
|
|
w2.destroy();
|
|
w2 = false;
|
|
}
|
|
if (w2) {
|
|
w2.__updateProps(props2, extra.fiber, undefined);
|
|
let pvnode = w2.__owl__.pvnode;
|
|
c1.push(pvnode);
|
|
} else {
|
|
let componentKey2 = \`Child\`;
|
|
let W2 = context.constructor.components[componentKey2] || QWeb.components[componentKey2]|| scope['Child'];
|
|
if (!W2) {throw new Error('Cannot find the definition of component \\"' + componentKey2 + '\\"')}
|
|
w2 = new W2(parent, props2);
|
|
parent.__owl__.cmap['__3__'] = w2.__owl__.id;
|
|
let fiber = w2.__prepare(extra.fiber, undefined, () => { const vnode = fiber.vnode; pvnode.sel = vnode.sel; utils.assignHooks(vnode.data, {create(_, vn){}});});
|
|
let pvnode = h('dummy', {key: '__3__', hook: {insert(vn) {context.__owl__.refs[ref4] = w2;},remove() {},destroy(vn) {w2.destroy();delete context.__owl__.refs[ref4];}}});
|
|
c1.push(pvnode);
|
|
w2.__owl__.pvnode = pvnode;
|
|
}
|
|
w2.__owl__.classObj=_5;
|
|
w2.__owl__.parentLastFiberId = extra.fiber.id;
|
|
return vn1;
|
|
}"
|
|
`;
|
|
|
|
exports[`class and style attributes with t-component t-att-class is properly added/removed on widget root el (v3) 2`] = `
|
|
"function anonymous(context, extra
|
|
) {
|
|
// Template name: \\"Child\\"
|
|
let utils = this.constructor.utils;
|
|
let scope = Object.create(context);
|
|
let h = this.h;
|
|
let _7 = {'c':true};
|
|
Object.assign(_7, utils.toObj(scope['state'].d?'d':''))
|
|
let c8 = [], p8 = {key:8,class:_7};
|
|
let vn8 = h('span', p8, c8);
|
|
return vn8;
|
|
}"
|
|
`;
|