Skip to content
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

Merged
merged 3 commits into from
Jan 7, 2019

Conversation

caridy
Copy link
Contributor

@caridy caridy commented Dec 21, 2018

Details

image

Does this PR introduce a breaking change?

  • No

@caridy caridy changed the title Caridy/ie devtool support fix(engine): to show shadow in IE11 devtool DOM explorer Dec 21, 2018
@caridy caridy requested a review from diervo December 21, 2018 02:45
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)';
Copy link
Contributor Author

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)) {
Copy link
Contributor Author

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

Copy link
Member

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, {
Copy link
Contributor Author

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.
Copy link
Contributor Author

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]: {
Copy link
Contributor Author

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, {
Copy link
Contributor Author

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, '');
Copy link
Member

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.

Copy link
Contributor Author

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 {
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any suggestion?

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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 ?

Copy link
Contributor

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

Copy link
Contributor

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 ?

Copy link
Contributor Author

@caridy caridy Jan 5, 2019

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?

Copy link
Contributor

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)) {
Copy link
Member

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?

@caridy
Copy link
Contributor Author

caridy commented Dec 21, 2018

@pmdartus

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.

@salesforce-best-lwc-internal
Copy link

Benchmark results

Base commit: 7c94042 | Target commit: 38e8eb7

Copy link
Contributor

@diervo diervo left a 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

@caridy caridy merged commit 6e2817f into master Jan 7, 2019
@caridy caridy deleted the caridy/ie-devtool-support branch January 7, 2019 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants