-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: upgrade typescript from 3.1.6 to 3.3.3 #1045
Conversation
src/3rdparty/polymer/outer-html.ts(43,46): error TS2345: Argument of type '(c: any) => "&" | "<" | ">" | """ | " " | undefined' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'. Type '"&" | "<" | ">" | """ | " " | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. src/3rdparty/polymer/outer-html.ts(47,46): error TS2345: Argument of type '(c: any) => "&" | "<" | ">" | """ | " " | undefined' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'.
src/faux-shadow/events.ts(62,11): error TS2322: Type 'Element | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/events.ts(119,23): error TS2322: Type 'Element | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/events.ts(213,37): error TS2345: Argument of type 'Element | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
src/faux-shadow/focus.ts(137,9): error TS2740: Type 'NodeListOf<Element>' is missing the following properties from type 'HTMLElement[]': pop, push, concat, join, and 24 more. src/faux-shadow/focus.ts(148,5): error TS2322: Type 'Element | null' is not assignable to type 'HTMLElement | null'. Type 'Element' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 109 more. src/faux-shadow/focus.ts(207,11): error TS2322: Type 'Element | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/focus.ts(219,11): error TS2322: Type 'EventTarget | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/focus.ts(248,11): error TS2322: Type 'Element | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/focus.ts(250,11): error TS2322: Type 'EventTarget | null' is not assignable to type 'EventTarget'. Type 'null' is not assignable to type 'EventTarget'. src/faux-shadow/focus.ts(313,33): error TS2345: Argument of type 'Element' is not assignable to parameter of type 'HTMLElement'.
src/faux-shadow/iframe.ts(10,47): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[any, string, (Transferable[] | undefined)?]'. Type 'IArguments' is missing the following properties from type '[any, string, (Transferable[] | undefined)?]': 0, 1, pop, push, and 26 more. src/faux-shadow/iframe.ts(13,40): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[]'. Type 'IArguments' is missing the following properties from type '[]': pop, push, concat, join, and 24 more. src/faux-shadow/iframe.ts(16,41): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[]'. src/faux-shadow/iframe.ts(19,41): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[]'.
src/faux-shadow/shadow-root.ts(70,5): error TS2740: Type 'DocumentFragment' is missing the following properties from type 'SyntheticShadowRootInterface': mode, delegatesFocus, host, innerHTML, and 7 more. src/faux-shadow/shadow-root.ts(120,17): error TS2322: Type 'Element | null' is not assignable to type 'Element'. Type 'null' is not assignable to type 'Element'.
src/faux-shadow/slot.ts(72,5): error TS2740: Type '{}' is missing the following properties from type 'Node[]': length, pop, push, concat, and 26 more. src/faux-shadow/slot.ts(81,5): error TS2322: Type '{}' is not assignable to type 'Node[]'.
src/faux-shadow/traverse.ts(296,5): error TS2740: Type '{}' is missing the following properties from type 'Element[]': length, pop, push, concat, and 26 more. src/faux-shadow/traverse.ts(333,5): error TS2322: Type 'typeof PatchedHTMLIframeElement' is not assignable to type 'HTMLIFrameElementConstructor'. Types of property 'prototype' are incompatible. Type 'PatchedHTMLIframeElement' is not assignable to type 'HTMLIFrameElement'. Types of property 'contentWindow' are incompatible. Type '{ postMessage(): void; blur(): void; close(): void; focus(): void; readonly closed: boolean; readonly frames: Window; readonly length: number; location: Location; readonly opener: any; readonly parent: Window; readonly self: Window; readonly top: Window; readonly window: Window; }' is not assignable to type 'Window'. src/faux-shadow/traverse.ts(334,13): error TS2416: Property 'contentWindow' in type 'PatchedHTMLIframeElement' is not assignable to the same property in base type 'HTMLIFrameElement'. Type '{ postMessage(): void; blur(): void; close(): void; focus(): void; readonly closed: boolean; readonly frames: Window; readonly length: number; location: Location; readonly opener: any; readonly parent: Window; readonly self: Window; readonly top: Window; readonly window: Window; }' is missing the following properties from type 'Window': Blob, URL, URLSearchParams, applicationCache, and 216 more.
src/framework/attributes.ts(193,83): error TS2345: Argument of type '"aria-"' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'.
src/framework/base-lightning-element.ts(226,37): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string, string]'. Type 'IArguments' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 26 more. src/framework/base-lightning-element.ts(232,51): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string]'. src/framework/base-lightning-element.ts(239,53): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string | null, string]'. src/framework/base-lightning-element.ts(341,7): error TS2322: Type '{}' is not assignable to type 'PropertyDescriptorMap'. Index signature is missing in type '{}'.
src/framework/restrictions.ts(190,61): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string, EventListener | EventListenerObject | null, (boolean | AddEventListenerOptions | undefined)?]'. Type 'IArguments' is missing the following properties from type '[string, EventListener | EventListenerObject | null, (boolean | AddEventListenerOptions | undefined)?]': 0, 1, pop, push, and 26 more. src/framework/restrictions.ts(197,58): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string]'. Type 'IArguments' is missing the following properties from type '[string]': 0, pop, push, concat, and 25 more. src/framework/restrictions.ts(204,61): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string]'. src/framework/restrictions.ts(348,61): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string, EventListenerOrEventListenerObject, (boolean | AddEventListenerOptions | undefined)?]'. Type 'IArguments' is missing the following properties from type '[string, EventListenerOrEventListenerObject, (boolean | AddEventListenerOptions | undefined)?]': 0, 1, pop, push, and 26 more. src/framework/restrictions.ts(400,50): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type '[string, any]'. Type 'IArguments' is missing the following properties from type '[string, any]': 0, 1, pop, push, and 26 more.
src/framework/def.ts(229,7): error TS2322: Type '{}' is not assignable to type 'PropsDef'. Index signature is missing in type '{}'.
src/faux-shadow/custom-element.ts(91,42): error TS2339: Property 'blur' does not exist on type 'Element'.
src/framework/services.ts(57,32): error TS2345: Argument of type 'ComponentInterface | undefined' is not assignable to parameter of type 'object'. Type 'undefined' is not assignable to type 'object'.
src/framework/stylesheet.ts(27,9): error TS2339: Property 'type' does not exist on type 'HTMLElement'. src/framework/stylesheet.ts(112,9): error TS2322: Type 'void' is not assignable to type 'VNode | null'. src/framework/stylesheet.ts(123,55): error TS2345: Argument of type '{}' is not assignable to parameter of type 'string'.
src/framework/template.ts(136,54): error TS2345: Argument of type 'ComponentInterface | undefined' is not assignable to parameter of type 'object'. Type 'undefined' is not assignable to type 'object'.
src/framework/vm.ts(66,26): error TS2345: Argument of type 'any[] | undefined' is not assignable to parameter of type 'any[]'. Type 'undefined' is not assignable to type 'any[]'. src/framework/vm.ts(498,5): error TS2322: Type 'Element | null' is not assignable to type 'HTMLElement | null'. Type 'Element' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 109 more. src/framework/vm.ts(513,37): error TS2345: Argument of type 'Element | null' is not assignable to parameter of type 'ShadowRoot | null'. Type 'Element' is missing the following properties from type 'ShadowRoot': host, mode, activeElement, styleSheets, and 6 more.
src/polyfills/aria-properties/polyfill.ts(69,86): error TS2345: Argument of type '"aria-"' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'.
src/polyfills/document-shadow/polyfill.ts(36,49): error TS2345: Argument of type 'Element | null' is not assignable to parameter of type 'Node'. Type 'null' is not assignable to type 'Node'. src/polyfills/document-shadow/polyfill.ts(39,17): error TS2531: Object is possibly 'null'.
src/shared/assert.ts(98,73): error TS2345: Argument of type '"\n"' is not assignable to parameter of type '{ [Symbol.split](string: string, limit?: number | undefined): string[]; }'.
Benchmark resultsBase commit: lwc-engine-benchmark
|
@@ -139,7 +139,7 @@ function getTabbableSegments(host: HTMLElement): QuerySegments { | |||
}; | |||
} | |||
|
|||
export function getActiveElement(host: HTMLElement): HTMLElement | null { | |||
export function getActiveElement(host: HTMLElement): Element | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did the return type change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The activeElement read-only property of the Document and ShadowRoot interfaces returns the Element within the DOM or shadow DOM tree that currently has focus.
yes, it could be an element.
const target: EventTarget = eventTargetGetter.call(event); | ||
// currentTarget should always be defined | ||
const host = eventCurrentTargetGetter.call(event) as EventTarget; | ||
const target = eventTargetGetter.call(event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we not need 'as EventTarget' here as well?
const target = eventTargetGetter.call(event) as EventTarget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the answer is that target and relatedTarget are always there... while currentTarget is not... it could be null, so I think this is correct because in this method, we are checking the event during the dispatch phase, which always have a currentTarget.
@@ -307,10 +310,14 @@ function stopFocusIn(evt) { | |||
|
|||
function handleFocusMouseDown(evt) { | |||
const target = eventTargetGetter.call(evt); | |||
if (isNull(target)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add a comment describing why the target would be null here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I don't have an explanation for this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what I did here either, it seems that asserting the type HTMLElement
is enough.
@@ -7,16 +7,20 @@ | |||
export function wrapIframeWindow(win: Window) { | |||
return { | |||
postMessage() { | |||
return win.postMessage.apply(win, arguments); | |||
const args = arguments as unknown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would casting to any not work?
const args = arguments as any[]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't easier to just ArraySlice arguments here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe change the signature method signature to:
{
postMessage(...args) {
return win.postMessage.apply(win, args);
},
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pmdartus I don't remember the transpiled code for (...args)
, but I remember it was some weird transformation that was pretty slow... maybe I'm getting confused with the default value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just trying to avoid the array conversion in general since this is not a problem in javascript. In terms of performance, the postMessage
method seems questionable but the other ones are probably safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the info, the rest parameter syntax is transformed an array copying using a standard for
loop. Based on the this benchmark, the slice is 40% faster than a pure array iteration.
@@ -67,7 +67,7 @@ export function attachShadow(elm: HTMLElement, options: ShadowRootInit): Synthet | |||
if (process.env.NODE_ENV === 'test') { | |||
elm['$$ShadowRoot$$'] = sr; // tslint:disable-line | |||
} | |||
return sr; | |||
return sr as SyntheticShadowRootInterface; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's interesting that the return type is not matching the type here. Is typescript expecting 'as' casting during the initial value assignment on line 53?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type is set to DocumentFragment
on line 53 but we're saying that the return type is SyntheticShadowRootInterface
.
return class PatchedHTMLIframeElement extends Ctor { | ||
// @ts-ignore type-mismatch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably log a work item to keep track of these @ts-ingores.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I don't think we can fix the type mismatch on PatchedHTMLIframeElement
. We can fix the one of contentWindow
.
The contentWindow
should wrap the current contentWindow
and return another object of type Window
. The wrapIframeWindow
needs its return type to be Window
.
const elm = getLinkedElement(this); | ||
if (process.env.NODE_ENV !== 'production') { | ||
assert.isFalse(isBeingConstructed(getComponentVM(this)), `Failed to construct '${getComponentAsString(this)}': The result must not have attributes.`); | ||
} | ||
unlockAttribute(elm, attrName); | ||
// Typescript does not like it when you treat the `arguments` object as an array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use the same workaround you had earlier
const args = arguments as unknown;
elm.setAttributeNS.apply(elm, args as any [])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think disabling the rule along with a comment is cleaner, but I'm also not opposed to array conversion. I was just worried about needless performance hits with the latter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no performance hit at runtime, types are only for the typescript compiler, those are not used at runtime. I personally prefer the type casting to any[]
, but I would defer the decision to @caridy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @ekashida is referencing to ArraySlice call for argument, which is going to be slower for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will leave this as-is unless anyone has further objections.
@@ -23,7 +23,7 @@ export type StylesheetFactory = (hostSelector: string, shadowSelector: string, n | |||
const CachedStyleFragments: Record<string, DocumentFragment> = create(null); | |||
|
|||
function createStyleElement(styleContent: string): Element { | |||
const elm = createElement.call(document, 'style'); | |||
const elm = createElement.call(document, 'style') as HTMLStyleElement; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
const vnodes: VNodes = html.call(undefined, api, component, cmpSlots, context.tplCache); | ||
|
||
const { styleVNode } = context; | ||
if (!isUndefined(context.styleVNode)) { | ||
if (styleVNode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be isNull(styleVNode)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you meant !isNull(styleVNode)
. What is the benefit of if (!isNull(styleVNode))
over if (styleVNode)
here? The type system already ensures that the only falsy value it can have is null
, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is a perf optimization
let node = DocumentPrototypeActiveElement.call(this); | ||
|
||
if (isNull(node)) { | ||
return node; | ||
} | ||
|
||
while (!isUndefined(getNodeOwnerKey(node))) { | ||
while (!isUndefined(getNodeOwnerKey(node as Node))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the 'as' casting be done during declaration on line 30?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be messy since parentElementGetter
returns an Element
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be messy since
parentElementGetter
returns anElement
.
@apapko What I meant by this is that node
is referenced in this function several times as an Element
(line 37 as well as the return value) and we would need to handle those. Does that make sense?
@@ -115,12 +116,13 @@ export function patchEvent(event: Event) { | |||
if (!isUndefined(originalRelatedTargetDescriptor)) { | |||
defineProperty(event, 'relatedTarget', { | |||
get(this: ComposableEvent): EventTarget | null | undefined { | |||
const eventContext = eventToContextMap.get(this); | |||
const originalCurrentTarget: EventTarget = eventCurrentTargetGetter.call(this); | |||
// currentTarget is always defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true... if you hold onto the event instance, and access relatedTarget in the next tick, what's the value of currentTarget?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, currentTarget
is null in this case.
@@ -209,7 +211,8 @@ function domListener(evt: Event) { | |||
let immediatePropagationStopped = false; | |||
let propagationStopped = false; | |||
const { type, stopImmediatePropagation, stopPropagation } = evt; | |||
const currentTarget = eventCurrentTargetGetter.call(evt); | |||
// currentTarget is always defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here on the other hand, it is always defined!
@@ -295,6 +297,7 @@ function willTriggerFocusInEvent(target: HTMLElement): boolean { | |||
} | |||
|
|||
function stopFocusIn(evt) { | |||
// currentTarget should always be defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, here this is true.
@@ -117,7 +117,7 @@ const ShadowRootDescriptors = { | |||
// activeElement must be child of the host and owned by it | |||
let node = activeElement; | |||
while (!isNodeOwnedBy(host, node)) { | |||
node = parentElementGetter.call(node); | |||
node = parentElementGetter.call(node) as HTMLElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no guarantee that parentElement exists, why forcing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If activeElement
is not null and is contained by the host (which is an HTMLElement
), then doesn't it mean that node
can never be null since we would stop bubbling up at the host?
@@ -193,46 +193,58 @@ BaseLightningElement.prototype = { | |||
const wrappedListener = getWrappedComponentsListener(vm, listener); | |||
vm.elm.removeEventListener(type, wrappedListener, options); | |||
}, | |||
setAttributeNS(ns: string, attrName: string, value: any) { | |||
setAttributeNS(ns: string | null, attrName: string, value: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this ns argument really be null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the definition in dom.d.ts: setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
@@ -53,6 +53,9 @@ export function invokeServiceHook(vm: VM, cbs: ServiceCallback[]) { | |||
assert.isTrue(isArray(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`); | |||
} | |||
const { component, data, def, context } = vm; | |||
if (isUndefined(component)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
component can't never be undefined at this point... this is a problem with few things of vm
that are defined as possible undefined because they need to be defined right after... but this affects the whole codebase where it complains about undefined values.
I was thinking about this, there are two possible solutions:
- having VM and UninitializedVM types... or something like that...
- using the trick in TS to define an empty obj to be fill out right after... but that might not solve the issue because some stuff are added to VM in the super call for LightningElement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of having 2 types with one for construction and another one for runtime.
@@ -133,10 +133,13 @@ export function evaluateTemplate(vm: VM, html: Template): Array<VNode|null> { | |||
// validating slots in every rendering since the allocated content might change over time | |||
validateSlots(vm, html); | |||
} | |||
|
|||
// TODO: Can `component` ever be undefined at this point? | |||
// @ts-ignore type-mismatch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
never... same explanation that above
@@ -451,8 +451,8 @@ function getErrorBoundaryVMFromOwnElement(vm: VM): VM | undefined { | |||
return getErrorBoundaryVM(elm); | |||
} | |||
|
|||
function getErrorBoundaryVM(startingElement: HTMLElement | null): VM | undefined { | |||
let elm: HTMLElement | null = startingElement; | |||
function getErrorBoundaryVM(startingElement: Element | null): VM | undefined { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we ever get a native element to throw something that is captured by the boundary, not sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it back but then does that mean that getParentOrHostElement
should always return HTMLElement
?
https://github.com/salesforce/lwc/pull/1045/files#diff-7ccfccbe4c1028889b761acec660f1afR443
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking very good, just minor stuff and few questions.
@@ -115,12 +116,13 @@ export function patchEvent(event: Event) { | |||
if (!isUndefined(originalRelatedTargetDescriptor)) { | |||
defineProperty(event, 'relatedTarget', { | |||
get(this: ComposableEvent): EventTarget | null | undefined { | |||
const eventContext = eventToContextMap.get(this); | |||
const originalCurrentTarget: EventTarget = eventCurrentTargetGetter.call(this); | |||
// currentTarget is always defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, currentTarget
is null in this case.
@@ -209,7 +211,8 @@ function domListener(evt: Event) { | |||
let immediatePropagationStopped = false; | |||
let propagationStopped = false; | |||
const { type, stopImmediatePropagation, stopPropagation } = evt; | |||
const currentTarget = eventCurrentTargetGetter.call(evt); | |||
// currentTarget is always defined | |||
const currentTarget = eventCurrentTargetGetter.call(evt) as HTMLElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not casting it to HTMLElement
instead of just EventTarget
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do that, but then we would have to change the signature of getEventMap
:
function getEventMap(elm: HTMLElement): ListenerMap {...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense, event handlers are associated with an EventTarget
.
const host: EventTarget = eventCurrentTargetGetter.call(event); | ||
const target: EventTarget = eventTargetGetter.call(event); | ||
// currentTarget should always be defined | ||
const host = eventCurrentTargetGetter.call(event) as EventTarget; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of as EventTarget
, you should add !
at the end to make it non-null:
const host = eventCurrentTargetGetter.call(event)!
It would avoid having to update the type you cast to if the method happened to change signature.
const target: EventTarget = eventTargetGetter.call(event); | ||
const relatedTarget: EventTarget = focusEventRelatedTargetGetter.call(event); | ||
// currentTarget should always be defined | ||
const host = eventCurrentTargetGetter.call(event) as EventTarget; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the !
instead of the explicit type cast.
@@ -7,16 +7,20 @@ | |||
export function wrapIframeWindow(win: Window) { | |||
return { | |||
postMessage() { | |||
return win.postMessage.apply(win, arguments); | |||
const args = arguments as unknown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe change the signature method signature to:
{
postMessage(...args) {
return win.postMessage.apply(win, args);
},
}
return class PatchedHTMLIframeElement extends Ctor { | ||
// @ts-ignore type-mismatch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I don't think we can fix the type mismatch on PatchedHTMLIframeElement
. We can fix the one of contentWindow
.
The contentWindow
should wrap the current contentWindow
and return another object of type Window
. The wrapIframeWindow
needs its return type to be Window
.
@@ -53,6 +53,9 @@ export function invokeServiceHook(vm: VM, cbs: ServiceCallback[]) { | |||
assert.isTrue(isArray(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`); | |||
} | |||
const { component, data, def, context } = vm; | |||
if (isUndefined(component)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of having 2 types with one for construction and another one for runtime.
Benchmark resultsBase commit: lwc-engine-benchmark
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm good with this, but a lot of test failures atm
Benchmark resultsBase commit: lwc-engine-benchmark
|
Things to note:
apply
invocation with thearguments
object is no longer valid (disabled the error instead of converting to array because this is a very common practice)Does this PR introduce a breaking change?