OLD | NEW |
---|---|
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 Loading... | |
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 } | |
OLD | NEW |