diff --git a/src/component.ts b/src/component.ts index eb8f0f89..5087d5f2 100644 --- a/src/component.ts +++ b/src/component.ts @@ -235,24 +235,27 @@ export class Component< } _callMounted() { - const children = this.__owl__.children; + const __owl__ = this.__owl__; + const children = __owl__.children; for (let id in children) { const comp = children[id]; if (!comp.__owl__.isMounted && this.el!.contains(comp.el)) { comp._callMounted(); } } - this.__owl__.isMounted = true; - for (let key in this.__owl__.mountedHandlers) { - this.__owl__.mountedHandlers[key](); + __owl__.isMounted = true; + const handlers = __owl__.mountedHandlers; + for (let key in handlers) { + handlers[key](); } this.mounted(); } _callWillUnmount() { this.willUnmount(); - this.__owl__.isMounted = false; - const children = this.__owl__.children; + const __owl__ = this.__owl__; + __owl__.isMounted = false; + const children = __owl__.children; for (let id in children) { const comp = children[id]; if (comp.__owl__.isMounted) { @@ -269,7 +272,8 @@ export class Component< } async render(force: boolean = false, patchQueue?: any[]): Promise { - if (!this.__owl__.isMounted) { + const __owl__ = this.__owl__; + if (!__owl__.isMounted) { return; } const shouldPatch: boolean = !patchQueue; @@ -277,26 +281,23 @@ export class Component< patchQueue = []; } const renderVDom = this._render(force, patchQueue); - const renderId = this.__owl__.renderId; + const renderId = __owl__.renderId; await renderVDom; - if ( - shouldPatch && - this.__owl__.isMounted && - renderId === this.__owl__.renderId - ) { + if (shouldPatch && __owl__.isMounted && renderId === __owl__.renderId) { // we only update the vnode and the actual DOM if no other rendering // occurred between now and when the render method was initially called. - for (let i = 0; i < patchQueue!.length; i++) { + const patchLen = patchQueue!.length; + for (let i = 0; i < patchLen; i++) { const patch = patchQueue![i]; patch.push(patch[0].willPatch()); } - for (let i = 0; i < patchQueue!.length; i++) { + for (let i = 0; i < patchLen; i++) { const patch = patchQueue![i]; patch[0]._patch(patch[1]); } - for (let i = patchQueue!.length - 1; i >= 0; i--) { + for (let i = patchLen - 1; i >= 0; i--) { const patch = patchQueue![i]; patch[0].patched(patch[2]); } @@ -304,9 +305,10 @@ export class Component< } destroy() { - if (!this.__owl__.isDestroyed) { + const __owl__ = this.__owl__; + if (!__owl__.isDestroyed) { const el = this.el; - this._destroy(this.__owl__.parent); + this._destroy(__owl__.parent); if (el) { el.remove(); } @@ -314,23 +316,24 @@ export class Component< } _destroy(parent) { - const isMounted = this.__owl__.isMounted; + const __owl__ = this.__owl__; + const isMounted = __owl__.isMounted; if (isMounted) { this.willUnmount(); - this.__owl__.isMounted = false; + __owl__.isMounted = false; } - const children = Object.values(this.__owl__.children); - for (let child of children) { - child._destroy(this); + const children = __owl__.children; + for (let key in children) { + children[key]._destroy(this); } if (parent) { - let id = this.__owl__.id; + let id = __owl__.id; delete parent.__owl__.children[id]; - this.__owl__.parent = null; + __owl__.parent = null; } this.clear(); - this.__owl__.isDestroyed = true; - delete this.__owl__.vnode; + __owl__.isDestroyed = true; + delete __owl__.vnode; } shouldUpdate(nextProps: Props): boolean { @@ -347,11 +350,12 @@ export class Component< * mode or not. */ async updateEnv(nextEnv: Partial): Promise { - if (this.__owl__.parent && this.__owl__.parent.env === this.env) { + const __owl__ = this.__owl__; + if (__owl__.parent && __owl__.parent.env === this.env) { this.env = Object.create(this.env); } Object.assign(this.env, nextEnv); - if (this.__owl__.isMounted) { + if (__owl__.isMounted) { await this.render(true); } } @@ -385,19 +389,22 @@ export class Component< } _patch(vnode) { - this.__owl__.renderPromise = null; - const target = this.__owl__.vnode || document.createElement(vnode.sel!); - this.__owl__.vnode = patch(target, vnode); + const __owl__ = this.__owl__; + __owl__.renderPromise = null; + const target = __owl__.vnode || document.createElement(vnode.sel!); + __owl__.vnode = patch(target, vnode); } _prepare(): Promise { - this.__owl__.renderProps = this.props; - this.__owl__.renderPromise = this._prepareAndRender(); - return this.__owl__.renderPromise; + const __owl__ = this.__owl__; + __owl__.renderProps = this.props; + __owl__.renderPromise = this._prepareAndRender(); + return __owl__.renderPromise; } async _prepareAndRender(): Promise { await this.willStart(); - if (this.__owl__.isDestroyed) { + const __owl__ = this.__owl__; + if (__owl__.isDestroyed) { return Promise.resolve(h("div")); } const qweb = this.env.qweb; @@ -428,7 +435,7 @@ export class Component< } } } - this.__owl__.render = qweb.render.bind(qweb, this.template); + __owl__.render = qweb.render.bind(qweb, this.template); this._observeState(); return this._render(); } @@ -436,25 +443,26 @@ export class Component< force: boolean = false, patchQueue: any[] = [] ): Promise { - this.__owl__.renderId++; + const __owl__ = this.__owl__; + __owl__.renderId++; const promises: Promise[] = []; const patch: any[] = [this]; - if (this.__owl__.isMounted) { + if (__owl__.isMounted) { patchQueue.push(patch); } - if (this.__owl__.observer) { - this.__owl__.observer.allowMutations = false; + if (__owl__.observer) { + __owl__.observer.allowMutations = false; } - let vnode = this.__owl__.render!(this, { + let vnode = __owl__.render!(this, { promises, - handlers: this.__owl__.boundHandlers, - mountedHandlers: this.__owl__.mountedHandlers, + handlers: __owl__.boundHandlers, + mountedHandlers: __owl__.mountedHandlers, forceUpdate: force, patchQueue }); patch.push(vnode); - if (this.__owl__.observer) { - this.__owl__.observer.allowMutations = true; + if (__owl__.observer) { + __owl__.observer.allowMutations = true; } // this part is critical for the patching process to be done correctly. The @@ -462,38 +470,41 @@ export class Component< // will update its own vnode representation without the knowledge of the // parent widget. With this, we make sure that the parent widget will be // able to patch itself properly after - vnode.key = this.__owl__.id; - this.__owl__.renderProps = this.props; - this.__owl__.renderPromise = Promise.all(promises).then(() => vnode); - return this.__owl__.renderPromise; + vnode.key = __owl__.id; + __owl__.renderProps = this.props; + __owl__.renderPromise = Promise.all(promises).then(() => vnode); + return __owl__.renderPromise; } /** * Only called by qweb t-widget directive */ _mount(vnode: VNode, elm: HTMLElement): VNode { - this.__owl__.vnode = patch(elm, vnode); - if (this.__owl__.parent!.__owl__.isMounted && !this.__owl__.isMounted) { + const __owl__ = this.__owl__; + __owl__.vnode = patch(elm, vnode); + if (__owl__.parent!.__owl__.isMounted && !__owl__.isMounted) { this._callMounted(); } - return this.__owl__.vnode; + return __owl__.vnode; } /** * Only called by qweb t-widget directive (when t-keepalive is set) */ _remount() { - if (!this.__owl__.isMounted) { - this.__owl__.isMounted = true; + const __owl__ = this.__owl__; + if (!__owl__.isMounted) { + __owl__.isMounted = true; this.mounted(); } } _observeState() { if (this.state) { - this.__owl__.observer = new Observer(); - this.__owl__.observer.observe(this.state); - this.__owl__.observer.notifyCB = this.render.bind(this); + const __owl__ = this.__owl__; + __owl__.observer = new Observer(); + __owl__.observer.observe(this.state); + __owl__.observer.notifyCB = this.render.bind(this); } } @@ -577,7 +588,7 @@ function isValidProp(prop, propDef): boolean { // If this code is executed, this means that we want to check if a prop // matches at least one of its descriptor. let result = false; - for (let i = 0; i < propDef.length; i++) { + for (let i = 0, iLen = propDef.length; i < iLen; i++) { result = result || isValidProp(prop, propDef[i]); } return result; @@ -585,13 +596,14 @@ function isValidProp(prop, propDef): boolean { // propsDef is an object let result = isValidProp(prop, propDef.type); if (propDef.type === Array) { - for (let i = 0; i < prop.length; i++) { + for (let i = 0, iLen = prop.length; i < iLen; i++) { result = result && isValidProp(prop[i], propDef.element); } } if (propDef.type === Object) { - for (let key in propDef.shape) { - result = result && isValidProp(prop[key], propDef.shape[key]); + const shape = propDef.shape; + for (let key in shape) { + result = result && isValidProp(prop[key], shape[key]); } } return result; diff --git a/src/event_bus.ts b/src/event_bus.ts index 720b9337..3a909a88 100644 --- a/src/event_bus.ts +++ b/src/event_bus.ts @@ -64,7 +64,8 @@ export class EventBus { */ trigger(eventType: string, ...args: any[]) { const subs = this.subscriptions[eventType] || []; - for (let sub of subs) { + for (let i = 0, iLen = subs.length; i < iLen; i++) { + const sub = subs[i]; sub.callback.call(sub.owner, ...args); } } diff --git a/src/observer.ts b/src/observer.ts index f39c865e..016adfeb 100644 --- a/src/observer.ts +++ b/src/observer.ts @@ -30,10 +30,13 @@ const methodsToPatch = [ "sort", "reverse" ]; +const methodLen = methodsToPatch.length; + const ArrayProto = Array.prototype; const ModifiedArrayProto = Object.create(ArrayProto); -for (let method of methodsToPatch) { +for (let i = 0; i < methodLen; i++) { + const method = methodsToPatch[i]; const initialMethod = ArrayProto[method]; ModifiedArrayProto[method] = function(...args) { if (!this.__observer__.allowMutations) { @@ -57,8 +60,8 @@ for (let method of methodsToPatch) { break; } if (inserted) { - for (let elem of inserted) { - this.__observer__.observe(elem, this); + for (let i = 0, iLen = inserted.length; i < iLen; i++) { + this.__observer__.observe(inserted[i], this); } } return initialMethod.call(this, ...args); @@ -112,10 +115,9 @@ export class Observer { } _observeObj(obj: T, parent?: any) { - const keys = Object.keys(obj); obj.__owl__ = { rev: this.rev, deepRev: this.rev, parent }; Object.defineProperty(obj, "__owl__", { enumerable: false }); - for (let key of keys) { + for (let key in obj) { this._addProp(obj, key, obj[key]); } } @@ -125,7 +127,7 @@ export class Observer { Object.defineProperty(arr, "__owl__", { enumerable: false }); (arr).__proto__ = Object.create(ModifiedArrayProto); (arr).__proto__.__observer__ = this; - for (let i = 0; i < arr.length; i++) { + for (let i = 0, iLen = arr.length; i < iLen; i++) { this.observe(arr[i], arr); } } diff --git a/src/qweb_core.ts b/src/qweb_core.ts index 5040101b..46b2a48f 100644 --- a/src/qweb_core.ts +++ b/src/qweb_core.ts @@ -100,9 +100,9 @@ interface Utils { h: typeof h; objectToAttrString(obj: Object): string; [key: string]: any; -}; +} -export const UTILS:Utils = { +export const UTILS: Utils = { h: h, objectToAttrString(obj: Object): string { let classes: string[] = []; @@ -361,17 +361,20 @@ export class QWeb { } } - for (let directive of DIRECTIVES) { + const DIR_N = DIRECTIVES.length; + const ATTR_N = attributes.length; + for (let i = 0; i < DIR_N; i++) { + let directive = DIRECTIVES[i]; let fullName; let value; - for (let i = 0; i < attributes.length; i++) { - const name = attributes[i].name; + for (let j = 0; j < ATTR_N; j++) { + const name = attributes[j].name; if ( name === "t-" + directive.name || name.startsWith("t-" + directive.name + "-") ) { fullName = name; - value = attributes[i].textContent; + value = attributes[j].textContent; validDirectives.push({ directive, value, fullName }); if (directive.name === "on") { withHandlers = true; @@ -721,8 +724,8 @@ export class Context { let invarPos = 0; let r = ""; chars.push(" "); - for (var i = 0, ilen = chars.length; i < ilen; i++) { - var c = chars[i]; + for (let i = 0, ilen = chars.length; i < ilen; i++) { + let c = chars[i]; if (instring.length) { if (c === instring && chars[i - 1] !== "\\") { instring = ""; diff --git a/src/qweb_directives.ts b/src/qweb_directives.ts index 19518273..c215c338 100644 --- a/src/qweb_directives.ts +++ b/src/qweb_directives.ts @@ -250,14 +250,15 @@ QWeb.addDirective({ ctx.addLine( `var _${keysID} = _${arrayID} instanceof Array ? _${arrayID} : Object.keys(_${arrayID});` ); + ctx.addLine(`var _length${keysID} = _${keysID}.length;`); let valuesID = ctx.generateID(); ctx.addLine( `var _${valuesID} = _${arrayID} instanceof Array ? _${arrayID} : Object.values(_${arrayID});` ); - ctx.addLine(`for (let i = 0; i < _${keysID}.length; i++) {`); + ctx.addLine(`for (let i = 0; i < _length${keysID}; i++) {`); ctx.indent(); ctx.addLine(`context.${name}_first = i === 0;`); - ctx.addLine(`context.${name}_last = i === _${keysID}.length - 1;`); + ctx.addLine(`context.${name}_last = i === _length${keysID} - 1;`); ctx.addLine(`context.${name}_parity = i % 2 === 0 ? 'even' : 'odd';`); ctx.addLine(`context.${name}_index = i;`); ctx.addLine(`context.${name} = _${keysID}[i];`); diff --git a/src/vdom.ts b/src/vdom.ts index a00ca645..1fa5c65e 100644 --- a/src/vdom.ts +++ b/src/vdom.ts @@ -15,12 +15,15 @@ * - patch function (to apply a vnode to an actual DOM node) */ - // because those in TypeScript are too restrictive: https://github.com/Microsoft/TSJS-lib-generator/pull/237 declare global { interface Element { setAttribute(name: string, value: string | number | boolean): void; - setAttributeNS(namespaceURI: string, qualifiedName: string, value: string | number | boolean): void; + setAttributeNS( + namespaceURI: string, + qualifiedName: string, + value: string | number | boolean + ): void; } } @@ -162,6 +165,7 @@ export function init(modules: Array>, domApi?: DOMAPI) { function createElm(vnode: VNode, insertedVnodeQueue: VNodeQueue): Node { let i: any, + iLen: number, data = vnode.data; if (data !== undefined) { if (isDef((i = data.hook)) && isDef((i = i.init))) { @@ -193,9 +197,10 @@ export function init(modules: Array>, domApi?: DOMAPI) { if (hash < dot) elm.setAttribute("id", sel.slice(hash + 1, dot)); if (dotIdx > 0) elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " ")); - for (i = 0; i < cbs.create.length; ++i) cbs.create[i](emptyNode, vnode); + for (i = 0, iLen = cbs.create.length; i < iLen; ++i) + cbs.create[i](emptyNode, vnode); if (array(children)) { - for (i = 0; i < children.length; ++i) { + for (i = 0, iLen = children.length; i < iLen; ++i) { const ch = children[i]; if (ch != null) { api.appendChild(elm, createElm(ch as VNode, insertedVnodeQueue)); @@ -233,13 +238,16 @@ export function init(modules: Array>, domApi?: DOMAPI) { function invokeDestroyHook(vnode: VNode) { let i: any, + iLen: number, j: number, + jLen: number, data = vnode.data; if (data !== undefined) { if (isDef((i = data.hook)) && isDef((i = i.destroy))) i(vnode); - for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode); + for (i = 0, iLen = cbs.destroy.length; i < iLen; ++i) + cbs.destroy[i](vnode); if (vnode.children !== undefined) { - for (j = 0; j < vnode.children.length; ++j) { + for (j = 0, jLen = vnode.children.length; j < jLen; ++j) { i = vnode.children[j]; if (i != null && typeof i !== "string") { invokeDestroyHook(i); @@ -257,6 +265,7 @@ export function init(modules: Array>, domApi?: DOMAPI) { ): void { for (; startIdx <= endIdx; ++startIdx) { let i: any, + iLen: number, listeners: number, rm: () => void, ch = vnodes[startIdx]; @@ -265,7 +274,8 @@ export function init(modules: Array>, domApi?: DOMAPI) { invokeDestroyHook(ch); listeners = cbs.remove.length + 1; rm = createRmCb(ch.elm as Node, listeners); - for (i = 0; i < cbs.remove.length; ++i) cbs.remove[i](ch, rm); + for (i = 0, iLen = cbs.remove.length; i < iLen; ++i) + cbs.remove[i](ch, rm); if ( isDef((i = ch.data)) && isDef((i = i.hook)) && @@ -395,7 +405,7 @@ export function init(modules: Array>, domApi?: DOMAPI) { vnode: VNode, insertedVnodeQueue: VNodeQueue ) { - let i: any, hook: any; + let i: any, iLen: number, hook: any; if ( isDef((i = vnode.data)) && isDef((hook = i.hook)) && @@ -408,7 +418,8 @@ export function init(modules: Array>, domApi?: DOMAPI) { let ch = vnode.children; if (oldVnode === vnode) return; if (vnode.data !== undefined) { - for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode); + for (i = 0, iLen = cbs.update.length; i < iLen; ++i) + cbs.update[i](oldVnode, vnode); i = vnode.data.hook; if (isDef(i) && isDef((i = i.update))) i(oldVnode, vnode); } @@ -458,9 +469,9 @@ export function init(modules: Array>, domApi?: DOMAPI) { } return function patch(oldVnode: VNode | Element, vnode: VNode): VNode { - let i: number, elm: Node, parent: Node; + let i: number, iLen: number, elm: Node, parent: Node; const insertedVnodeQueue: VNodeQueue = []; - for (i = 0; i < cbs.pre.length; ++i) cbs.pre[i](); + for (i = 0, iLen = cbs.pre.length; i < iLen; ++i) cbs.pre[i](); if (!isVnode(oldVnode)) { oldVnode = emptyNodeAt(oldVnode); @@ -480,12 +491,12 @@ export function init(modules: Array>, domApi?: DOMAPI) { } } - for (i = 0; i < insertedVnodeQueue.length; ++i) { + for (i = 0, iLen = insertedVnodeQueue.length; i < iLen; ++i) { (((insertedVnodeQueue[i].data as VNodeData).hook as Hooks).insert as any)( insertedVnodeQueue[i] ); } - for (i = 0; i < cbs.post.length; ++i) cbs.post[i](); + for (i = 0, iLen = cbs.post.length; i < iLen; ++i) cbs.post[i](); return vnode; }; } @@ -647,7 +658,7 @@ function addNS( ): void { data.ns = "http://www.w3.org/2000/svg"; if (sel !== "foreignObject" && children !== undefined) { - for (let i = 0; i < children.length; ++i) { + for (let i = 0, iLen = children.length; i < iLen; ++i) { let childData = children[i].data; if (childData !== undefined) { addNS( @@ -668,7 +679,8 @@ export function h(sel: any, b?: any, c?: any): VNode { var data: VNodeData = {}, children: any, text: any, - i: number; + i: number, + iLen: number; if (c !== undefined) { data = b; if (array(c)) { @@ -690,7 +702,7 @@ export function h(sel: any, b?: any, c?: any): VNode { } } if (children !== undefined) { - for (i = 0; i < children.length; ++i) { + for (i = 0, iLen = children.length; i < iLen; ++i) { if (primitive(children[i])) children[i] = vnode( undefined, @@ -788,7 +800,7 @@ function invokeHandler(handler: any, vnode?: VNode, event?: Event): void { } } else { // call multiple handlers - for (var i = 0; i < handler.length; i++) { + for (let i = 0, iLen = handler.length; i < iLen; i++) { invokeHandler(handler[i], vnode, event); } } diff --git a/tests/__snapshots__/component.test.ts.snap b/tests/__snapshots__/component.test.ts.snap index 9c3437da..eb541ce7 100644 --- a/tests/__snapshots__/component.test.ts.snap +++ b/tests/__snapshots__/component.test.ts.snap @@ -90,10 +90,11 @@ exports[`composition sub widgets with some state rendered in a loop 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.number_first = i === 0; - context.number_last = i === _3.length - 1; + context.number_last = i === _length3 - 1; context.number_parity = i % 2 === 0 ? 'even' : 'odd'; context.number_index = i; context.number = _3[i]; diff --git a/tests/__snapshots__/qweb.test.ts.snap b/tests/__snapshots__/qweb.test.ts.snap index 7d3f398d..8a562c6b 100644 --- a/tests/__snapshots__/qweb.test.ts.snap +++ b/tests/__snapshots__/qweb.test.ts.snap @@ -308,10 +308,11 @@ exports[`foreach does not pollute the rendering context 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -336,10 +337,11 @@ exports[`foreach iterate on items (on a element node) 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -367,10 +369,11 @@ exports[`foreach iterate on items 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -407,10 +410,11 @@ exports[`foreach iterate, dict param 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -452,10 +456,11 @@ exports[`foreach iterate, integer param 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -492,10 +497,11 @@ exports[`foreach iterate, position 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.elem_first = i === 0; - context.elem_last = i === _3.length - 1; + context.elem_last = i === _length3 - 1; context.elem_parity = i % 2 === 0 ? 'even' : 'odd'; context.elem_index = i; context.elem = _3[i]; @@ -529,10 +535,11 @@ exports[`foreach warn if no key in some case 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -589,10 +596,11 @@ exports[`misc global 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.value_first = i === 0; - context.value_last = i === _3.length - 1; + context.value_last = i === _length3 - 1; context.value_parity = i % 2 === 0 ? 'even' : 'odd'; context.value_index = i; context.value = _3[i]; @@ -1098,10 +1106,11 @@ exports[`t-key t-key directive in a list 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.beer_first = i === 0; - context.beer_last = i === _3.length - 1; + context.beer_last = i === _length3 - 1; context.beer_parity = i % 2 === 0 ? 'even' : 'odd'; context.beer_index = i; context.beer = _3[i]; @@ -1197,10 +1206,11 @@ exports[`t-on can bind handlers with loop variable as argument 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.action_first = i === 0; - context.action_last = i === _3.length - 1; + context.action_last = i === _length3 - 1; context.action_parity = i % 2 === 0 ? 'even' : 'odd'; context.action_index = i; context.action = _3[i]; @@ -1524,10 +1534,11 @@ exports[`t-ref refs in a loop 1`] = ` if (!_2) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _2 === 'number') { _2 = Array.from(Array(_2).keys())} var _3 = _2 instanceof Array ? _2 : Object.keys(_2); + var _length3 = _3.length; var _4 = _2 instanceof Array ? _2 : Object.values(_2); - for (let i = 0; i < _3.length; i++) { + for (let i = 0; i < _length3; i++) { context.item_first = i === 0; - context.item_last = i === _3.length - 1; + context.item_last = i === _length3 - 1; context.item_parity = i % 2 === 0 ? 'even' : 'odd'; context.item_index = i; context.item = _3[i]; @@ -1682,10 +1693,11 @@ exports[`t-set t-set should reuse variable if possible 1`] = ` if (!_3) { throw new Error('QWeb error: Invalid loop expression')} if (typeof _3 === 'number') { _3 = Array.from(Array(_3).keys())} var _4 = _3 instanceof Array ? _3 : Object.keys(_3); + var _length4 = _4.length; var _5 = _3 instanceof Array ? _3 : Object.values(_3); - for (let i = 0; i < _4.length; i++) { + for (let i = 0; i < _length4; i++) { context.elem_first = i === 0; - context.elem_last = i === _4.length - 1; + context.elem_last = i === _length4 - 1; context.elem_parity = i % 2 === 0 ? 'even' : 'odd'; context.elem_index = i; context.elem = _4[i];