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

Side by Side Diff: Source/devtools/front_end/DOMPresentationUtils.js

Issue 75253002: DevTools: [Elements] Implement "Copy CSS Path" context menu item for elements (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Move CSS path-building code from DOMAgent to DOMPresentationUtils, reuse in DOMNode.appropriateSeleā€¦ Created 7 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 | Annotate | Revision Log
« no previous file with comments | « Source/devtools/front_end/DOMAgent.js ('k') | Source/devtools/front_end/ElementsTreeOutline.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
aandrey 2013/11/20 16:20:49 should we also move XPath to this file (maybe in a
apavlov 2013/11/21 07:31:35 XPath building deals equally much with DOM and pre
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 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 else 151 else
152 description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight); 152 description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
153 } 153 }
154 154
155 container.createChild("tr").createChild("td", "image-container").appendC hild(imageElement); 155 container.createChild("tr").createChild("td", "image-container").appendC hild(imageElement);
156 if (description) 156 if (description)
157 container.createChild("tr").createChild("td").createChild("span", "d escription").textContent = description; 157 container.createChild("tr").createChild("td").createChild("span", "d escription").textContent = description;
158 userCallback(container); 158 userCallback(container);
159 } 159 }
160 } 160 }
161
162 WebInspector.DOMPresentationUtils.cssPathValue = function(node, optimized)
aandrey 2013/11/20 16:20:49 jsdocs plz
apavlov 2013/11/21 07:31:35 Done.
163 {
164 if (node.nodeType() !== Node.ELEMENT_NODE)
165 return null;
166
167 var id = node.getAttribute("id");
168 if (optimized) {
169 if (id)
170 return new WebInspector.DOMNodePathStep(idSelector(id), true);
171 var nodeNameLower = node.nodeName().toLowerCase();
172 if (nodeNameLower === "body" || nodeNameLower === "head" || nodeNameLowe r === "html")
173 return new WebInspector.DOMNodePathStep(node.nodeNameInCorrectCase() , true);
174 }
175 var nodeName = node.nodeNameInCorrectCase();
176
177 // The "id" presence should terminate the traversal, hence |true|.
aandrey 2013/11/20 16:20:49 sound obvious to me... maybe remove?
apavlov 2013/11/21 07:31:35 Done.
178 if (id)
179 return new WebInspector.DOMNodePathStep(nodeName + idSelector(id), true) ;
180 var parent = node.parentNode;
181 if (!parent || parent.nodeType() === Node.DOCUMENT_NODE)
182 return new WebInspector.DOMNodePathStep(nodeName, true);
183
184 /**
185 * @param {WebInspector.DOMNode} node
186 * @return {Array.<string>}
187 */
188 function elementClassNames(node)
189 {
190 var classAttribute = node.getAttribute("class");
191 if (!classAttribute)
192 return [];
193
194 return classAttribute.split(/\s+/g).filter(Boolean);
195 }
196
197 /**
198 * @param {string} id
199 * @return {string}
200 */
201 function idSelector(id)
202 {
203 return "#" + escapeIdentifierIfNeeded(id);
204 }
205
206 /**
207 * @param {string} ident
208 * @return {string}
209 */
210 function escapeIdentifierIfNeeded(ident)
211 {
212 if (isCSSIdentifier(ident))
213 return ident;
214 var shouldEscapeFirst = /^(?:[0-9]|-[0-9-]?)/.test(ident);
215 var lastIndex = ident.length - 1;
216 return ident.replace(/./g, function(c, i) {
217 return ((shouldEscapeFirst && i === 0) || !isCSSIdentChar(c)) ? esca peAsciiChar(c, i === lastIndex) : c;
218 });
219 }
220
221 /**
222 * @param {string} c
223 * @param {boolean} isLast
224 * @return {string}
225 */
226 function escapeAsciiChar(c, isLast)
227 {
228 return "\\" + toHexByte(c) + (isLast ? "" : " ");
229 }
230
231 /**
232 * @param {string} c
233 */
234 function toHexByte(c)
235 {
236 var hexByte = c.charCodeAt(0).toString(16);
237 if (hexByte.length === 1)
238 hexByte = "0" + hexByte;
239 return hexByte;
240 }
241
242 /**
243 * @param {string} c
244 * @return {boolean}
245 */
246 function isCSSIdentChar(c)
247 {
248 if (/[a-zA-Z0-9_-]/.test(c))
249 return true;
250 return c.charCodeAt(0) >= 0xA0;
251 }
252
253 /**
254 * @param {string} value
255 * @return {boolean}
256 */
257 function isCSSIdentifier(value)
258 {
259 return /^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(value);
260 }
261
262 var uniqueClassNamesArray = elementClassNames(node);
aandrey 2013/11/20 16:20:49 they are no longer unique, once you removed keySet
apavlov 2013/11/21 07:31:35 Done.
263 var needsClassNames = false;
264 var needsNthChild = false;
265 var ownIndex = -1;
266 var siblings = parent.children();
267 for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {
268 var sibling = siblings[i];
269 if (sibling === node) {
270 ownIndex = i;
271 continue;
272 }
273 if (needsNthChild)
274 continue;
275 if (sibling.nodeNameInCorrectCase() !== nodeName)
276 continue;
277
278 needsClassNames = true;
279 var ownClassNames = uniqueClassNamesArray.keySet();
aandrey 2013/11/20 16:20:49 maybe write a utility method to remove a given arr
apavlov 2013/11/21 07:31:35 The problem is that we still need to know how many
280 var ownClassNameCount = 0;
281 for (var name in ownClassNames)
282 ++ownClassNameCount;
283 if (ownClassNameCount === 0) {
284 needsNthChild = true;
285 continue;
286 }
287 var siblingClassNames = elementClassNames(sibling).keySet();
288 for (var siblingClass in siblingClassNames) {
289 if (!ownClassNames.hasOwnProperty(siblingClass))
290 continue;
291 delete ownClassNames[siblingClass];
292 if (!--ownClassNameCount) {
293 needsNthChild = true;
294 break;
295 }
296 }
297 }
298
299 var result = nodeName;
300 if (needsNthChild) {
301 result += ":nth-child(" + (ownIndex + 1) + ")";
302 } else if (needsClassNames) {
303 for (var name in uniqueClassNamesArray.keySet())
304 result += "." + escapeIdentifierIfNeeded(name);
305 }
306
307 return new WebInspector.DOMNodePathStep(result, false);
308 }
309
310 /**
311 * @constructor
312 * @param {string} value
313 * @param {boolean} optimized
314 */
315 WebInspector.DOMNodePathStep = function(value, optimized)
316 {
317 this.value = value;
318 this.optimized = optimized;
319 }
320
321 WebInspector.DOMNodePathStep.prototype = {
322 toString: function()
323 {
324 return this.value;
325 }
326 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/DOMAgent.js ('k') | Source/devtools/front_end/ElementsTreeOutline.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698