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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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 (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> 4 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
5 * Copyright (C) 2009 Joseph Pecoraro 5 * Copyright (C) 2009 Joseph Pecoraro
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 10 *
(...skipping 10 matching lines...) Expand all
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31
32 WebInspector.DOMPresentationUtils = {}; 31 WebInspector.DOMPresentationUtils = {};
33 32
34 /** 33 /**
35 * @param {!WebInspector.DOMNode} node 34 * @param {!WebInspector.DOMNode} node
36 * @param {!Element} parentElement 35 * @param {!Element} parentElement
37 */ 36 */
38 WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentEleme nt) 37 WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentEleme nt) {
39 { 38 var originalNode = node;
40 var originalNode = node; 39 var isPseudo = node.nodeType() === Node.ELEMENT_NODE && node.pseudoType();
41 var isPseudo = node.nodeType() === Node.ELEMENT_NODE && node.pseudoType(); 40 if (isPseudo && node.parentNode)
42 if (isPseudo && node.parentNode) 41 node = node.parentNode;
43 node = node.parentNode;
44 42
45 var title = node.nodeNameInCorrectCase(); 43 var title = node.nodeNameInCorrectCase();
46 44
47 var nameElement = parentElement.createChild("span", "node-label-name"); 45 var nameElement = parentElement.createChild('span', 'node-label-name');
48 nameElement.textContent = title; 46 nameElement.textContent = title;
49 47
50 var idAttribute = node.getAttribute("id"); 48 var idAttribute = node.getAttribute('id');
51 if (idAttribute) { 49 if (idAttribute) {
52 var idElement = parentElement.createChild("span", "node-label-id"); 50 var idElement = parentElement.createChild('span', 'node-label-id');
53 var part = "#" + idAttribute; 51 var part = '#' + idAttribute;
54 title += part; 52 title += part;
55 idElement.createTextChild(part); 53 idElement.createTextChild(part);
56 54
57 // Mark the name as extra, since the ID is more important. 55 // Mark the name as extra, since the ID is more important.
58 nameElement.classList.add("extra"); 56 nameElement.classList.add('extra');
57 }
58
59 var classAttribute = node.getAttribute('class');
60 if (classAttribute) {
61 var classes = classAttribute.split(/\s+/);
62 var foundClasses = {};
63
64 if (classes.length) {
65 var classesElement = parentElement.createChild('span', 'extra node-label-c lass');
66 for (var i = 0; i < classes.length; ++i) {
67 var className = classes[i];
68 if (className && !(className in foundClasses)) {
69 var part = '.' + className;
70 title += part;
71 classesElement.createTextChild(part);
72 foundClasses[className] = true;
73 }
74 }
59 } 75 }
76 }
60 77
61 var classAttribute = node.getAttribute("class"); 78 if (isPseudo) {
62 if (classAttribute) { 79 var pseudoElement = parentElement.createChild('span', 'extra node-label-pseu do');
63 var classes = classAttribute.split(/\s+/); 80 var pseudoText = '::' + originalNode.pseudoType();
64 var foundClasses = {}; 81 pseudoElement.createTextChild(pseudoText);
65 82 title += pseudoText;
66 if (classes.length) { 83 }
67 var classesElement = parentElement.createChild("span", "extra node-l abel-class"); 84 parentElement.title = title;
68 for (var i = 0; i < classes.length; ++i) {
69 var className = classes[i];
70 if (className && !(className in foundClasses)) {
71 var part = "." + className;
72 title += part;
73 classesElement.createTextChild(part);
74 foundClasses[className] = true;
75 }
76 }
77 }
78 }
79
80 if (isPseudo) {
81 var pseudoElement = parentElement.createChild("span", "extra node-label- pseudo");
82 var pseudoText = "::" + originalNode.pseudoType();
83 pseudoElement.createTextChild(pseudoText);
84 title += pseudoText;
85 }
86 parentElement.title = title;
87 }; 85 };
88 86
89 /** 87 /**
90 * @param {!Element} container 88 * @param {!Element} container
91 * @param {string} nodeTitle 89 * @param {string} nodeTitle
92 */ 90 */
93 WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle) 91 WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container, nodeTitle) {
94 { 92 var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
95 var match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/); 93 container.createChild('span', 'webkit-html-tag-name').textContent = match[1];
96 container.createChild("span", "webkit-html-tag-name").textContent = match[1] ; 94 if (match[2])
97 if (match[2]) 95 container.createChild('span', 'webkit-html-attribute-value').textContent = m atch[2];
98 container.createChild("span", "webkit-html-attribute-value").textContent = match[2]; 96 if (match[3])
99 if (match[3]) 97 container.createChild('span', 'webkit-html-attribute-name').textContent = ma tch[3];
100 container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
101 }; 98 };
102 99
103 /** 100 /**
104 * @param {?WebInspector.DOMNode} node 101 * @param {?WebInspector.DOMNode} node
105 * @param {string=} idref 102 * @param {string=} idref
106 * @return {!Node} 103 * @return {!Node}
107 */ 104 */
108 WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node, idref) 105 WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node, idref) {
109 { 106 if (!node)
110 if (!node) 107 return createTextNode(WebInspector.UIString('<node>'));
111 return createTextNode(WebInspector.UIString("<node>"));
112 108
113 var root = createElementWithClass("span", "monospace"); 109 var root = createElementWithClass('span', 'monospace');
114 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, "componen ts/domUtils.css"); 110 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, 'components /domUtils.css');
115 var link = shadowRoot.createChild("div", "node-link"); 111 var link = shadowRoot.createChild('div', 'node-link');
116 112
117 if (idref) 113 if (idref)
118 link.createChild("span", "node-label-id").createTextChild("#" + idref); 114 link.createChild('span', 'node-label-id').createTextChild('#' + idref);
119 else 115 else
120 WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link); 116 WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
121 117
122 link.addEventListener("click", WebInspector.Revealer.reveal.bind(WebInspecto r.Revealer, node, undefined), false); 118 link.addEventListener('click', WebInspector.Revealer.reveal.bind(WebInspector. Revealer, node, undefined), false);
123 link.addEventListener("mouseover", node.highlight.bind(node, undefined, unde fined), false); 119 link.addEventListener('mouseover', node.highlight.bind(node, undefined, undefi ned), false);
124 link.addEventListener("mouseleave", WebInspector.DOMModel.hideDOMNodeHighlig ht.bind(WebInspector.DOMModel), false); 120 link.addEventListener('mouseleave', WebInspector.DOMModel.hideDOMNodeHighlight .bind(WebInspector.DOMModel), false);
125 121
126 return root; 122 return root;
127 }; 123 };
128 124
129 /** 125 /**
130 * @param {!WebInspector.DeferredDOMNode} deferredNode 126 * @param {!WebInspector.DeferredDOMNode} deferredNode
131 * @return {!Node} 127 * @return {!Node}
132 */ 128 */
133 WebInspector.DOMPresentationUtils.linkifyDeferredNodeReference = function(deferr edNode) 129 WebInspector.DOMPresentationUtils.linkifyDeferredNodeReference = function(deferr edNode) {
134 { 130 var root = createElement('div');
135 var root = createElement("div"); 131 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, 'components /domUtils.css');
136 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(root, "componen ts/domUtils.css"); 132 var link = shadowRoot.createChild('div', 'node-link');
137 var link = shadowRoot.createChild("div", "node-link"); 133 link.createChild('content');
138 link.createChild("content"); 134 link.addEventListener('click', deferredNode.resolve.bind(deferredNode, onDefer redNodeResolved), false);
139 link.addEventListener("click", deferredNode.resolve.bind(deferredNode, onDef erredNodeResolved), false); 135 link.addEventListener('mousedown', (e) => e.consume(), false);
140 link.addEventListener("mousedown", (e) => e.consume(), false);
141 136
142 /** 137 /**
143 * @param {?WebInspector.DOMNode} node 138 * @param {?WebInspector.DOMNode} node
144 */ 139 */
145 function onDeferredNodeResolved(node) 140 function onDeferredNodeResolved(node) {
146 { 141 WebInspector.Revealer.reveal(node);
147 WebInspector.Revealer.reveal(node); 142 }
148 }
149 143
150 return root; 144 return root;
151 }; 145 };
152 146
153 /** 147 /**
154 * @param {!WebInspector.Target} target 148 * @param {!WebInspector.Target} target
155 * @param {string} originalImageURL 149 * @param {string} originalImageURL
156 * @param {boolean} showDimensions 150 * @param {boolean} showDimensions
157 * @param {function(!Element=)} userCallback 151 * @param {function(!Element=)} userCallback
158 * @param {!Object=} precomputedFeatures 152 * @param {!Object=} precomputedFeatures
159 */ 153 */
160 WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(target, o riginalImageURL, showDimensions, userCallback, precomputedFeatures) 154 WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(
161 { 155 target, originalImageURL, showDimensions, userCallback, precomputedFeatures) {
162 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target); 156 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target);
163 if (!resourceTreeModel) { 157 if (!resourceTreeModel) {
164 userCallback(); 158 userCallback();
165 return; 159 return;
166 } 160 }
167 var resource = resourceTreeModel.resourceForURL(originalImageURL); 161 var resource = resourceTreeModel.resourceForURL(originalImageURL);
168 var imageURL = originalImageURL; 162 var imageURL = originalImageURL;
169 if (!isImageResource(resource) && precomputedFeatures && precomputedFeatures .currentSrc) { 163 if (!isImageResource(resource) && precomputedFeatures && precomputedFeatures.c urrentSrc) {
170 imageURL = precomputedFeatures.currentSrc; 164 imageURL = precomputedFeatures.currentSrc;
171 resource = resourceTreeModel.resourceForURL(imageURL); 165 resource = resourceTreeModel.resourceForURL(imageURL);
172 } 166 }
173 if (!isImageResource(resource)) { 167 if (!isImageResource(resource)) {
174 userCallback(); 168 userCallback();
175 return; 169 return;
170 }
171
172 var imageElement = createElement('img');
173 imageElement.addEventListener('load', buildContent, false);
174 imageElement.addEventListener('error', errorCallback, false);
175 resource.populateImageSource(imageElement);
176
177 function errorCallback() {
178 // Drop the event parameter when invoking userCallback.
179 userCallback();
180 }
181
182 /**
183 * @param {?WebInspector.Resource} resource
184 * @return {boolean}
185 */
186 function isImageResource(resource) {
187 return !!resource && resource.resourceType() === WebInspector.resourceTypes. Image;
188 }
189
190 function buildContent() {
191 var container = createElement('table');
192 container.className = 'image-preview-container';
193 var naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidth : imageElement.naturalWidth;
194 var naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHeight : imageElement.naturalHeight;
195 var offsetWidth = precomputedFeatures ? precomputedFeatures.offsetWidth : na turalWidth;
196 var offsetHeight = precomputedFeatures ? precomputedFeatures.offsetHeight : naturalHeight;
197 var description;
198 if (showDimensions) {
199 if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
200 description = WebInspector.UIString('%d \xd7 %d pixels', offsetWidth, of fsetHeight);
201 else
202 description = WebInspector.UIString(
203 '%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)', offsetWidth, offse tHeight, naturalWidth, naturalHeight);
176 } 204 }
177 205
178 var imageElement = createElement("img"); 206 container.createChild('tr').createChild('td', 'image-container').appendChild (imageElement);
179 imageElement.addEventListener("load", buildContent, false); 207 if (description)
180 imageElement.addEventListener("error", errorCallback, false); 208 container.createChild('tr').createChild('td').createChild('span', 'descrip tion').textContent = description;
181 resource.populateImageSource(imageElement); 209 if (imageURL !== originalImageURL)
182 210 container.createChild('tr').createChild('td').createChild('span', 'descrip tion').textContent =
183 function errorCallback() 211 String.sprintf('currentSrc: %s', imageURL.trimMiddle(100));
184 { 212 userCallback(container);
185 // Drop the event parameter when invoking userCallback. 213 }
186 userCallback();
187 }
188
189 /**
190 * @param {?WebInspector.Resource} resource
191 * @return {boolean}
192 */
193 function isImageResource(resource)
194 {
195 return !!resource && resource.resourceType() === WebInspector.resourceTy pes.Image;
196 }
197
198 function buildContent()
199 {
200 var container = createElement("table");
201 container.className = "image-preview-container";
202 var naturalWidth = precomputedFeatures ? precomputedFeatures.naturalWidt h : imageElement.naturalWidth;
203 var naturalHeight = precomputedFeatures ? precomputedFeatures.naturalHei ght : imageElement.naturalHeight;
204 var offsetWidth = precomputedFeatures ? precomputedFeatures.offsetWidth : naturalWidth;
205 var offsetHeight = precomputedFeatures ? precomputedFeatures.offsetHeigh t : naturalHeight;
206 var description;
207 if (showDimensions) {
208 if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
209 description = WebInspector.UIString("%d \xd7 %d pixels", offsetW idth, offsetHeight);
210 else
211 description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
212 }
213
214 container.createChild("tr").createChild("td", "image-container").appendC hild(imageElement);
215 if (description)
216 container.createChild("tr").createChild("td").createChild("span", "d escription").textContent = description;
217 if (imageURL !== originalImageURL)
218 container.createChild("tr").createChild("td").createChild("span", "d escription").textContent = String.sprintf("currentSrc: %s", imageURL.trimMiddle( 100));
219 userCallback(container);
220 }
221 }; 214 };
222 215
223 /** 216 /**
224 * @param {!WebInspector.Target} target 217 * @param {!WebInspector.Target} target
225 * @param {!WebInspector.Linkifier} linkifier 218 * @param {!WebInspector.Linkifier} linkifier
226 * @param {!RuntimeAgent.StackTrace=} stackTrace 219 * @param {!RuntimeAgent.StackTrace=} stackTrace
227 * @return {!Element} 220 * @return {!Element}
228 */ 221 */
229 WebInspector.DOMPresentationUtils.buildStackTracePreviewContents = function(targ et, linkifier, stackTrace) 222 WebInspector.DOMPresentationUtils.buildStackTracePreviewContents = function(targ et, linkifier, stackTrace) {
230 { 223 var element = createElement('span');
231 var element = createElement("span"); 224 element.style.display = 'inline-block';
232 element.style.display = "inline-block"; 225 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(element, 'compone nts/domUtils.css');
233 var shadowRoot = WebInspector.createShadowRootWithCoreStyles(element, "compo nents/domUtils.css"); 226 var contentElement = shadowRoot.createChild('table', 'stack-preview-container' );
234 var contentElement = shadowRoot.createChild("table", "stack-preview-containe r");
235 227
236 /** 228 /**
237 * @param {!RuntimeAgent.StackTrace} stackTrace 229 * @param {!RuntimeAgent.StackTrace} stackTrace
238 */ 230 */
239 function appendStackTrace(stackTrace) 231 function appendStackTrace(stackTrace) {
240 { 232 for (var stackFrame of stackTrace.callFrames) {
241 for (var stackFrame of stackTrace.callFrames) { 233 var row = createElement('tr');
242 var row = createElement("tr"); 234 row.createChild('td').textContent = '\n';
243 row.createChild("td").textContent = "\n"; 235 row.createChild('td', 'function-name').textContent = WebInspector.beautify FunctionName(stackFrame.functionName);
244 row.createChild("td", "function-name").textContent = WebInspector.be autifyFunctionName(stackFrame.functionName); 236 var link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame);
245 var link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame ); 237 if (link) {
246 if (link) { 238 row.createChild('td').textContent = ' @ ';
247 row.createChild("td").textContent = " @ "; 239 row.createChild('td').appendChild(link);
248 row.createChild("td").appendChild(link); 240 }
249 } 241 contentElement.appendChild(row);
250 contentElement.appendChild(row);
251 }
252 } 242 }
243 }
253 244
254 if (!stackTrace) 245 if (!stackTrace)
255 return element; 246 return element;
256 247
257 appendStackTrace(stackTrace); 248 appendStackTrace(stackTrace);
258 249
259 var asyncStackTrace = stackTrace.parent; 250 var asyncStackTrace = stackTrace.parent;
260 while (asyncStackTrace) { 251 while (asyncStackTrace) {
261 if (!asyncStackTrace.callFrames.length) { 252 if (!asyncStackTrace.callFrames.length) {
262 asyncStackTrace = asyncStackTrace.parent; 253 asyncStackTrace = asyncStackTrace.parent;
263 continue; 254 continue;
264 }
265 var row = contentElement.createChild("tr");
266 row.createChild("td").textContent = "\n";
267 row.createChild("td", "stack-preview-async-description").textContent = W ebInspector.asyncStackTraceLabel(asyncStackTrace.description);
268 row.createChild("td");
269 row.createChild("td");
270 appendStackTrace(asyncStackTrace);
271 asyncStackTrace = asyncStackTrace.parent;
272 } 255 }
256 var row = contentElement.createChild('tr');
257 row.createChild('td').textContent = '\n';
258 row.createChild('td', 'stack-preview-async-description').textContent =
259 WebInspector.asyncStackTraceLabel(asyncStackTrace.description);
260 row.createChild('td');
261 row.createChild('td');
262 appendStackTrace(asyncStackTrace);
263 asyncStackTrace = asyncStackTrace.parent;
264 }
273 265
274 return element; 266 return element;
275 }; 267 };
276 268
277 /** 269 /**
278 * @param {!WebInspector.DOMNode} node 270 * @param {!WebInspector.DOMNode} node
279 * @param {boolean=} justSelector 271 * @param {boolean=} justSelector
280 * @return {string} 272 * @return {string}
281 */ 273 */
282 WebInspector.DOMPresentationUtils.fullQualifiedSelector = function(node, justSel ector) 274 WebInspector.DOMPresentationUtils.fullQualifiedSelector = function(node, justSel ector) {
283 { 275 if (node.nodeType() !== Node.ELEMENT_NODE)
284 if (node.nodeType() !== Node.ELEMENT_NODE) 276 return node.localName() || node.nodeName().toLowerCase();
285 return node.localName() || node.nodeName().toLowerCase(); 277 return WebInspector.DOMPresentationUtils.cssPath(node, justSelector);
286 return WebInspector.DOMPresentationUtils.cssPath(node, justSelector);
287 }; 278 };
288 279
289 /** 280 /**
290 * @param {!WebInspector.DOMNode} node 281 * @param {!WebInspector.DOMNode} node
291 * @return {string} 282 * @return {string}
292 */ 283 */
293 WebInspector.DOMPresentationUtils.simpleSelector = function(node) 284 WebInspector.DOMPresentationUtils.simpleSelector = function(node) {
294 { 285 var lowerCaseName = node.localName() || node.nodeName().toLowerCase();
295 var lowerCaseName = node.localName() || node.nodeName().toLowerCase(); 286 if (node.nodeType() !== Node.ELEMENT_NODE)
296 if (node.nodeType() !== Node.ELEMENT_NODE)
297 return lowerCaseName;
298 if (lowerCaseName === "input" && node.getAttribute("type") && !node.getAttri bute("id") && !node.getAttribute("class"))
299 return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
300 if (node.getAttribute("id"))
301 return lowerCaseName + "#" + node.getAttribute("id");
302 if (node.getAttribute("class"))
303 return (lowerCaseName === "div" ? "" : lowerCaseName) + "." + node.getAt tribute("class").trim().replace(/\s+/g, ".");
304 return lowerCaseName; 287 return lowerCaseName;
288 if (lowerCaseName === 'input' && node.getAttribute('type') && !node.getAttribu te('id') && !node.getAttribute('class'))
289 return lowerCaseName + '[type="' + node.getAttribute('type') + '"]';
290 if (node.getAttribute('id'))
291 return lowerCaseName + '#' + node.getAttribute('id');
292 if (node.getAttribute('class'))
293 return (lowerCaseName === 'div' ? '' : lowerCaseName) + '.' +
294 node.getAttribute('class').trim().replace(/\s+/g, '.');
295 return lowerCaseName;
305 }; 296 };
306 297
307 /** 298 /**
308 * @param {!WebInspector.DOMNode} node 299 * @param {!WebInspector.DOMNode} node
309 * @param {boolean=} optimized 300 * @param {boolean=} optimized
310 * @return {string} 301 * @return {string}
311 */ 302 */
312 WebInspector.DOMPresentationUtils.cssPath = function(node, optimized) 303 WebInspector.DOMPresentationUtils.cssPath = function(node, optimized) {
313 { 304 if (node.nodeType() !== Node.ELEMENT_NODE)
314 if (node.nodeType() !== Node.ELEMENT_NODE) 305 return '';
315 return "";
316 306
317 var steps = []; 307 var steps = [];
318 var contextNode = node; 308 var contextNode = node;
319 while (contextNode) { 309 while (contextNode) {
320 var step = WebInspector.DOMPresentationUtils._cssPathStep(contextNode, ! !optimized, contextNode === node); 310 var step = WebInspector.DOMPresentationUtils._cssPathStep(contextNode, !!opt imized, contextNode === node);
321 if (!step) 311 if (!step)
322 break; // Error - bail out early. 312 break; // Error - bail out early.
323 steps.push(step); 313 steps.push(step);
324 if (step.optimized) 314 if (step.optimized)
325 break; 315 break;
326 contextNode = contextNode.parentNode; 316 contextNode = contextNode.parentNode;
327 } 317 }
328 318
329 steps.reverse(); 319 steps.reverse();
330 return steps.join(" > "); 320 return steps.join(' > ');
331 }; 321 };
332 322
333 /** 323 /**
334 * @param {!WebInspector.DOMNode} node 324 * @param {!WebInspector.DOMNode} node
335 * @param {boolean} optimized 325 * @param {boolean} optimized
336 * @param {boolean} isTargetNode 326 * @param {boolean} isTargetNode
337 * @return {?WebInspector.DOMNodePathStep} 327 * @return {?WebInspector.DOMNodePathStep}
338 */ 328 */
339 WebInspector.DOMPresentationUtils._cssPathStep = function(node, optimized, isTar getNode) 329 WebInspector.DOMPresentationUtils._cssPathStep = function(node, optimized, isTar getNode) {
340 { 330 if (node.nodeType() !== Node.ELEMENT_NODE)
341 if (node.nodeType() !== Node.ELEMENT_NODE) 331 return null;
342 return null;
343 332
344 var id = node.getAttribute("id"); 333 var id = node.getAttribute('id');
345 if (optimized) { 334 if (optimized) {
346 if (id) 335 if (id)
347 return new WebInspector.DOMNodePathStep(idSelector(id), true); 336 return new WebInspector.DOMNodePathStep(idSelector(id), true);
348 var nodeNameLower = node.nodeName().toLowerCase(); 337 var nodeNameLower = node.nodeName().toLowerCase();
349 if (nodeNameLower === "body" || nodeNameLower === "head" || nodeNameLowe r === "html") 338 if (nodeNameLower === 'body' || nodeNameLower === 'head' || nodeNameLower == = 'html')
350 return new WebInspector.DOMNodePathStep(node.nodeNameInCorrectCase() , true); 339 return new WebInspector.DOMNodePathStep(node.nodeNameInCorrectCase(), true );
340 }
341 var nodeName = node.nodeNameInCorrectCase();
342
343 if (id)
344 return new WebInspector.DOMNodePathStep(nodeName + idSelector(id), true);
345 var parent = node.parentNode;
346 if (!parent || parent.nodeType() === Node.DOCUMENT_NODE)
347 return new WebInspector.DOMNodePathStep(nodeName, true);
348
349 /**
350 * @param {!WebInspector.DOMNode} node
351 * @return {!Array.<string>}
352 */
353 function prefixedElementClassNames(node) {
354 var classAttribute = node.getAttribute('class');
355 if (!classAttribute)
356 return [];
357
358 return classAttribute.split(/\s+/g).filter(Boolean).map(function(name) {
359 // The prefix is required to store "__proto__" in a object-based map.
360 return '$' + name;
361 });
362 }
363
364 /**
365 * @param {string} id
366 * @return {string}
367 */
368 function idSelector(id) {
369 return '#' + escapeIdentifierIfNeeded(id);
370 }
371
372 /**
373 * @param {string} ident
374 * @return {string}
375 */
376 function escapeIdentifierIfNeeded(ident) {
377 if (isCSSIdentifier(ident))
378 return ident;
379 var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);
380 var lastIndex = ident.length - 1;
381 return ident.replace(/./g, function(c, i) {
382 return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? escapeAsci iChar(c, i === lastIndex) : c;
383 });
384 }
385
386 /**
387 * @param {string} c
388 * @param {boolean} isLast
389 * @return {string}
390 */
391 function escapeAsciiChar(c, isLast) {
392 return '\\' + toHexByte(c) + (isLast ? '' : ' ');
393 }
394
395 /**
396 * @param {string} c
397 */
398 function toHexByte(c) {
399 var hexByte = c.charCodeAt(0).toString(16);
400 if (hexByte.length === 1)
401 hexByte = '0' + hexByte;
402 return hexByte;
403 }
404
405 /**
406 * @param {string} c
407 * @return {boolean}
408 */
409 function isCSSIdentChar(c) {
410 if (/[a-zA-Z0-9_-]/.test(c))
411 return true;
412 return c.charCodeAt(0) >= 0xA0;
413 }
414
415 /**
416 * @param {string} value
417 * @return {boolean}
418 */
419 function isCSSIdentifier(value) {
420 return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);
421 }
422
423 var prefixedOwnClassNamesArray = prefixedElementClassNames(node);
424 var needsClassNames = false;
425 var needsNthChild = false;
426 var ownIndex = -1;
427 var elementIndex = -1;
428 var siblings = parent.children();
429 for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++ i) {
430 var sibling = siblings[i];
431 if (sibling.nodeType() !== Node.ELEMENT_NODE)
432 continue;
433 elementIndex += 1;
434 if (sibling === node) {
435 ownIndex = elementIndex;
436 continue;
351 } 437 }
352 var nodeName = node.nodeNameInCorrectCase(); 438 if (needsNthChild)
439 continue;
440 if (sibling.nodeNameInCorrectCase() !== nodeName)
441 continue;
353 442
354 if (id) 443 needsClassNames = true;
355 return new WebInspector.DOMNodePathStep(nodeName + idSelector(id), true) ; 444 var ownClassNames = new Set(prefixedOwnClassNamesArray);
356 var parent = node.parentNode; 445 if (!ownClassNames.size) {
357 if (!parent || parent.nodeType() === Node.DOCUMENT_NODE) 446 needsNthChild = true;
358 return new WebInspector.DOMNodePathStep(nodeName, true); 447 continue;
448 }
449 var siblingClassNamesArray = prefixedElementClassNames(sibling);
450 for (var j = 0; j < siblingClassNamesArray.length; ++j) {
451 var siblingClass = siblingClassNamesArray[j];
452 if (!ownClassNames.has(siblingClass))
453 continue;
454 ownClassNames.delete(siblingClass);
455 if (!ownClassNames.size) {
456 needsNthChild = true;
457 break;
458 }
459 }
460 }
359 461
360 /** 462 var result = nodeName;
361 * @param {!WebInspector.DOMNode} node 463 if (isTargetNode && nodeName.toLowerCase() === 'input' && node.getAttribute('t ype') && !node.getAttribute('id') &&
362 * @return {!Array.<string>} 464 !node.getAttribute('class'))
363 */ 465 result += '[type="' + node.getAttribute('type') + '"]';
364 function prefixedElementClassNames(node) 466 if (needsNthChild) {
365 { 467 result += ':nth-child(' + (ownIndex + 1) + ')';
366 var classAttribute = node.getAttribute("class"); 468 } else if (needsClassNames) {
367 if (!classAttribute) 469 for (var prefixedName of prefixedOwnClassNamesArray)
368 return []; 470 result += '.' + escapeIdentifierIfNeeded(prefixedName.substr(1));
471 }
369 472
370 return classAttribute.split(/\s+/g).filter(Boolean).map(function(name) { 473 return new WebInspector.DOMNodePathStep(result, false);
371 // The prefix is required to store "__proto__" in a object-based map .
372 return "$" + name;
373 });
374 }
375
376 /**
377 * @param {string} id
378 * @return {string}
379 */
380 function idSelector(id)
381 {
382 return "#" + escapeIdentifierIfNeeded(id);
383 }
384
385 /**
386 * @param {string} ident
387 * @return {string}
388 */
389 function escapeIdentifierIfNeeded(ident)
390 {
391 if (isCSSIdentifier(ident))
392 return ident;
393 var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);
394 var lastIndex = ident.length - 1;
395 return ident.replace(/./g, function(c, i) {
396 return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? esca peAsciiChar(c, i === lastIndex) : c;
397 });
398 }
399
400 /**
401 * @param {string} c
402 * @param {boolean} isLast
403 * @return {string}
404 */
405 function escapeAsciiChar(c, isLast)
406 {
407 return "\\" + toHexByte(c) + (isLast ? "" : " ");
408 }
409
410 /**
411 * @param {string} c
412 */
413 function toHexByte(c)
414 {
415 var hexByte = c.charCodeAt(0).toString(16);
416 if (hexByte.length === 1)
417 hexByte = "0" + hexByte;
418 return hexByte;
419 }
420
421 /**
422 * @param {string} c
423 * @return {boolean}
424 */
425 function isCSSIdentChar(c)
426 {
427 if (/[a-zA-Z0-9_-]/.test(c))
428 return true;
429 return c.charCodeAt(0) >= 0xA0;
430 }
431
432 /**
433 * @param {string} value
434 * @return {boolean}
435 */
436 function isCSSIdentifier(value)
437 {
438 return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);
439 }
440
441 var prefixedOwnClassNamesArray = prefixedElementClassNames(node);
442 var needsClassNames = false;
443 var needsNthChild = false;
444 var ownIndex = -1;
445 var elementIndex = -1;
446 var siblings = parent.children();
447 for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {
448 var sibling = siblings[i];
449 if (sibling.nodeType() !== Node.ELEMENT_NODE)
450 continue;
451 elementIndex += 1;
452 if (sibling === node) {
453 ownIndex = elementIndex;
454 continue;
455 }
456 if (needsNthChild)
457 continue;
458 if (sibling.nodeNameInCorrectCase() !== nodeName)
459 continue;
460
461 needsClassNames = true;
462 var ownClassNames = new Set(prefixedOwnClassNamesArray);
463 if (!ownClassNames.size) {
464 needsNthChild = true;
465 continue;
466 }
467 var siblingClassNamesArray = prefixedElementClassNames(sibling);
468 for (var j = 0; j < siblingClassNamesArray.length; ++j) {
469 var siblingClass = siblingClassNamesArray[j];
470 if (!ownClassNames.has(siblingClass))
471 continue;
472 ownClassNames.delete(siblingClass);
473 if (!ownClassNames.size) {
474 needsNthChild = true;
475 break;
476 }
477 }
478 }
479
480 var result = nodeName;
481 if (isTargetNode && nodeName.toLowerCase() === "input" && node.getAttribute( "type") && !node.getAttribute("id") && !node.getAttribute("class"))
482 result += "[type=\"" + node.getAttribute("type") + "\"]";
483 if (needsNthChild) {
484 result += ":nth-child(" + (ownIndex + 1) + ")";
485 } else if (needsClassNames) {
486 for (var prefixedName of prefixedOwnClassNamesArray)
487 result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1));
488 }
489
490 return new WebInspector.DOMNodePathStep(result, false);
491 }; 474 };
492 475
493 /** 476 /**
494 * @param {!WebInspector.DOMNode} node 477 * @param {!WebInspector.DOMNode} node
495 * @param {boolean=} optimized 478 * @param {boolean=} optimized
496 * @return {string} 479 * @return {string}
497 */ 480 */
498 WebInspector.DOMPresentationUtils.xPath = function(node, optimized) 481 WebInspector.DOMPresentationUtils.xPath = function(node, optimized) {
499 { 482 if (node.nodeType() === Node.DOCUMENT_NODE)
500 if (node.nodeType() === Node.DOCUMENT_NODE) 483 return '/';
501 return "/";
502 484
503 var steps = []; 485 var steps = [];
504 var contextNode = node; 486 var contextNode = node;
505 while (contextNode) { 487 while (contextNode) {
506 var step = WebInspector.DOMPresentationUtils._xPathValue(contextNode, op timized); 488 var step = WebInspector.DOMPresentationUtils._xPathValue(contextNode, optimi zed);
507 if (!step) 489 if (!step)
508 break; // Error - bail out early. 490 break; // Error - bail out early.
509 steps.push(step); 491 steps.push(step);
510 if (step.optimized) 492 if (step.optimized)
511 break; 493 break;
512 contextNode = contextNode.parentNode; 494 contextNode = contextNode.parentNode;
513 } 495 }
514 496
515 steps.reverse(); 497 steps.reverse();
516 return (steps.length && steps[0].optimized ? "" : "/") + steps.join("/"); 498 return (steps.length && steps[0].optimized ? '' : '/') + steps.join('/');
517 }; 499 };
518 500
519 /** 501 /**
520 * @param {!WebInspector.DOMNode} node 502 * @param {!WebInspector.DOMNode} node
521 * @param {boolean=} optimized 503 * @param {boolean=} optimized
522 * @return {?WebInspector.DOMNodePathStep} 504 * @return {?WebInspector.DOMNodePathStep}
523 */ 505 */
524 WebInspector.DOMPresentationUtils._xPathValue = function(node, optimized) 506 WebInspector.DOMPresentationUtils._xPathValue = function(node, optimized) {
525 { 507 var ownValue;
526 var ownValue; 508 var ownIndex = WebInspector.DOMPresentationUtils._xPathIndex(node);
527 var ownIndex = WebInspector.DOMPresentationUtils._xPathIndex(node); 509 if (ownIndex === -1)
528 if (ownIndex === -1) 510 return null; // Error.
529 return null; // Error.
530 511
531 switch (node.nodeType()) { 512 switch (node.nodeType()) {
532 case Node.ELEMENT_NODE: 513 case Node.ELEMENT_NODE:
533 if (optimized && node.getAttribute("id")) 514 if (optimized && node.getAttribute('id'))
534 return new WebInspector.DOMNodePathStep("//*[@id=\"" + node.getAttri bute("id") + "\"]", true); 515 return new WebInspector.DOMNodePathStep('//*[@id="' + node.getAttribute( 'id') + '"]', true);
535 ownValue = node.localName(); 516 ownValue = node.localName();
536 break; 517 break;
537 case Node.ATTRIBUTE_NODE: 518 case Node.ATTRIBUTE_NODE:
538 ownValue = "@" + node.nodeName(); 519 ownValue = '@' + node.nodeName();
539 break; 520 break;
540 case Node.TEXT_NODE: 521 case Node.TEXT_NODE:
541 case Node.CDATA_SECTION_NODE: 522 case Node.CDATA_SECTION_NODE:
542 ownValue = "text()"; 523 ownValue = 'text()';
543 break; 524 break;
544 case Node.PROCESSING_INSTRUCTION_NODE: 525 case Node.PROCESSING_INSTRUCTION_NODE:
545 ownValue = "processing-instruction()"; 526 ownValue = 'processing-instruction()';
546 break; 527 break;
547 case Node.COMMENT_NODE: 528 case Node.COMMENT_NODE:
548 ownValue = "comment()"; 529 ownValue = 'comment()';
549 break; 530 break;
550 case Node.DOCUMENT_NODE: 531 case Node.DOCUMENT_NODE:
551 ownValue = ""; 532 ownValue = '';
552 break; 533 break;
553 default: 534 default:
554 ownValue = ""; 535 ownValue = '';
555 break; 536 break;
556 } 537 }
557 538
558 if (ownIndex > 0) 539 if (ownIndex > 0)
559 ownValue += "[" + ownIndex + "]"; 540 ownValue += '[' + ownIndex + ']';
560 541
561 return new WebInspector.DOMNodePathStep(ownValue, node.nodeType() === Node.D OCUMENT_NODE); 542 return new WebInspector.DOMNodePathStep(ownValue, node.nodeType() === Node.DOC UMENT_NODE);
562 }; 543 };
563 544
564 /** 545 /**
565 * @param {!WebInspector.DOMNode} node 546 * @param {!WebInspector.DOMNode} node
566 * @return {number} 547 * @return {number}
567 */ 548 */
568 WebInspector.DOMPresentationUtils._xPathIndex = function(node) 549 WebInspector.DOMPresentationUtils._xPathIndex = function(node) {
569 { 550 // Returns -1 in case of error, 0 if no siblings matching the same expression, <XPath index among the same expression-matching sibling nodes> otherwise.
570 // Returns -1 in case of error, 0 if no siblings matching the same expressio n, <XPath index among the same expression-matching sibling nodes> otherwise. 551 function areNodesSimilar(left, right) {
571 function areNodesSimilar(left, right) 552 if (left === right)
572 { 553 return true;
573 if (left === right)
574 return true;
575 554
576 if (left.nodeType() === Node.ELEMENT_NODE && right.nodeType() === Node.E LEMENT_NODE) 555 if (left.nodeType() === Node.ELEMENT_NODE && right.nodeType() === Node.ELEME NT_NODE)
577 return left.localName() === right.localName(); 556 return left.localName() === right.localName();
578 557
579 if (left.nodeType() === right.nodeType()) 558 if (left.nodeType() === right.nodeType())
580 return true; 559 return true;
581 560
582 // XPath treats CDATA as text nodes. 561 // XPath treats CDATA as text nodes.
583 var leftType = left.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_N ODE : left.nodeType(); 562 var leftType = left.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NODE : left.nodeType();
584 var rightType = right.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT _NODE : right.nodeType(); 563 var rightType = right.nodeType() === Node.CDATA_SECTION_NODE ? Node.TEXT_NOD E : right.nodeType();
585 return leftType === rightType; 564 return leftType === rightType;
565 }
566
567 var siblings = node.parentNode ? node.parentNode.children() : null;
568 if (!siblings)
569 return 0; // Root node - no siblings.
570 var hasSameNamedElements;
571 for (var i = 0; i < siblings.length; ++i) {
572 if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) {
573 hasSameNamedElements = true;
574 break;
586 } 575 }
587 576 }
588 var siblings = node.parentNode ? node.parentNode.children() : null; 577 if (!hasSameNamedElements)
589 if (!siblings) 578 return 0;
590 return 0; // Root node - no siblings. 579 var ownIndex = 1; // XPath indices start with 1.
591 var hasSameNamedElements; 580 for (var i = 0; i < siblings.length; ++i) {
592 for (var i = 0; i < siblings.length; ++i) { 581 if (areNodesSimilar(node, siblings[i])) {
593 if (areNodesSimilar(node, siblings[i]) && siblings[i] !== node) { 582 if (siblings[i] === node)
594 hasSameNamedElements = true; 583 return ownIndex;
595 break; 584 ++ownIndex;
596 }
597 } 585 }
598 if (!hasSameNamedElements) 586 }
599 return 0; 587 return -1; // An error occurred: |node| not found in parent's children.
600 var ownIndex = 1; // XPath indices start with 1.
601 for (var i = 0; i < siblings.length; ++i) {
602 if (areNodesSimilar(node, siblings[i])) {
603 if (siblings[i] === node)
604 return ownIndex;
605 ++ownIndex;
606 }
607 }
608 return -1; // An error occurred: |node| not found in parent's children.
609 }; 588 };
610 589
611 /** 590 /**
612 * @constructor 591 * @unrestricted
613 * @param {string} value
614 * @param {boolean} optimized
615 */ 592 */
616 WebInspector.DOMNodePathStep = function(value, optimized) 593 WebInspector.DOMNodePathStep = class {
617 { 594 /**
595 * @param {string} value
596 * @param {boolean} optimized
597 */
598 constructor(value, optimized) {
618 this.value = value; 599 this.value = value;
619 this.optimized = optimized || false; 600 this.optimized = optimized || false;
620 }; 601 }
621 602
622 WebInspector.DOMNodePathStep.prototype = { 603 /**
623 /** 604 * @override
624 * @override 605 * @return {string}
625 * @return {string} 606 */
626 */ 607 toString() {
627 toString: function() 608 return this.value;
628 { 609 }
629 return this.value;
630 }
631 }; 610 };
632 611
633 /** 612 /**
634 * @interface 613 * @interface
635 */ 614 */
636 WebInspector.DOMPresentationUtils.MarkerDecorator = function() 615 WebInspector.DOMPresentationUtils.MarkerDecorator = function() {};
637 {
638 };
639 616
640 WebInspector.DOMPresentationUtils.MarkerDecorator.prototype = { 617 WebInspector.DOMPresentationUtils.MarkerDecorator.prototype = {
641 /** 618 /**
642 * @param {!WebInspector.DOMNode} node 619 * @param {!WebInspector.DOMNode} node
643 * @return {?{title: string, color: string}} 620 * @return {?{title: string, color: string}}
644 */ 621 */
645 decorate: function(node) { } 622 decorate: function(node) {}
646 }; 623 };
647 624
648 /** 625 /**
649 * @constructor
650 * @implements {WebInspector.DOMPresentationUtils.MarkerDecorator} 626 * @implements {WebInspector.DOMPresentationUtils.MarkerDecorator}
651 * @param {!Runtime.Extension} extension 627 * @unrestricted
652 */ 628 */
653 WebInspector.DOMPresentationUtils.GenericDecorator = function(extension) 629 WebInspector.DOMPresentationUtils.GenericDecorator = class {
654 { 630 /**
631 * @param {!Runtime.Extension} extension
632 */
633 constructor(extension) {
655 this._title = WebInspector.UIString(extension.title()); 634 this._title = WebInspector.UIString(extension.title());
656 this._color = extension.descriptor()["color"]; 635 this._color = extension.descriptor()['color'];
636 }
637
638 /**
639 * @override
640 * @param {!WebInspector.DOMNode} node
641 * @return {?{title: string, color: string}}
642 */
643 decorate(node) {
644 return {title: this._title, color: this._color};
645 }
657 }; 646 };
658
659 WebInspector.DOMPresentationUtils.GenericDecorator.prototype = {
660 /**
661 * @override
662 * @param {!WebInspector.DOMNode} node
663 * @return {?{title: string, color: string}}
664 */
665 decorate: function(node)
666 {
667 return { title: this._title, color: this._color };
668 }
669 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698