-
Notifications
You must be signed in to change notification settings - Fork 402
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
fix(engine): to show shadow in IE11 devtool DOM explorer #904
Conversation
import { getActiveElement, handleFocusIn, handleFocus, ignoreFocusIn, ignoreFocus } from "./focus"; | ||
import { HTMLElementConstructor } from "../framework/base-bridge-element"; | ||
import { createStaticNodeList } from "../shared/static-node-list"; | ||
import { createStaticHTMLCollection } from "../shared/static-html-collection"; | ||
|
||
const hasNativeSymbolsSupport = Symbol('x').toString() === 'Symbol(x)'; |
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 how we detect IE11, it doesn't have symbol
@@ -96,6 +98,12 @@ export function PatchedCustomElement(Base: HTMLElement): HTMLElementConstructor | |||
get childNodes(this: HTMLElement): NodeListOf<Node & Element> { | |||
const owner = getNodeOwner(this); | |||
const childNodes = isNull(owner) ? [] : getAllMatches(owner, getFilteredChildNodes(this)); | |||
if (process.env.NODE_ENV !== 'production' && isFalse(hasNativeSymbolsSupport)) { |
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 only runs in non-prod, and it doesn't affect snapshots in jest because that does have symbol
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.
Did you test this in older versions of Chrome, Safari, and Firefox to see how it looks like in the devtool?
} | ||
// @ts-ignore $$placeholder$$ is fine, read the node above. | ||
c = shadowRoot.$$placeholder$$ = createComment.call(document, ''); | ||
defineProperties(c, { |
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 trick, you create a comment, and set tagName and childNodes, and IE11 will get very confused, it will display it as a tag with children etc.
@@ -10,7 +10,7 @@ import { defineProperty, create, isUndefined } from "./language"; | |||
* In IE11, symbols are expensive. | |||
* Due to the nature of the symbol polyfill. This method abstract the | |||
* creation of symbols, so we can fallback to string when native symbols | |||
* are not supported. Note that we can't use typeof since it will fail when tranpiling. | |||
* are not supported. Note that we can't use typeof since it will fail when transpiling. |
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.
just a typo
@@ -122,11 +122,8 @@ StaticHTMLCollection.prototype = create(HTMLCollection.prototype, { | |||
setPrototypeOf(StaticHTMLCollection, HTMLCollection); | |||
|
|||
export function createStaticHTMLCollection<T extends Element>(items: T[]): HTMLCollectionOf<T> { | |||
const collection: HTMLCollectionOf<T> = create(StaticHTMLCollection.prototype, { | |||
[Items]: { |
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 issue here, I don't know how is that it didn't popped before, but this will breaking the inspection of childNodes because Object.create() polyfill is not honoring the symbols, probably because of the symbol polyfill.
@@ -94,11 +94,8 @@ StaticNodeList.prototype = create(NodeList.prototype, { | |||
setPrototypeOf(StaticNodeList, NodeList); | |||
|
|||
export function createStaticNodeList<T extends Node>(items: T[]): NodeListOf<T> { | |||
const nodeList: NodeListOf<T> = create(StaticNodeList.prototype, { |
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.
same as above.
return c; | ||
} | ||
// @ts-ignore $$placeholder$$ is fine, read the node above. | ||
c = shadowRoot.$$placeholder$$ = createComment.call(document, ''); |
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 add value to the comment (#shadow-root
). I would expect older versions of Chrome and Safari would display the comment properly so it would be nice to have some content in 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.
yeah, I can work on that... I was hoping to display the open or closed as well, but that is proven to be more tricky.
* and a comment node that is intended to use to trick the IE11 DevTools | ||
* to show the content of the shadowRoot in the DOM Explorer. | ||
*/ | ||
export function getIE11FakeShadowRootPlaceholder(host: HTMLElement): Comment { |
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 name this function something else, since it would run in all the browsers that don't support Symbol
.
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.
any suggestion?
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.
What about fakeShadowRootPlaceholder
without the IE11
?
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.
Well, the problem is that no other devTool that I know of will really show that placeholder.
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.
in that case would it make sense to do a user agent check along with the lack of symbol support check so that we're only doing this in IE11 ?
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 already do some very trivial symbol check, but is not based on user agent, is feature detection. I will love to stay away of user agent detection as much as possible
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.
okay, so is there an alternative feature detection we can do instead of symbol check since this captures other browsers besides IE11 ?
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.
@tariq-sfdc what other browser besides IE11 in our browser matrix will produce a false negative on symbol?
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 not sure. I only asked because Pierre's comment suggested that there was a supported browser that didn't support symbols and wouldn't show the placeholder.
Looks like in terms of supported browsers, IE11 is the only real browser that doesn't support symbols
@@ -96,6 +98,12 @@ export function PatchedCustomElement(Base: HTMLElement): HTMLElementConstructor | |||
get childNodes(this: HTMLElement): NodeListOf<Node & Element> { | |||
const owner = getNodeOwner(this); | |||
const childNodes = isNull(owner) ? [] : getAllMatches(owner, getFilteredChildNodes(this)); | |||
if (process.env.NODE_ENV !== 'production' && isFalse(hasNativeSymbolsSupport)) { |
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.
Did you test this in older versions of Chrome, Safari, and Firefox to see how it looks like in the devtool?
yes, I did test this in chrome, safari and firefox running compat, and it doesn't affect them because none of those devtools are really relying on the JS obj the represent the dom to show the stuff in the console, instead, they rely on the internal representation, which we don't control. |
Benchmark resultsBase commit: |
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 love that we are feature detecting IE11 based on symbols, but I much rather prefer do that since we know it works, than some user agent check
Details
Does this PR introduce a breaking change?