Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/audits2/lighthouse/renderer/dom.js

Issue 2856653002: Roll Lighthouse & add error reporting (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /** 1 /**
2 * Copyright 2017 Google Inc. All rights reserved. 2 * Copyright 2017 Google Inc. All rights reserved.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 * 7 *
8 * http://www.apache.org/licenses/LICENSE-2.0 8 * http://www.apache.org/licenses/LICENSE-2.0
9 * 9 *
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, 11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 'use strict'; 16 'use strict';
17 17
18 /* globals URL */ 18 /* globals URL self */
19 19
20 class DOM { 20 class DOM {
21 /** 21 /**
22 * @param {!Document} document 22 * @param {!Document} document
23 */ 23 */
24 constructor(document) { 24 constructor(document) {
25 /** @private {!Document} */
25 this._document = document; 26 this._document = document;
26 } 27 }
27 28
28 /** 29 /**
29 * @param {string} name 30 * @param {string} name
30 * @param {string=} className 31 * @param {string=} className
31 * @param {!Object<string, (string|undefined)>=} attrs Attribute key/val pairs . 32 * @param {!Object<string, (string|undefined)>=} attrs Attribute key/val pairs .
32 * Note: if an attribute key has an undefined value, this method does not 33 * Note: if an attribute key has an undefined value, this method does not
33 * set the attribute on the node. 34 * set the attribute on the node.
34 * @return {!Element} 35 * @return {!Element}
35 */ 36 */
36 createElement(name, className, attrs) { 37 createElement(name, className, attrs = {}) {
37 // TODO(all): adopt `attrs` default arg when https://codereview.chromium.org /2821773002/ lands
38 attrs = attrs || {};
39 const element = this._document.createElement(name); 38 const element = this._document.createElement(name);
40 if (className) { 39 if (className) {
41 element.className = className; 40 element.className = className;
42 } 41 }
43 Object.keys(attrs).forEach(key => { 42 Object.keys(attrs).forEach(key => {
44 const value = attrs[key]; 43 const value = attrs[key];
45 if (typeof value !== 'undefined') { 44 if (typeof value !== 'undefined') {
46 element.setAttribute(key, value); 45 element.setAttribute(key, value);
47 } 46 }
48 }); 47 });
49 return element; 48 return element;
50 } 49 }
51 50
52 /** 51 /**
53 * @param {string} selector 52 * @param {string} selector
54 * @param {!Document|!Element} context 53 * @param {!Node} context
55 * @return {!DocumentFragment} A clone of the template content. 54 * @return {!DocumentFragment} A clone of the template content.
56 * @throws {Error} 55 * @throws {Error}
57 */ 56 */
58 cloneTemplate(selector, context) { 57 cloneTemplate(selector, context) {
59 const template = context.querySelector(selector); 58 const template = /** @type {?HTMLTemplateElement} */ (context.querySelector( selector));
60 if (!template) { 59 if (!template) {
61 throw new Error(`Template not found: template${selector}`); 60 throw new Error(`Template not found: template${selector}`);
62 } 61 }
63 return /** @type {!DocumentFragment} */ (this._document.importNode(template. content, true)); 62
63 const clone = /** @type {!DocumentFragment} */ (
64 this._document.importNode(template.content, true));
65
66 // Prevent duplicate styles in the DOM. After a template has been stamped
67 // for the first time, remove the clone's styles so they're not re-added.
68 if (template.hasAttribute('data-stamped')) {
69 this.findAll('style', clone).forEach(style => style.remove());
70 }
71 template.setAttribute('data-stamped', true);
72
73 return clone;
64 } 74 }
65 75
66 /** 76 /**
77 * Resets the "stamped" state of the templates.
78 */
79 resetTemplates() {
80 this.findAll('template[data-stamped]', this._document).forEach(t => {
81 t.removeAttribute('data-stamped');
82 });
83 }
84
85 /**
67 * @param {string} text 86 * @param {string} text
68 * @return {!Element} 87 * @return {!Element}
69 */ 88 */
70 createSpanFromMarkdown(text) { 89 createSpanFromMarkdown(text) {
71 const element = this.createElement('span'); 90 const element = this.createElement('span');
72 91
73 // Split on markdown links (e.g. [some link](https://...)). 92 // Split on markdown links (e.g. [some link](https://...)).
74 const parts = text.split(/\[(.*?)\]\((https?:\/\/.*?)\)/g); 93 const parts = text.split(/\[(.*?)\]\((https?:\/\/.*?)\)/g);
75 94
76 while (parts.length) { 95 while (parts.length) {
77 // Pop off the same number of elements as there are capture groups. 96 // Pop off the same number of elements as there are capture groups.
78 const [preambleText, linkText, linkHref] = parts.splice(0, 3); 97 const [preambleText, linkText, linkHref] = parts.splice(0, 3);
79 element.appendChild(this._document.createTextNode(preambleText)); 98 element.appendChild(this._document.createTextNode(preambleText));
80 99
81 // Append link if there are any. 100 // Append link if there are any.
82 if (linkText && linkHref) { 101 if (linkText && linkHref) {
83 const a = this.createElement('a'); 102 const a = /** @type {!HTMLAnchorElement} */ (this.createElement('a'));
84 a.rel = 'noopener'; 103 a.rel = 'noopener';
85 a.target = '_blank'; 104 a.target = '_blank';
86 a.textContent = linkText; 105 a.textContent = linkText;
87 a.href = (new URL(linkHref)).href; 106 a.href = (new URL(linkHref)).href;
88 element.appendChild(a); 107 element.appendChild(a);
89 } 108 }
90 } 109 }
91 110
92 return element; 111 return element;
93 } 112 }
94 113
95 /** 114 /**
96 * @return {!Document} 115 * @return {!Document}
97 */ 116 */
98 document() { 117 document() {
99 return this._document; 118 return this._document;
100 } 119 }
120
121 /**
122 * Guaranteed context.querySelector. Always returns an element or throws if
123 * nothing matches query.
124 * @param {string} query
125 * @param {!Node} context
126 * @return {!Element}
127 */
128 find(query, context) {
129 const result = context.querySelector(query);
130 if (result === null) {
131 throw new Error(`query ${query} not found`);
132 }
133 return result;
134 }
135
136 /**
137 * Helper for context.querySelectorAll. Returns an Array instead of a NodeList .
138 * @param {string} query
139 * @param {!Node} context
140 * @return {!Array<!Element>}
141 */
142 findAll(query, context) {
143 return Array.from(context.querySelectorAll(query));
144 }
101 } 145 }
102 146
103 if (typeof module !== 'undefined' && module.exports) { 147 if (typeof module !== 'undefined' && module.exports) {
104 module.exports = DOM; 148 module.exports = DOM;
149 } else {
150 self.DOM = DOM;
105 } 151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698