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

Add pierce option to DOM.querySelector[All] #19

Closed
ebidel opened this issue May 24, 2017 · 7 comments
Closed

Add pierce option to DOM.querySelector[All] #19

ebidel opened this issue May 24, 2017 · 7 comments

Comments

@ebidel
Copy link
Contributor

ebidel commented May 24, 2017

The/deep/ combinator is being deprecated in the platform. Unfortunately, we use this in Lighthouse in a couple of places to find nodes within shadow roots. This gets injected into the page:

document.querySelector('html, html /deep/ *');

In Chrome 60, we'll have to move to DOM traversal [1] or use the protocol to get the full tree:

driver.sendCommand('DOM.getFlattenedDocument', {depth: -1, pierce: true}).then(result => {
  return result.nodes.filter(node => node.nodeType === 1); // element nodes.
});

However, this method is less convenient than qS() and only works against the root node. In some parts of the code, we still want to select nodes from the DOM using a complex CSS selector.

Ideally,DOM.querySelector/DOM.querySelectorAll could be updated to accept a {depth: -1, pierce: true} option....nodes within shadow trees would be returned.

Thoughts? Is there already a way to make this work?


[1]:

let allElements = [];
function findAllElements(nodes) {
  for (let i = 0, el; el = nodes[i]; ++i) {
    allElements.push(el);
    // If the element has a shadow root, dig deeper.
    if (el.shadowRoot) {
      findAllElements(el.shadowRoot.querySelectorAll('*'));
    }
  }
}
findAllElements(document.querySelectorAll('*'));
@pavelfeldman
Copy link
Contributor

@paulirish was asking me about this and it turned out that this was needed for image / raster resolution mismatch. I wonder if a more straightforward event upon image resize would suffice. Could you explain your use case in greater detail?

@ebidel
Copy link
Contributor Author

ebidel commented May 24, 2017

That might be https://github.com/GoogleChrome/lighthouse/blob/fb3cfbd533b113e2e37f38d7251491eb1aeba915/lighthouse-core/gather/gatherers/image-usage.js#L61?

Basically, we have a number of audits that collect nodes from the page and need to be aware of shadow trees. To date, we've done that using /deep/ (e.g. document.querySelector('html /deep/ img'); but they're removing that from shadow dom :\

So for example, I'm not sure how we use the protocol to do the equivalent of this:

driver.querySelectorAll('#somecontainer /deep/ a[target="_blank"]:not([rel~="noopener"])')`

Other examples (some we still need to make shadow dom aware) in the codebase:

dom size audit -
https://github.com/GoogleChrome/lighthouse/blob/d3a0692549d1a4791b7a402e3fb01dca632f505e/lighthouse-core/gather/gatherers/dobetterweb/domstats.js#L122

link-rel-opener audit -
https://github.com/GoogleChrome/lighthouse/blob/91ad83a37c25e213a6ef8e9166e86bdc6fc5dbdd/lighthouse-core/gather/gatherers/dobetterweb/anchors-with-no-rel-noopener.js#L28

all-event-listeners.js -
https://github.com/GoogleChrome/lighthouse/blob/d99778b4f1eb8d353ad54dc7830d286dfe30ba3e/lighthouse-core/gather/gatherers/dobetterweb/all-event-listeners.js#L131

links blocking first paint
https://github.com/GoogleChrome/lighthouse/blob/d99778b4f1eb8d353ad54dc7830d286dfe30ba3e/lighthouse-core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js#L41

@pavelfeldman
Copy link
Contributor

It is not practical to grow DOM domain to satisfy those, it is easier to inject snippets of JS that would do the job. It would involve piercing shadow, but that's straightforward. Since this patch you can create isolated worlds (content scripts), so your injected snippets won't be detected.

@paulirish
Copy link
Member

paulirish commented Jul 6, 2017

Just to note: this isolated worlds patch landed in 60.0.3097.0

@TakayoshiKochi
Copy link

FYI >>> (alternative to/deep/, only usable in querySelector(), was implemented under experimental
flag) is now considered for removal, due to lack from other vendor's interest.
Chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=829713
Spec discussion: w3c/csswg-drafts#640

@Georgegriff
Copy link

I put this together for use with a Selenium based Automation framework, performance might be all that but should work for my E2E testing use case: https://www.npmjs.com/package/query-selector-shadow-dom
Still need some work on writing test cases to check if my understanding of css selectors is correct

@TimvdLippe
Copy link
Contributor

This repository is related to Chrome DevTools Protocol, but does not track issues regarding its definition or implementation. If you want to file an issue for the Chrome DevTools Protocol, please open an issue on https://crbug.com under component: Platform>DevTools>Platform. Thanks in advance!

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

No branches or pull requests

6 participants