[IMP] update owl to v1.2.5

This commit is contained in:
Géry Debongnie
2021-05-18 10:01:54 +02:00
parent ce11bbba0a
commit 23679373b4
+135 -111
View File
@@ -181,15 +181,15 @@
// Misc types, constants and helpers
//------------------------------------------------------------------------------
const RESERVED_WORDS = "true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,eval,void,Math,RegExp,Array,Object,Date".split(",");
const WORD_REPLACEMENT = {
const WORD_REPLACEMENT = Object.assign(Object.create(null), {
and: "&&",
or: "||",
gt: ">",
gte: ">=",
lt: "<",
lte: "<=",
};
const STATIC_TOKEN_MAP = {
});
const STATIC_TOKEN_MAP = Object.assign(Object.create(null), {
"{": "LEFT_BRACE",
"}": "RIGHT_BRACE",
"[": "LEFT_BRACKET",
@@ -198,7 +198,7 @@
",": "COMMA",
"(": "LEFT_PAREN",
")": "RIGHT_PAREN",
};
});
// note that the space after typeof is relevant. It makes sure that the formatted
// expression has a space after typeof
const OPERATORS = "...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;,in ".split(",");
@@ -2531,7 +2531,7 @@
code = ctx.captureExpression(value);
}
const modCode = mods.map((mod) => modcodes[mod]).join("");
let handler = `function (e) {if (!context.__owl__.isMounted){return}${modCode}${code}}`;
let handler = `function (e) {if (context.__owl__.status === ${5 /* DESTROYED */}){return}${modCode}${code}}`;
if (putInCache) {
const key = ctx.generateTemplateKey(event);
ctx.addLine(`extra.handlers[${key}] = extra.handlers[${key}] || ${handler};`);
@@ -3176,7 +3176,7 @@
// need to update component
let styleCode = "";
if (tattStyle) {
styleCode = `.then(()=>{if (w${componentID}.__owl__.isDestroyed) {return};w${componentID}.el.style=${tattStyle};});`;
styleCode = `.then(()=>{if (w${componentID}.__owl__.status === ${5 /* DESTROYED */}) {return};w${componentID}.el.style=${tattStyle};});`;
}
ctx.addLine(`w${componentID}.__updateProps(props${componentID}, extra.fiber, ${scope})${styleCode};`);
ctx.addLine(`let pvnode = w${componentID}.__owl__.pvnode;`);
@@ -3188,13 +3188,10 @@
}
ctx.addElse();
// new component
let dynamicFallback = "";
if (!value.match(INTERP_REGEXP)) {
dynamicFallback = `|| ${ctx.formatExpression(value)}`;
}
const contextualValue = value.match(INTERP_REGEXP) ? "false" : ctx.formatExpression(value);
const interpValue = ctx.interpolate(value);
ctx.addLine(`let componentKey${componentID} = ${interpValue};`);
ctx.addLine(`let W${componentID} = context.constructor.components[componentKey${componentID}] || QWeb.components[componentKey${componentID}]${dynamicFallback};`);
ctx.addLine(`let W${componentID} = ${contextualValue} || context.constructor.components[componentKey${componentID}] || QWeb.components[componentKey${componentID}];`);
// maybe only do this in dev mode...
ctx.addLine(`if (!W${componentID}) {throw new Error('Cannot find the definition of component "' + componentKey${componentID} + '"')}`);
ctx.addLine(`w${componentID} = new W${componentID}(parent, props${componentID});`);
@@ -3440,6 +3437,8 @@
*/
_reuseFiber(oldFiber) {
oldFiber.cancel(); // cancel children fibers
oldFiber.target = this.target || oldFiber.target;
oldFiber.position = this.position || oldFiber.position;
oldFiber.isCompleted = false; // keep the root fiber alive
oldFiber.isRendered = false; // the fiber has to be re-rendered
if (oldFiber.child) {
@@ -3519,7 +3518,8 @@
complete() {
let component = this.component;
this.isCompleted = true;
if (!this.target && !component.__owl__.isMounted) {
const status = component.__owl__.status;
if (status === 5 /* DESTROYED */) {
return;
}
// build patchQueue
@@ -3531,14 +3531,16 @@
this._walk(doWork);
const patchLen = patchQueue.length;
// call willPatch hook on each fiber of patchQueue
for (let i = 0; i < patchLen; i++) {
const fiber = patchQueue[i];
if (fiber.shouldPatch) {
component = fiber.component;
if (component.__owl__.willPatchCB) {
component.__owl__.willPatchCB();
if (status === 3 /* MOUNTED */) {
for (let i = 0; i < patchLen; i++) {
const fiber = patchQueue[i];
if (fiber.shouldPatch) {
component = fiber.component;
if (component.__owl__.willPatchCB) {
component.__owl__.willPatchCB();
}
component.willPatch();
}
component.willPatch();
}
}
// call __patch on each fiber of (reversed) patchQueue
@@ -3579,8 +3581,9 @@
component.__owl__.pvnode.elm = component.__owl__.vnode.elm;
}
}
if (fiber === component.__owl__.currentFiber) {
component.__owl__.currentFiber = null;
const compOwl = component.__owl__;
if (fiber === compOwl.currentFiber) {
compOwl.currentFiber = null;
}
}
// insert into the DOM (mount case)
@@ -3598,17 +3601,26 @@
this.component.env.qweb.trigger("dom-appended");
}
// call patched/mounted hook on each fiber of (reversed) patchQueue
for (let i = patchLen - 1; i >= 0; i--) {
const fiber = patchQueue[i];
component = fiber.component;
if (fiber.shouldPatch && !this.target) {
component.patched();
if (component.__owl__.patchedCB) {
component.__owl__.patchedCB();
if (status === 3 /* MOUNTED */ || inDOM) {
for (let i = patchLen - 1; i >= 0; i--) {
const fiber = patchQueue[i];
component = fiber.component;
if (fiber.shouldPatch && !this.target) {
component.patched();
if (component.__owl__.patchedCB) {
component.__owl__.patchedCB();
}
}
else {
component.__callMounted();
}
}
else if (this.target ? inDOM : true) {
component.__callMounted();
}
else {
for (let i = patchLen - 1; i >= 0; i--) {
const fiber = patchQueue[i];
component = fiber.component;
component.__owl__.status = 4 /* UNMOUNTED */;
}
}
}
@@ -3840,6 +3852,15 @@
document.head.appendChild(sheet);
}
var STATUS;
(function (STATUS) {
STATUS[STATUS["CREATED"] = 0] = "CREATED";
STATUS[STATUS["WILLSTARTED"] = 1] = "WILLSTARTED";
STATUS[STATUS["RENDERED"] = 2] = "RENDERED";
STATUS[STATUS["MOUNTED"] = 3] = "MOUNTED";
STATUS[STATUS["UNMOUNTED"] = 4] = "UNMOUNTED";
STATUS[STATUS["DESTROYED"] = 5] = "DESTROYED";
})(STATUS || (STATUS = {}));
const portalSymbol = Symbol("portal"); // FIXME
//------------------------------------------------------------------------------
// Component
@@ -3887,16 +3908,18 @@
this.env.browser = browser;
}
this.env.qweb.on("update", this, () => {
if (this.__owl__.isMounted) {
this.render(true);
}
if (this.__owl__.isDestroyed) {
// this is unlikely to happen, but if a root widget is destroyed,
// we want to remove our subscription. The usual way to do that
// would be to perform some check in the destroy method, but since
// it is very performance sensitive, and since this is a rare event,
// we simply do it lazily
this.env.qweb.off("update", this);
switch (this.__owl__.status) {
case 3 /* MOUNTED */:
this.render(true);
break;
case 5 /* DESTROYED */:
// this is unlikely to happen, but if a root widget is destroyed,
// we want to remove our subscription. The usual way to do that
// would be to perform some check in the destroy method, but since
// it is very performance sensitive, and since this is a rare event,
// we simply do it lazily
this.env.qweb.off("update", this);
break;
}
});
depth = 0;
@@ -3908,8 +3931,7 @@
depth: depth,
vnode: null,
pvnode: null,
isMounted: false,
isDestroyed: false,
status: 0 /* CREATED */,
parent: parent || null,
children: {},
cmap: {},
@@ -3931,6 +3953,7 @@
if (constr.style) {
this.__applyStyles(constr);
}
this.setup();
}
/**
* The `el` is the root element of the component. Note that it could be null:
@@ -3939,6 +3962,16 @@
get el() {
return this.__owl__.vnode ? this.__owl__.vnode.elm : null;
}
/**
* setup is run just after the component is constructed. This is the standard
* location where the component can setup its hooks. It has some advantages
* over the constructor:
* - it can be patched (useful in odoo ecosystem)
* - it does not need to propagate the arguments to the super call
*
* Note: this method should not be called manually.
*/
setup() { }
/**
* willStart is an asynchronous hook that can be implemented to perform some
* action before the initial rendering of a component.
@@ -4017,52 +4050,53 @@
* Note that a component can be mounted an unmounted several times
*/
async mount(target, options = {}) {
const position = options.position || "last-child";
const __owl__ = this.__owl__;
if (__owl__.isMounted) {
if (position !== "self" && this.el.parentNode !== target) {
// in this situation, we are trying to mount a component on a different
// target. In this case, we need to unmount first, otherwise it will
// not work.
this.unmount();
}
else {
return Promise.resolve();
}
}
if (__owl__.isDestroyed) {
throw new Error("Cannot mount a destroyed component");
}
if (__owl__.currentFiber) {
const currentFiber = __owl__.currentFiber;
if (currentFiber.target === target && currentFiber.position === position) {
return scheduler.addFiber(currentFiber);
}
else {
scheduler.rejectFiber(currentFiber, "Mounting operation cancelled");
}
}
if (!(target instanceof HTMLElement || target instanceof DocumentFragment)) {
let message = `Component '${this.constructor.name}' cannot be mounted: the target is not a valid DOM node.`;
message += `\nMaybe the DOM is not ready yet? (in that case, you can use owl.utils.whenReady)`;
throw new Error(message);
}
const fiber = new Fiber(null, this, true, target, position);
fiber.shouldPatch = false;
if (!__owl__.vnode) {
this.__prepareAndRender(fiber, () => { });
const position = options.position || "last-child";
const __owl__ = this.__owl__;
const currentFiber = __owl__.currentFiber;
switch (__owl__.status) {
case 0 /* CREATED */: {
const fiber = new Fiber(null, this, true, target, position);
fiber.shouldPatch = false;
this.__prepareAndRender(fiber, () => { });
return scheduler.addFiber(fiber);
}
case 1 /* WILLSTARTED */:
case 2 /* RENDERED */:
currentFiber.target = target;
currentFiber.position = position;
return scheduler.addFiber(currentFiber);
case 4 /* UNMOUNTED */: {
const fiber = new Fiber(null, this, true, target, position);
fiber.shouldPatch = false;
this.__render(fiber);
return scheduler.addFiber(fiber);
}
case 3 /* MOUNTED */: {
if (position !== "self" && this.el.parentNode !== target) {
const fiber = new Fiber(null, this, true, target, position);
fiber.shouldPatch = false;
this.__render(fiber);
return scheduler.addFiber(fiber);
}
else {
return Promise.resolve();
}
}
case 5 /* DESTROYED */:
throw new Error("Cannot mount a destroyed component");
}
else {
this.__render(fiber);
}
return scheduler.addFiber(fiber);
}
/**
* The unmount method is the opposite of the mount method. It is useful
* to call willUnmount calls and remove the component from the DOM.
*/
unmount() {
if (this.__owl__.isMounted) {
if (this.__owl__.status === 3 /* MOUNTED */) {
this.__callWillUnmount();
this.el.remove();
}
@@ -4079,10 +4113,7 @@
async render(force = false) {
const __owl__ = this.__owl__;
const currentFiber = __owl__.currentFiber;
if (!__owl__.isMounted && !currentFiber) {
// if we get here, this means that the component was either never mounted,
// or was unmounted and some state change triggered a render. Either way,
// we do not want to actually render anything in this case.
if (!__owl__.vnode && !currentFiber) {
return;
}
if (currentFiber && !currentFiber.isRendered && !currentFiber.isCompleted) {
@@ -4091,15 +4122,13 @@
// if we aren't mounted at this point, it implies that there is a
// currentFiber that is already rendered (isRendered is true), so we are
// about to be mounted
const isMounted = __owl__.isMounted;
const status = __owl__.status;
const fiber = new Fiber(null, this, force, null, null);
Promise.resolve().then(() => {
if (__owl__.isMounted || !isMounted) {
if (fiber.isCompleted) {
if (__owl__.status === 3 /* MOUNTED */ || status !== 3 /* MOUNTED */) {
if (fiber.isCompleted || fiber.isRendered) {
return;
}
// we are mounted (__owl__.isMounted), or if we are currently being
// mounted (!isMounted), so we call __render
this.__render(fiber);
}
else {
@@ -4123,7 +4152,7 @@
*/
destroy() {
const __owl__ = this.__owl__;
if (!__owl__.isDestroyed) {
if (__owl__.status !== 5 /* DESTROYED */) {
const el = this.el;
this.__destroy(__owl__.parent);
if (el) {
@@ -4164,13 +4193,12 @@
*/
__destroy(parent) {
const __owl__ = this.__owl__;
const isMounted = __owl__.isMounted;
if (isMounted) {
if (__owl__.status === 3 /* MOUNTED */) {
if (__owl__.willUnmountCB) {
__owl__.willUnmountCB();
}
this.willUnmount();
__owl__.isMounted = false;
__owl__.status = 4 /* UNMOUNTED */;
}
const children = __owl__.children;
for (let key in children) {
@@ -4181,7 +4209,7 @@
delete parent.__owl__.children[id];
__owl__.parent = null;
}
__owl__.isDestroyed = true;
__owl__.status = 5 /* DESTROYED */;
delete __owl__.vnode;
if (__owl__.currentFiber) {
__owl__.currentFiber.isCompleted = true;
@@ -4189,7 +4217,7 @@
}
__callMounted() {
const __owl__ = this.__owl__;
__owl__.isMounted = true;
__owl__.status = 3 /* MOUNTED */;
__owl__.currentFiber = null;
this.mounted();
if (__owl__.mountedCB) {
@@ -4202,7 +4230,7 @@
__owl__.willUnmountCB();
}
this.willUnmount();
__owl__.isMounted = false;
__owl__.status = 4 /* UNMOUNTED */;
if (__owl__.currentFiber) {
__owl__.currentFiber.isCompleted = true;
__owl__.currentFiber.root.counter = 0;
@@ -4210,7 +4238,7 @@
const children = __owl__.children;
for (let id in children) {
const comp = children[id];
if (comp.__owl__.isMounted) {
if (comp.__owl__.status === 3 /* MOUNTED */) {
comp.__callWillUnmount();
}
}
@@ -4330,17 +4358,23 @@
}
async __prepareAndRender(fiber, cb) {
try {
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
const proms = Promise.all([
this.willStart(),
this.__owl__.willStartCB && this.__owl__.willStartCB(),
]);
this.__owl__.status = 1 /* WILLSTARTED */;
await proms;
if (this.__owl__.status === 5 /* DESTROYED */) {
return Promise.resolve();
}
}
catch (e) {
fiber.handleError(e);
return Promise.resolve();
}
if (this.__owl__.isDestroyed) {
return Promise.resolve();
}
if (!fiber.isCompleted) {
this.__render(fiber);
this.__owl__.status = 2 /* RENDERED */;
cb();
}
}
@@ -4362,7 +4396,7 @@
for (let childKey in __owl__.children) {
const child = __owl__.children[childKey];
const childOwl = child.__owl__;
if (!childOwl.isMounted && childOwl.parentLastFiberId < fiber.id) {
if (childOwl.status !== 3 /* MOUNTED */ && childOwl.parentLastFiberId < fiber.id) {
// we only do here a "soft" destroy, meaning that we leave the child
// dom node alone, without removing it. Most of the time, it does not
// matter, because the child component is already unmounted. However,
@@ -4408,16 +4442,6 @@
fiber.handleError(error);
}
}
/**
* Only called by qweb t-component directive (when t-keepalive is set)
*/
__remount() {
const __owl__ = this.__owl__;
if (!__owl__.isMounted) {
__owl__.isMounted = true;
this.mounted();
}
}
/**
* Apply default props (only top level).
*
@@ -5364,9 +5388,9 @@
exports.utils = utils;
__info__.version = '1.2.1';
__info__.date = '2021-01-08T14:31:35.573Z';
__info__.hash = '25738a1';
__info__.version = '1.2.5';
__info__.date = '2021-05-18T08:01:47.651Z';
__info__.hash = '968a546';
__info__.url = 'https://github.com/odoo/owl';