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

Side by Side Diff: chrome/tools/test/reference_build/chrome_linux/resources/inspector/InjectedScript.js

Issue 177049: On Linux, move the passing of filedescriptors to a dedicated socketpair(). (Closed)
Patch Set: Removed *.d files from reference build Created 11 years, 3 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
(Empty)
1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 var InjectedScript = {};
30
31 // Called from within InspectorController on the 'inspected page' side.
32 InjectedScript.reset = function()
33 {
34 InjectedScript._styles = {};
35 InjectedScript._styleRules = {};
36 InjectedScript._lastStyleId = 0;
37 InjectedScript._lastStyleRuleId = 0;
38 InjectedScript._searchResults = [];
39 InjectedScript._includedInSearchResultsPropertyName = "__includedInInspector SearchResults";
40 }
41
42 InjectedScript.reset();
43
44 InjectedScript.getStyles = function(nodeId, authorOnly)
45 {
46 var node = InjectedScript._nodeForId(nodeId);
47 if (!node)
48 return false;
49 var matchedRules = InjectedScript._window().getMatchedCSSRules(node, "", aut horOnly);
50 var matchedCSSRules = [];
51 for (var i = 0; matchedRules && i < matchedRules.length; ++i)
52 matchedCSSRules.push(InjectedScript._serializeRule(matchedRules[i]));
53
54 var styleAttributes = {};
55 var attributes = node.attributes;
56 for (var i = 0; attributes && i < attributes.length; ++i) {
57 if (attributes[i].style)
58 styleAttributes[attributes[i].name] = InjectedScript._serializeStyle (attributes[i].style, true);
59 }
60 var result = {};
61 result.inlineStyle = InjectedScript._serializeStyle(node.style, true);
62 result.computedStyle = InjectedScript._serializeStyle(InjectedScript._window ().getComputedStyle(node));
63 result.matchedCSSRules = matchedCSSRules;
64 result.styleAttributes = styleAttributes;
65 return result;
66 }
67
68 InjectedScript.getComputedStyle = function(nodeId)
69 {
70 var node = InjectedScript._nodeForId(nodeId);
71 if (!node)
72 return false;
73 return InjectedScript._serializeStyle(InjectedScript._window().getComputedSt yle(node));
74 }
75
76 InjectedScript.getInlineStyle = function(nodeId)
77 {
78 var node = InjectedScript._nodeForId(nodeId);
79 if (!node)
80 return false;
81 return InjectedScript._serializeStyle(node.style, true);
82 }
83
84 InjectedScript.applyStyleText = function(styleId, styleText, propertyName)
85 {
86 var style = InjectedScript._styles[styleId];
87 if (!style)
88 return false;
89
90 var styleTextLength = styleText.length;
91
92 // Create a new element to parse the user input CSS.
93 var parseElement = document.createElement("span");
94 parseElement.setAttribute("style", styleText);
95
96 var tempStyle = parseElement.style;
97 if (tempStyle.length || !styleTextLength) {
98 // The input was parsable or the user deleted everything, so remove the
99 // original property from the real style declaration. If this represents
100 // a shorthand remove all the longhand properties.
101 if (style.getPropertyShorthand(propertyName)) {
102 var longhandProperties = InjectedScript._getLonghandProperties(style , propertyName);
103 for (var i = 0; i < longhandProperties.length; ++i)
104 style.removeProperty(longhandProperties[i]);
105 } else
106 style.removeProperty(propertyName);
107 }
108
109 if (!tempStyle.length)
110 return false;
111
112 // Iterate of the properties on the test element's style declaration and
113 // add them to the real style declaration. We take care to move shorthands.
114 var foundShorthands = {};
115 var changedProperties = [];
116 var uniqueProperties = InjectedScript._getUniqueStyleProperties(tempStyle);
117 for (var i = 0; i < uniqueProperties.length; ++i) {
118 var name = uniqueProperties[i];
119 var shorthand = tempStyle.getPropertyShorthand(name);
120
121 if (shorthand && shorthand in foundShorthands)
122 continue;
123
124 if (shorthand) {
125 var value = InjectedScript._getShorthandValue(tempStyle, shorthand);
126 var priority = InjectedScript._getShorthandPriority(tempStyle, short hand);
127 foundShorthands[shorthand] = true;
128 } else {
129 var value = tempStyle.getPropertyValue(name);
130 var priority = tempStyle.getPropertyPriority(name);
131 }
132
133 // Set the property on the real style declaration.
134 style.setProperty((shorthand || name), value, priority);
135 changedProperties.push(shorthand || name);
136 }
137 return [InjectedScript._serializeStyle(style, true), changedProperties];
138 }
139
140 InjectedScript.setStyleText = function(style, cssText)
141 {
142 style.cssText = cssText;
143 }
144
145 InjectedScript.toggleStyleEnabled = function(styleId, propertyName, disabled)
146 {
147 var style = InjectedScript._styles[styleId];
148 if (!style)
149 return false;
150
151 if (disabled) {
152 if (!style.__disabledPropertyValues || !style.__disabledPropertyPrioriti es) {
153 var inspectedWindow = InjectedScript._window();
154 style.__disabledProperties = new inspectedWindow.Object;
155 style.__disabledPropertyValues = new inspectedWindow.Object;
156 style.__disabledPropertyPriorities = new inspectedWindow.Object;
157 }
158
159 style.__disabledPropertyValues[propertyName] = style.getPropertyValue(pr opertyName);
160 style.__disabledPropertyPriorities[propertyName] = style.getPropertyPrio rity(propertyName);
161
162 if (style.getPropertyShorthand(propertyName)) {
163 var longhandProperties = InjectedScript._getLonghandProperties(style , propertyName);
164 for (var i = 0; i < longhandProperties.length; ++i) {
165 style.__disabledProperties[longhandProperties[i]] = true;
166 style.removeProperty(longhandProperties[i]);
167 }
168 } else {
169 style.__disabledProperties[propertyName] = true;
170 style.removeProperty(propertyName);
171 }
172 } else if (style.__disabledProperties && style.__disabledProperties[property Name]) {
173 var value = style.__disabledPropertyValues[propertyName];
174 var priority = style.__disabledPropertyPriorities[propertyName];
175
176 style.setProperty(propertyName, value, priority);
177 delete style.__disabledProperties[propertyName];
178 delete style.__disabledPropertyValues[propertyName];
179 delete style.__disabledPropertyPriorities[propertyName];
180 }
181 return InjectedScript._serializeStyle(style, true);
182 }
183
184 InjectedScript.applyStyleRuleText = function(ruleId, newContent, selectedNodeId)
185 {
186 var rule = InjectedScript._styleRules[ruleId];
187 if (!rule)
188 return false;
189
190 var selectedNode = InjectedScript._nodeForId(selectedNodeId);
191
192 try {
193 var stylesheet = rule.parentStyleSheet;
194 stylesheet.addRule(newContent);
195 var newRule = stylesheet.cssRules[stylesheet.cssRules.length - 1];
196 newRule.style.cssText = rule.style.cssText;
197
198 var parentRules = stylesheet.cssRules;
199 for (var i = 0; i < parentRules.length; ++i) {
200 if (parentRules[i] === rule) {
201 rule.parentStyleSheet.removeRule(i);
202 break;
203 }
204 }
205
206 return [InjectedScript._serializeRule(newRule), InjectedScript._doesSele ctorAffectNode(newContent, selectedNode)];
207 } catch(e) {
208 // Report invalid syntax.
209 return false;
210 }
211 }
212
213 InjectedScript.addStyleSelector = function(newContent, selectedNodeId)
214 {
215 var stylesheet = InjectedScript.stylesheet;
216 if (!stylesheet) {
217 var inspectedDocument = InjectedScript._window().document;
218 var head = inspectedDocument.getElementsByTagName("head")[0];
219 var styleElement = inspectedDocument.createElement("style");
220 styleElement.type = "text/css";
221 head.appendChild(styleElement);
222 stylesheet = inspectedDocument.styleSheets[inspectedDocument.styleSheets .length - 1];
223 InjectedScript.stylesheet = stylesheet;
224 }
225
226 try {
227 stylesheet.addRule(newContent);
228 } catch (e) {
229 // Invalid Syntax for a Selector
230 return false;
231 }
232
233 var selectedNode = InjectedScript._nodeForId(selectedNodeId);
234 var rule = stylesheet.cssRules[stylesheet.cssRules.length - 1];
235 rule.__isViaInspector = true;
236
237 return [ InjectedScript._serializeRule(rule), InjectedScript._doesSelectorAf fectNode(newContent, selectedNode) ];
238 }
239
240 InjectedScript._doesSelectorAffectNode = function(selectorText, node)
241 {
242 if (!node)
243 return false;
244 var nodes = node.ownerDocument.querySelectorAll(selectorText);
245 for (var i = 0; i < nodes.length; ++i) {
246 if (nodes[i] === node) {
247 return true;
248 }
249 }
250 return false;
251 }
252
253 InjectedScript.setStyleProperty = function(styleId, name, value)
254 {
255 var style = InjectedScript._styles[styleId];
256 if (!style)
257 return false;
258
259 style.setProperty(name, value, "");
260 return true;
261 }
262
263 InjectedScript._serializeRule = function(rule)
264 {
265 var parentStyleSheet = rule.parentStyleSheet;
266
267 var ruleValue = {};
268 ruleValue.selectorText = rule.selectorText;
269 if (parentStyleSheet) {
270 ruleValue.parentStyleSheet = {};
271 ruleValue.parentStyleSheet.href = parentStyleSheet.href;
272 }
273 ruleValue.isUserAgent = parentStyleSheet && !parentStyleSheet.ownerNode && ! parentStyleSheet.href;
274 ruleValue.isUser = parentStyleSheet && parentStyleSheet.ownerNode && parentS tyleSheet.ownerNode.nodeName == "#document";
275 ruleValue.isViaInspector = !!rule.__isViaInspector;
276
277 // Bind editable scripts only.
278 var doBind = !ruleValue.isUserAgent && !ruleValue.isUser;
279 ruleValue.style = InjectedScript._serializeStyle(rule.style, doBind);
280
281 if (doBind) {
282 if (!rule.id) {
283 rule.id = InjectedScript._lastStyleRuleId++;
284 InjectedScript._styleRules[rule.id] = rule;
285 }
286 ruleValue.id = rule.id;
287 }
288 return ruleValue;
289 }
290
291 InjectedScript._serializeStyle = function(style, doBind)
292 {
293 var result = {};
294 result.width = style.width;
295 result.height = style.height;
296 result.__disabledProperties = style.__disabledProperties;
297 result.__disabledPropertyValues = style.__disabledPropertyValues;
298 result.__disabledPropertyPriorities = style.__disabledPropertyPriorities;
299 result.properties = [];
300 result.shorthandValues = {};
301 var foundShorthands = {};
302 for (var i = 0; i < style.length; ++i) {
303 var property = {};
304 var name = style[i];
305 property.name = name;
306 property.priority = style.getPropertyPriority(name);
307 property.implicit = style.isPropertyImplicit(name);
308 var shorthand = style.getPropertyShorthand(name);
309 property.shorthand = shorthand;
310 if (shorthand && !(shorthand in foundShorthands)) {
311 foundShorthands[shorthand] = true;
312 result.shorthandValues[shorthand] = InjectedScript._getShorthandValu e(style, shorthand);
313 }
314 property.value = style.getPropertyValue(name);
315 result.properties.push(property);
316 }
317 result.uniqueStyleProperties = InjectedScript._getUniqueStyleProperties(styl e);
318
319 if (doBind) {
320 if (!style.id) {
321 style.id = InjectedScript._lastStyleId++;
322 InjectedScript._styles[style.id] = style;
323 }
324 result.id = style.id;
325 }
326 return result;
327 }
328
329 InjectedScript._getUniqueStyleProperties = function(style)
330 {
331 var properties = [];
332 var foundProperties = {};
333
334 for (var i = 0; i < style.length; ++i) {
335 var property = style[i];
336 if (property in foundProperties)
337 continue;
338 foundProperties[property] = true;
339 properties.push(property);
340 }
341
342 return properties;
343 }
344
345
346 InjectedScript._getLonghandProperties = function(style, shorthandProperty)
347 {
348 var properties = [];
349 var foundProperties = {};
350
351 for (var i = 0; i < style.length; ++i) {
352 var individualProperty = style[i];
353 if (individualProperty in foundProperties || style.getPropertyShorthand( individualProperty) !== shorthandProperty)
354 continue;
355 foundProperties[individualProperty] = true;
356 properties.push(individualProperty);
357 }
358
359 return properties;
360 }
361
362 InjectedScript._getShorthandValue = function(style, shorthandProperty)
363 {
364 var value = style.getPropertyValue(shorthandProperty);
365 if (!value) {
366 // Some shorthands (like border) return a null value, so compute a short hand value.
367 // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 is fixed.
368
369 var foundProperties = {};
370 for (var i = 0; i < style.length; ++i) {
371 var individualProperty = style[i];
372 if (individualProperty in foundProperties || style.getPropertyShorth and(individualProperty) !== shorthandProperty)
373 continue;
374
375 var individualValue = style.getPropertyValue(individualProperty);
376 if (style.isPropertyImplicit(individualProperty) || individualValue === "initial")
377 continue;
378
379 foundProperties[individualProperty] = true;
380
381 if (!value)
382 value = "";
383 else if (value.length)
384 value += " ";
385 value += individualValue;
386 }
387 }
388 return value;
389 }
390
391 InjectedScript._getShorthandPriority = function(style, shorthandProperty)
392 {
393 var priority = style.getPropertyPriority(shorthandProperty);
394 if (!priority) {
395 for (var i = 0; i < style.length; ++i) {
396 var individualProperty = style[i];
397 if (style.getPropertyShorthand(individualProperty) !== shorthandProp erty)
398 continue;
399 priority = style.getPropertyPriority(individualProperty);
400 break;
401 }
402 }
403 return priority;
404 }
405
406 InjectedScript.getPrototypes = function(nodeId)
407 {
408 var node = InjectedScript._nodeForId(nodeId);
409 if (!node)
410 return false;
411
412 var result = [];
413 for (var prototype = node; prototype; prototype = prototype.__proto__) {
414 var title = Object.describe(prototype);
415 if (title.match(/Prototype$/)) {
416 title = title.replace(/Prototype$/, "");
417 }
418 result.push(title);
419 }
420 return result;
421 }
422
423 InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty)
424 {
425 var object = InjectedScript._resolveObject(objectProxy);
426 if (!object)
427 return false;
428
429 var properties = [];
430
431 // Go over properties, prepare results.
432 for (var propertyName in object) {
433 if (!ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOw nProperty(propertyName))
434 continue;
435
436 var property = {};
437 property.name = propertyName;
438 property.parentObjectProxy = objectProxy;
439 var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(pro pertyName);
440 if (!property.isGetter) {
441 var childObject = object[propertyName];
442 var childObjectProxy = new InjectedScript.createProxyObject(childObj ect, objectProxy.objectId, true);
443 childObjectProxy.path = objectProxy.path ? objectProxy.path.slice() : [];
444 childObjectProxy.path.push(propertyName);
445 childObjectProxy.protoDepth = objectProxy.protoDepth || 0;
446 property.value = childObjectProxy;
447 } else {
448 // FIXME: this should show something like "getter" (bug 16734).
449 property.value = { description: "\u2014" }; // em dash
450 property.isGetter = true;
451 }
452 properties.push(property);
453 }
454 return properties;
455 }
456
457 InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression )
458 {
459 var object = InjectedScript._resolveObject(objectProxy);
460 if (!object)
461 return false;
462
463 var expressionLength = expression.length;
464 if (!expressionLength) {
465 delete object[propertyName];
466 return !(propertyName in object);
467 }
468
469 try {
470 // Surround the expression in parenthesis so the result of the eval is t he result
471 // of the whole expression not the last potential sub-expression.
472
473 // There is a regression introduced here: eval is now happening against global object,
474 // not call frame while on a breakpoint.
475 // TODO: bring evaluation against call frame back.
476 var result = InjectedScript._window().eval("(" + expression + ")");
477 // Store the result in the property.
478 object[propertyName] = result;
479 return true;
480 } catch(e) {
481 try {
482 var result = InjectedScript._window().eval("\"" + expression.escapeC haracters("\"") + "\"");
483 object[propertyName] = result;
484 return true;
485 } catch(e) {
486 return false;
487 }
488 }
489 }
490
491 InjectedScript.evaluate = function(expression)
492 {
493 return InjectedScript._evaluateOn(InjectedScript._window().eval, InjectedScr ipt._window(), expression);
494 }
495
496 InjectedScript._evaluateOn = function(evalFunction, object, expression)
497 {
498 InjectedScript._ensureCommandLineAPIInstalled();
499 // Surround the expression in with statements to inject our command line API so that
500 // the window object properties still take more precedent than our API funct ions.
501 expression = "with (window._inspectorCommandLineAPI) { with (window) { " + e xpression + " } }";
502
503 var result = {};
504 try {
505 var value = evalFunction.call(object, expression);
506 if (value === null)
507 return { value: null };
508 var value = evalFunction.call(object, expression);
509 var wrapper = InspectorController.wrapObject(value);
510 if (typeof wrapper === "object" && wrapper.exception) {
511 result.value = wrapper.exception;
512 result.isException = true;
513 } else {
514 result.value = wrapper;
515 }
516 } catch (e) {
517 result.value = e.toString();
518 result.isException = true;
519 }
520 return result;
521 }
522
523 InjectedScript.addInspectedNode = function(nodeId)
524 {
525 var node = InjectedScript._nodeForId(nodeId);
526 if (!node)
527 return false;
528
529 InjectedScript._ensureCommandLineAPIInstalled();
530 var inspectedNodes = InjectedScript._window()._inspectorCommandLineAPI._insp ectedNodes;
531 inspectedNodes.unshift(node);
532 if (inspectedNodes.length >= 5)
533 inspectedNodes.pop();
534 return true;
535 }
536
537 InjectedScript.performSearch = function(whitespaceTrimmedQuery)
538 {
539 var tagNameQuery = whitespaceTrimmedQuery;
540 var attributeNameQuery = whitespaceTrimmedQuery;
541 var startTagFound = (tagNameQuery.indexOf("<") === 0);
542 var endTagFound = (tagNameQuery.lastIndexOf(">") === (tagNameQuery.length - 1));
543
544 if (startTagFound || endTagFound) {
545 var tagNameQueryLength = tagNameQuery.length;
546 tagNameQuery = tagNameQuery.substring((startTagFound ? 1 : 0), (endTagFo und ? (tagNameQueryLength - 1) : tagNameQueryLength));
547 }
548
549 // Check the tagNameQuery is it is a possibly valid tag name.
550 if (!/^[a-zA-Z0-9\-_:]+$/.test(tagNameQuery))
551 tagNameQuery = null;
552
553 // Check the attributeNameQuery is it is a possibly valid tag name.
554 if (!/^[a-zA-Z0-9\-_:]+$/.test(attributeNameQuery))
555 attributeNameQuery = null;
556
557 const escapedQuery = whitespaceTrimmedQuery.escapeCharacters("'");
558 const escapedTagNameQuery = (tagNameQuery ? tagNameQuery.escapeCharacters("' ") : null);
559 const escapedWhitespaceTrimmedQuery = whitespaceTrimmedQuery.escapeCharacter s("'");
560 const searchResultsProperty = InjectedScript._includedInSearchResultsPropert yName;
561
562 function addNodesToResults(nodes, length, getItem)
563 {
564 if (!length)
565 return;
566
567 var nodeIds = [];
568 for (var i = 0; i < length; ++i) {
569 var node = getItem.call(nodes, i);
570 // Skip this node if it already has the property.
571 if (searchResultsProperty in node)
572 continue;
573
574 if (!InjectedScript._searchResults.length) {
575 InjectedScript._currentSearchResultIndex = 0;
576 }
577
578 node[searchResultsProperty] = true;
579 InjectedScript._searchResults.push(node);
580 var nodeId = InspectorController.pushNodePathToFrontend(node, false) ;
581 nodeIds.push(nodeId);
582 }
583 InspectorController.addNodesToSearchResult(nodeIds.join(","));
584 }
585
586 function matchExactItems(doc)
587 {
588 matchExactId.call(this, doc);
589 matchExactClassNames.call(this, doc);
590 matchExactTagNames.call(this, doc);
591 matchExactAttributeNames.call(this, doc);
592 }
593
594 function matchExactId(doc)
595 {
596 const result = doc.__proto__.getElementById.call(doc, whitespaceTrimmedQ uery);
597 addNodesToResults.call(this, result, (result ? 1 : 0), function() { retu rn this });
598 }
599
600 function matchExactClassNames(doc)
601 {
602 const result = doc.__proto__.getElementsByClassName.call(doc, whitespace TrimmedQuery);
603 addNodesToResults.call(this, result, result.length, result.item);
604 }
605
606 function matchExactTagNames(doc)
607 {
608 if (!tagNameQuery)
609 return;
610 const result = doc.__proto__.getElementsByTagName.call(doc, tagNameQuery );
611 addNodesToResults.call(this, result, result.length, result.item);
612 }
613
614 function matchExactAttributeNames(doc)
615 {
616 if (!attributeNameQuery)
617 return;
618 const result = doc.__proto__.querySelectorAll.call(doc, "[" + attributeN ameQuery + "]");
619 addNodesToResults.call(this, result, result.length, result.item);
620 }
621
622 function matchPartialTagNames(doc)
623 {
624 if (!tagNameQuery)
625 return;
626 const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYP E);
627 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
628 }
629
630 function matchStartOfTagNames(doc)
631 {
632 if (!tagNameQuery)
633 return;
634 const result = doc.__proto__.evaluate.call(doc, "//*[starts-with(name(), '" + escapedTagNameQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_ TYPE);
635 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
636 }
637
638 function matchPartialTagNamesAndAttributeValues(doc)
639 {
640 if (!tagNameQuery) {
641 matchPartialAttributeValues.call(this, doc);
642 return;
643 }
644
645 const result = doc.__proto__.evaluate.call(doc, "//*[contains(name(), '" + escapedTagNameQuery + "') or contains(@*, '" + escapedQuery + "')]", doc, nul l, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
646 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
647 }
648
649 function matchPartialAttributeValues(doc)
650 {
651 const result = doc.__proto__.evaluate.call(doc, "//*[contains(@*, '" + e scapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
652 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
653 }
654
655 function matchStyleSelector(doc)
656 {
657 const result = doc.__proto__.querySelectorAll.call(doc, whitespaceTrimme dQuery);
658 addNodesToResults.call(this, result, result.length, result.item);
659 }
660
661 function matchPlainText(doc)
662 {
663 const result = doc.__proto__.evaluate.call(doc, "//text()[contains(., '" + escapedQuery + "')] | //comment()[contains(., '" + escapedQuery + "')]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
664 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
665 }
666
667 function matchXPathQuery(doc)
668 {
669 const result = doc.__proto__.evaluate.call(doc, whitespaceTrimmedQuery, doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
670 addNodesToResults.call(this, result, result.snapshotLength, result.snaps hotItem);
671 }
672
673 function finishedSearching()
674 {
675 // Remove the searchResultsProperty now that the search is finished.
676 for (var i = 0; i < InjectedScript._searchResults.length; ++i)
677 delete InjectedScript._searchResults[i][searchResultsProperty];
678 }
679
680 const mainFrameDocument = InjectedScript._window().document;
681 const searchDocuments = [mainFrameDocument];
682 var searchFunctions;
683 if (tagNameQuery && startTagFound && endTagFound)
684 searchFunctions = [matchExactTagNames, matchPlainText];
685 else if (tagNameQuery && startTagFound)
686 searchFunctions = [matchStartOfTagNames, matchPlainText];
687 else if (tagNameQuery && endTagFound) {
688 // FIXME: we should have a matchEndOfTagNames search function if endTagF ound is true but not startTagFound.
689 // This requires ends-with() support in XPath, WebKit only supports star ts-with() and contains().
690 searchFunctions = [matchPartialTagNames, matchPlainText];
691 } else if (whitespaceTrimmedQuery === "//*" || whitespaceTrimmedQuery === "* ") {
692 // These queries will match every node. Matching everything isn't useful and can be slow for large pages,
693 // so limit the search functions list to plain text and attribute matchi ng.
694 searchFunctions = [matchPartialAttributeValues, matchPlainText];
695 } else
696 searchFunctions = [matchExactItems, matchStyleSelector, matchPartialTagN amesAndAttributeValues, matchPlainText, matchXPathQuery];
697
698 // Find all frames, iframes and object elements to search their documents.
699 const querySelectorAllFunction = InjectedScript._window().Document.prototype .querySelectorAll;
700 const subdocumentResult = querySelectorAllFunction.call(mainFrameDocument, " iframe, frame, object");
701
702 for (var i = 0; i < subdocumentResult.length; ++i) {
703 var element = subdocumentResult.item(i);
704 if (element.contentDocument)
705 searchDocuments.push(element.contentDocument);
706 }
707
708 const panel = InjectedScript;
709 var documentIndex = 0;
710 var searchFunctionIndex = 0;
711 var chunkIntervalIdentifier = null;
712
713 // Split up the work into chunks so we don't block the UI thread while proce ssing.
714
715 function processChunk()
716 {
717 var searchDocument = searchDocuments[documentIndex];
718 var searchFunction = searchFunctions[searchFunctionIndex];
719
720 if (++searchFunctionIndex > searchFunctions.length) {
721 searchFunction = searchFunctions[0];
722 searchFunctionIndex = 0;
723
724 if (++documentIndex > searchDocuments.length) {
725 if (panel._currentSearchChunkIntervalIdentifier === chunkInterva lIdentifier)
726 delete panel._currentSearchChunkIntervalIdentifier;
727 clearInterval(chunkIntervalIdentifier);
728 finishedSearching.call(panel);
729 return;
730 }
731
732 searchDocument = searchDocuments[documentIndex];
733 }
734
735 if (!searchDocument || !searchFunction)
736 return;
737
738 try {
739 searchFunction.call(panel, searchDocument);
740 } catch(err) {
741 // ignore any exceptions. the query might be malformed, but we allow that.
742 }
743 }
744
745 processChunk();
746
747 chunkIntervalIdentifier = setInterval(processChunk, 25);
748 InjectedScript._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifi er;
749 return true;
750 }
751
752 InjectedScript.searchCanceled = function()
753 {
754 if (InjectedScript._searchResults) {
755 const searchResultsProperty = InjectedScript._includedInSearchResultsPro pertyName;
756 for (var i = 0; i < this._searchResults.length; ++i) {
757 var node = this._searchResults[i];
758
759 // Remove the searchResultsProperty since there might be an unfinish ed search.
760 delete node[searchResultsProperty];
761 }
762 }
763
764 if (InjectedScript._currentSearchChunkIntervalIdentifier) {
765 clearInterval(InjectedScript._currentSearchChunkIntervalIdentifier);
766 delete InjectedScript._currentSearchChunkIntervalIdentifier;
767 }
768 InjectedScript._searchResults = [];
769 return true;
770 }
771
772 InjectedScript.openInInspectedWindow = function(url)
773 {
774 InjectedScript._window().open(url);
775 }
776
777 InjectedScript.getCallFrames = function()
778 {
779 var callFrame = InspectorController.currentCallFrame();
780 if (!callFrame)
781 return false;
782
783 var result = [];
784 var depth = 0;
785 do {
786 result.push(new InjectedScript.CallFrameProxy(depth++, callFrame));
787 callFrame = callFrame.caller;
788 } while (callFrame);
789 return result;
790 }
791
792 InjectedScript.evaluateInCallFrame = function(callFrameId, code)
793 {
794 var callFrame = InjectedScript._callFrameForId(callFrameId);
795 if (!callFrame)
796 return false;
797 return InjectedScript._evaluateOn(callFrame.evaluate, callFrame, code);
798 }
799
800 InjectedScript._callFrameForId = function(id)
801 {
802 var callFrame = InspectorController.currentCallFrame();
803 while (--id >= 0 && callFrame)
804 callFrame = callFrame.caller;
805 return callFrame;
806 }
807
808 InjectedScript._ensureCommandLineAPIInstalled = function(inspectedWindow)
809 {
810 var inspectedWindow = InjectedScript._window();
811 if (inspectedWindow._inspectorCommandLineAPI)
812 return;
813
814 inspectedWindow.eval("window._inspectorCommandLineAPI = { \
815 $: function() { return document.getElementById.apply(document, arguments ) }, \
816 $$: function() { return document.querySelectorAll.apply(document, argume nts) }, \
817 $x: function(xpath, context) { \
818 var nodes = []; \
819 try { \
820 var doc = context || document; \
821 var results = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYP E, null); \
822 var node; \
823 while (node = results.iterateNext()) nodes.push(node); \
824 } catch (e) {} \
825 return nodes; \
826 }, \
827 dir: function() { return console.dir.apply(console, arguments) }, \
828 dirxml: function() { return console.dirxml.apply(console, arguments) }, \
829 keys: function(o) { var a = []; for (var k in o) a.push(k); return a; }, \
830 values: function(o) { var a = []; for (var k in o) a.push(o[k]); return a; }, \
831 profile: function() { return console.profile.apply(console, arguments) } , \
832 profileEnd: function() { return console.profileEnd.apply(console, argume nts) }, \
833 _inspectedNodes: [], \
834 get $0() { return _inspectorCommandLineAPI._inspectedNodes[0] }, \
835 get $1() { return _inspectorCommandLineAPI._inspectedNodes[1] }, \
836 get $2() { return _inspectorCommandLineAPI._inspectedNodes[2] }, \
837 get $3() { return _inspectorCommandLineAPI._inspectedNodes[3] }, \
838 get $4() { return _inspectorCommandLineAPI._inspectedNodes[4] } \
839 };");
840
841 inspectedWindow._inspectorCommandLineAPI.clear = InspectorController.wrapCal lback(InspectorController.clearMessages.bind(InspectorController, true));
842 inspectedWindow._inspectorCommandLineAPI.inspect = InspectorController.wrapC allback(inspectObject.bind(this));
843
844 function inspectObject(o)
845 {
846 if (arguments.length === 0)
847 return;
848
849 inspectedWindow.console.log(o);
850 if (Object.type(o, inspectedWindow) === "node") {
851 InspectorController.pushNodePathToFrontend(o, true);
852 } else {
853 switch (Object.describe(o)) {
854 case "Database":
855 InspectorController.selectDatabase(o);
856 break;
857 case "Storage":
858 InspectorController.selectDOMStorage(o);
859 break;
860 }
861 }
862 }
863 }
864
865 InjectedScript._resolveObject = function(objectProxy)
866 {
867 var object = InjectedScript._objectForId(objectProxy.objectId);
868 var path = objectProxy.path;
869 var protoDepth = objectProxy.protoDepth;
870
871 // Follow the property path.
872 for (var i = 0; object && path && i < path.length; ++i)
873 object = object[path[i]];
874
875 // Get to the necessary proto layer.
876 for (var i = 0; object && protoDepth && i < protoDepth; ++i)
877 object = object.__proto__;
878
879 return object;
880 }
881
882 InjectedScript._window = function()
883 {
884 // TODO: replace with 'return window;' once this script is injected into
885 // the page's context.
886 return InspectorController.inspectedWindow();
887 }
888
889 InjectedScript._nodeForId = function(nodeId)
890 {
891 if (!nodeId)
892 return null;
893 return InspectorController.nodeForId(nodeId);
894 }
895
896 InjectedScript._objectForId = function(objectId)
897 {
898 // There are three types of object ids used:
899 // - numbers point to DOM Node via the InspectorDOMAgent mapping
900 // - strings point to console objects cached in InspectorController for lazy evaluation upon them
901 // - objects contain complex ids and are currently used for scoped objects
902 if (typeof objectId === "number") {
903 return InjectedScript._nodeForId(objectId);
904 } else if (typeof objectId === "string") {
905 return InspectorController.unwrapObject(objectId);
906 } else if (typeof objectId === "object") {
907 var callFrame = InjectedScript._callFrameForId(objectId.callFrame);
908 if (objectId.thisObject)
909 return callFrame.thisObject;
910 else
911 return callFrame.scopeChain[objectId.chainIndex];
912 }
913 return objectId;
914 }
915
916 InjectedScript.pushNodeToFrontend = function(objectProxy)
917 {
918 var object = InjectedScript._resolveObject(objectProxy);
919 if (!object || Object.type(object, InjectedScript._window()) !== "node")
920 return false;
921 return InspectorController.pushNodePathToFrontend(object, false);
922 }
923
924 // Called from within InspectorController on the 'inspected page' side.
925 InjectedScript.createProxyObject = function(object, objectId, abbreviate)
926 {
927 var result = {};
928 result.objectId = objectId;
929 result.type = Object.type(object, InjectedScript._window());
930
931 var type = typeof object;
932 if (type === "object" || type === "function") {
933 for (var subPropertyName in object) {
934 result.hasChildren = true;
935 break;
936 }
937 }
938 try {
939 result.description = Object.describe(object, abbreviate, InjectedScript. _window());
940 } catch (e) {
941 result.exception = e.toString();
942 }
943 return result;
944 }
945
946 InjectedScript.CallFrameProxy = function(id, callFrame)
947 {
948 this.id = id;
949 this.type = callFrame.type;
950 this.functionName = callFrame.functionName;
951 this.sourceID = callFrame.sourceID;
952 this.line = callFrame.line;
953 this.scopeChain = this._wrapScopeChain(callFrame);
954 }
955
956 InjectedScript.CallFrameProxy.prototype = {
957 _wrapScopeChain: function(callFrame)
958 {
959 var foundLocalScope = false;
960 var scopeChain = callFrame.scopeChain;
961 var scopeChainProxy = [];
962 for (var i = 0; i < scopeChain.length; ++i) {
963 var scopeObject = scopeChain[i];
964 var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: i });
965 if (Object.prototype.toString.call(scopeObject) === "[object JSActiv ation]") {
966 if (!foundLocalScope)
967 scopeObjectProxy.thisObject = InjectedScript.createProxyObje ct(callFrame.thisObject, { callFrame: this.id, thisObject: true });
968 else
969 scopeObjectProxy.isClosure = true;
970 foundLocalScope = true;
971 scopeObjectProxy.isLocal = true;
972 } else if (foundLocalScope && scopeObject instanceof InjectedScript. _window().Element)
973 scopeObjectProxy.isElement = true;
974 else if (foundLocalScope && scopeObject instanceof InjectedScript._w indow().Document)
975 scopeObjectProxy.isDocument = true;
976 else if (!foundLocalScope && !localScope)
977 scopeObjectProxy.isWithBlock = true;
978 scopeObjectProxy.properties = [];
979 try {
980 for (var propertyName in scopeObject)
981 scopeObjectProxy.properties.push(propertyName);
982 } catch (e) {
983 }
984 scopeChainProxy.push(scopeObjectProxy);
985 }
986 return scopeChainProxy;
987 }
988 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698