Skip to content

Commit 6d862b0

Browse files
authored
Remove /deep/ usage (#2371)
* Remove /deep/ usage * Feedback * getElementsInDocumentFnString * Fix tests. Rename fun back to original
1 parent 57bcf43 commit 6d862b0

File tree

8 files changed

+107
-36
lines changed

8 files changed

+107
-36
lines changed

lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ <h2>Do better web tester page</h2>
289289
}
290290

291291
function noRelOpenLinksTest() {
292-
stampTemplate('noopener-links-tmpl', document.head);
292+
stampTemplate('noopener-links-tmpl', document.body);
293293
}
294294

295295
function passwordInputsCanBePastedIntoTest() {

lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,14 @@ module.exports = [
196196
score: 0,
197197
extendedInfo: {
198198
value: {
199-
0: {value: '6,025'},
199+
0: {value: '6,037'},
200200
1: {value: '9'},
201201
2: {value: '6,003'}
202202
}
203203
},
204204
details: {
205205
items: {
206-
0: {value: '6,025'},
206+
0: {value: '6,037'},
207207
1: {value: '9'},
208208
2: {value: '6,003'}
209209
}
@@ -218,14 +218,14 @@ module.exports = [
218218
score: 100,
219219
extendedInfo: {
220220
value: {
221-
0: {value: '25'},
221+
0: {value: '37'},
222222
1: {value: '9'},
223223
2: {value: '9'}
224224
}
225225
},
226226
details: {
227227
items: {
228-
0: {value: '25'},
228+
0: {value: '37'},
229229
1: {value: '9'},
230230
2: {value: '9'}
231231
}
@@ -240,14 +240,14 @@ module.exports = [
240240
score: 100,
241241
extendedInfo: {
242242
value: {
243-
0: {value: '24'},
243+
0: {value: '33'},
244244
1: {value: '7'},
245245
2: {value: '9'}
246246
}
247247
},
248248
details: {
249249
items: {
250-
0: {value: '24'},
250+
0: {value: '33'},
251251
1: {value: '7'},
252252
2: {value: '9'}
253253
}

lighthouse-core/gather/driver.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,20 @@ class Driver {
743743
});
744744
}
745745

746+
/**
747+
* Returns the flattened list of all DOM nodes within the document.
748+
* @param {boolean=} pierce Whether to pierce through shadow trees and iframes.
749+
* True by default.
750+
* @return {!Promise<!Array<!Element>>} The found elements, or [], resolved in a promise
751+
*/
752+
getElementsInDocument(pierce = true) {
753+
return this.sendCommand('DOM.getFlattenedDocument', {depth: -1, pierce})
754+
.then(result => {
755+
const elements = result.nodes.filter(node => node.nodeType === 1);
756+
return elements.map(node => new Element({nodeId: node.nodeId}, this));
757+
});
758+
}
759+
746760
/**
747761
* @param {{additionalTraceCategories: string=}=} flags
748762
*/

lighthouse-core/gather/gatherers/dobetterweb/all-event-listeners.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class EventListeners extends Gatherer {
117117
return Promise.resolve()
118118
.then(() => this.listenForScriptParsedEvents())
119119
.then(() => this.unlistenForScriptParsedEvents())
120-
.then(_ => options.driver.querySelectorAll('body, body /deep/ *')) // drill into shadow trees
120+
.then(_ => options.driver.getElementsInDocument())
121121
.then(nodes => {
122122
nodes.push('document', 'window');
123123
return this.collectListeners(nodes);

lighthouse-core/gather/gatherers/dobetterweb/anchors-with-no-rel-noopener.js

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,26 @@
66
'use strict';
77

88
const Gatherer = require('../gatherer');
9+
const DOMHelpers = require('../../../lib/dom-helpers.js');
910

1011
class AnchorsWithNoRelNoopener extends Gatherer {
1112
/**
1213
* @param {!Object} options
1314
* @return {!Promise<!Array<{href: string, rel: string, target: string}>>}
1415
*/
1516
afterPass(options) {
16-
const driver = options.driver;
17-
return driver.querySelectorAll('a[target="_blank"]:not([rel~="noopener"])')
18-
.then(failingNodeList => {
19-
const failingNodes = failingNodeList.map(node => {
20-
return Promise.all([
21-
node.getAttribute('href'),
22-
node.getAttribute('rel'),
23-
node.getAttribute('target')
24-
]);
25-
});
26-
return Promise.all(failingNodes);
27-
})
28-
.then(failingNodes => {
29-
return failingNodes.map(node => {
30-
return {
31-
href: node[0],
32-
rel: node[1],
33-
target: node[2]
34-
};
35-
});
36-
});
17+
const expression = `(function() {
18+
${DOMHelpers.getElementsInDocumentFnString}; // define function on page
19+
const selector = 'a[target="_blank"]:not([rel~="noopener"])';
20+
const elements = getElementsInDocument(selector);
21+
return elements.map(node => ({
22+
href: node.getAttribute('href'),
23+
rel: node.getAttribute('rel'),
24+
target: node.getAttribute('target')
25+
}));
26+
})()`;
27+
28+
return options.driver.evaluateAsync(expression);
3729
}
3830
}
3931

lighthouse-core/gather/gatherers/dobetterweb/domstats.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* and total number of nodes used on the page.
1010
*/
1111

12-
/* global document ShadowRoot */
12+
/* global ShadowRoot */
1313

1414
'use strict';
1515

@@ -115,7 +115,6 @@ function getDOMStats(element, deep=true) {
115115
const result = _calcDOMWidthAndHeight(element);
116116

117117
return {
118-
totalDOMNodes: document.querySelectorAll('html, html /deep/ *').length,
119118
depth: {
120119
max: result.maxDepth,
121120
pathToElement: elementPathInDOM(deepestNode),
@@ -138,7 +137,11 @@ class DOMStats extends Gatherer {
138137
${elementPathInDOM.toString()};
139138
return (${getDOMStats.toString()}(document.documentElement));
140139
})()`;
141-
return options.driver.evaluateAsync(expression);
140+
return options.driver.evaluateAsync(expression)
141+
.then(results => options.driver.getElementsInDocument().then(allNodes => {
142+
results.totalDOMNodes = allNodes.length;
143+
return results;
144+
}));
142145
}
143146
}
144147

lighthouse-core/gather/gatherers/image-usage.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
'use strict';
1212

1313
const Gatherer = require('./gatherer');
14+
const DOMHelpers = require('../../lib/dom-helpers.js');
1415

15-
/* global window, document, Image */
16+
/* global window, getElementsInDocument, Image */
1617

1718
/* istanbul ignore next */
1819
function collectImageElementInfo() {
@@ -27,7 +28,10 @@ function collectImageElementInfo() {
2728
};
2829
}
2930

30-
const htmlImages = [...document.querySelectorAll('img')].map(element => {
31+
const allElements = getElementsInDocument();
32+
const allImageElements = allElements.filter(element => element.localName === 'img');
33+
34+
const htmlImages = allImageElements.map(element => {
3135
return {
3236
// currentSrc used over src to get the url as determined by the browser
3337
// after taking into account srcset/media/sizes/etc.
@@ -47,7 +51,8 @@ function collectImageElementInfo() {
4751
const CSS_URL_REGEX = /^url\("([^"]+)"\)$/;
4852
// Only find images that aren't specifically scaled
4953
const CSS_SIZE_REGEX = /(auto|contain|cover)/;
50-
const cssImages = [...document.querySelectorAll('html /deep/ *')].reduce((images, element) => {
54+
55+
const cssImages = allElements.reduce((images, element) => {
5156
const style = window.getComputedStyle(element);
5257
if (!CSS_URL_REGEX.test(style.backgroundImage) ||
5358
!CSS_SIZE_REGEX.test(style.backgroundSize)) {
@@ -128,7 +133,12 @@ class ImageUsage extends Gatherer {
128133
return map;
129134
}, {});
130135

131-
return driver.evaluateAsync(`(${collectImageElementInfo.toString()})()`)
136+
const expression = `(function() {
137+
${DOMHelpers.getElementsInDocumentFnString}; // define function on page
138+
return (${collectImageElementInfo.toString()})();
139+
})()`;
140+
141+
return driver.evaluateAsync(expression)
132142
.then(elements => {
133143
return elements.reduce((promise, element) => {
134144
return promise.then(collector => {

lighthouse-core/lib/dom-helpers.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @license
3+
* Copyright 2017 Google Inc. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
'use strict';
18+
19+
/**
20+
* @fileoverview Helpers to be used with driver.evaluateAsync(). That is, these
21+
* methods are intended to be injected into and run in the context of the page.
22+
*/
23+
24+
/* global document */
25+
26+
/**
27+
* @param {string=} selector Optional simple CSS selector to filter nodes on.
28+
* Combinators are not supported.
29+
* @param {!Array<!Element>}
30+
*/
31+
function getElementsInDocument(selector) {
32+
const results = [];
33+
34+
const _findAllElements = nodes => {
35+
for (let i = 0, el; el = nodes[i]; ++i) {
36+
if (!selector || el.matches(selector)) {
37+
results.push(el);
38+
}
39+
// If the element has a shadow root, dig deeper.
40+
if (el.shadowRoot) {
41+
_findAllElements(el.shadowRoot.querySelectorAll('*'));
42+
}
43+
}
44+
};
45+
_findAllElements(document.querySelectorAll('*'));
46+
47+
return results;
48+
}
49+
50+
module.exports = {
51+
getElementsInDocumentFnString: getElementsInDocument.toString()
52+
};

0 commit comments

Comments
 (0)