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

Side by Side Diff: chrome/tools/test/reference_build/chrome_linux/resources/inspector/dom_agent.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 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Dom and DomNode are used to represent remote DOM in the
7 * web inspector.
8 */
9 goog.provide('devtools.DomAgent');
10 goog.provide('devtools.DomDocument');
11 goog.provide('devtools.DomNode');
12
13 goog.require('devtools.Callback');
14
15
16 /**
17 * Defines indexes for the node payload properties.
18 */
19 devtools.PayloadIndex = {
20 ID : 0,
21 TYPE : 1,
22 NAME : 2,
23 VALUE : 3,
24 ATTRS : 4,
25 HAS_CHILDREN : 5,
26 CHILD_NODES : 6
27 };
28
29
30 /**
31 * Creates document node in a given document based on a given payload data.
32 * @param {devtools.Doc} doc Document to create node in.
33 * @param {Array.<Object>} payload Data to build node based upon.
34 * @constructor
35 */
36 devtools.DomNode = function(doc, payload) {
37 this.ownerDocument = doc;
38
39 this.id_ = payload[devtools.PayloadIndex.ID];
40 this.nodeType = payload[devtools.PayloadIndex.TYPE];
41 this.nodeName = payload[devtools.PayloadIndex.NAME];
42 this.nodeValue_ = payload[devtools.PayloadIndex.VALUE];
43 this.textContent = this.nodeValue;
44
45 this.attributes = [];
46 this.attributesMap_ = {};
47 if (payload.length > devtools.PayloadIndex.ATTRS) {
48 this.setAttributesPayload_(payload[devtools.PayloadIndex.ATTRS]);
49 }
50
51 this.childNodesCount_ = payload[devtools.PayloadIndex.HAS_CHILDREN];
52 this.children = null;
53
54 this.nextSibling = null;
55 this.prevSibling = null;
56 this.firstChild = null;
57 this.parentNode = null;
58
59 this.disabledStyleProperties_ = {};
60
61 if (payload.length > devtools.PayloadIndex.CHILD_NODES) {
62 // Has children payloads
63 this.setChildrenPayload_(
64 payload[devtools.PayloadIndex.CHILD_NODES]);
65 }
66
67 this.computedStyle_ = null;
68 this.style = null;
69 this.matchedCSSRules_ = [];
70 };
71
72
73 /**
74 * Overrides for getters and setters.
75 */
76 devtools.DomNode.prototype = {
77 get nodeValue() {
78 return this.nodeValue_;
79 },
80
81 set nodeValue(value) {
82 if (this.nodeType != Node.TEXT_NODE) {
83 return;
84 }
85 var self = this;
86 this.ownerDocument.domAgent_.setTextNodeValueAsync(this, value,
87 function() {
88 self.nodeValue_ = value;
89 self.textContent = value;
90 });
91 }
92 };
93
94
95 /**
96 * Sets attributes for a given node based on a given attrs payload.
97 * @param {Array.<string>} attrs Attribute key-value pairs to set.
98 * @private
99 */
100 devtools.DomNode.prototype.setAttributesPayload_ = function(attrs) {
101 for (var i = 0; i < attrs.length; i += 2) {
102 this.addAttribute_(attrs[i], attrs[i + 1]);
103 }
104 };
105
106
107 /**
108 * @return True iff node has attributes.
109 */
110 devtools.DomNode.prototype.hasAttributes = function() {
111 return this.attributes.length > 0;
112 };
113
114
115 /**
116 * @return True iff node has child nodes.
117 */
118 devtools.DomNode.prototype.hasChildNodes = function() {
119 return this.childNodesCount_ > 0;
120 };
121
122
123 /**
124 * Inserts child node into this node after a given anchor.
125 * @param {devtools.DomNode} prev Node to insert child after.
126 * @param {Array.<Object>} payload Child node data.
127 * @private
128 */
129 devtools.DomNode.prototype.insertChild_ = function(prev, payload) {
130 var node = new devtools.DomNode(this.ownerDocument, payload);
131 if (!prev) {
132 // First node
133 this.children = [ node ];
134 } else {
135 this.children.splice(this.children.indexOf(prev) + 1, 0, node);
136 }
137 this.renumber_();
138 return node;
139 };
140
141
142 /**
143 * Removes child node from this node.
144 * @param {devtools.DomNode} node Node to remove.
145 * @private
146 */
147 devtools.DomNode.prototype.removeChild_ = function(node) {
148 this.children.splice(this.children.indexOf(node), 1);
149 node.parentNode = null;
150 this.renumber_();
151 };
152
153
154 /**
155 * Sets children for this node based on the given payload.
156 * @param {Array.<Object>} payload Data for children.
157 * @private
158 */
159 devtools.DomNode.prototype.setChildrenPayload_ = function(payloads) {
160 this.children = [];
161 for (var i = 0; i < payloads.length; ++i) {
162 var payload = payloads[i];
163 var node = new devtools.DomNode(this.ownerDocument, payload);
164 this.children.push(node);
165 }
166 this.renumber_();
167 };
168
169
170 /**
171 * Normalizes prev/next/parent/firstChild links for this node's children.
172 * @private
173 */
174 devtools.DomNode.prototype.renumber_ = function() {
175 this.childNodesCount_ = this.children.length;
176 if (this.childNodesCount_ == 0) {
177 this.firstChild = null;
178 return;
179 }
180 this.firstChild = this.children[0];
181 for (var i = 0; i < this.childNodesCount_; ++i) {
182 var child = this.children[i];
183 child.nextSibling = i + 1 < this.childNodesCount_ ?
184 this.children[i + 1] : null;
185 child.prevSibling = i - 1 >= 0 ? this.children[i - 1] : null;
186 child.parentNode = this;
187 }
188 };
189
190
191 /**
192 * Returns attribute value.
193 * @param {string} name Attribute name to get value for.
194 * @return {string} Attribute value.
195 */
196 devtools.DomNode.prototype.getAttribute = function(name) {
197 var attr = this.attributesMap_[name];
198 return attr ? attr.value : undefined;
199 };
200
201
202 /**
203 * Sends 'set attribute' command to the remote agent.
204 * @param {string} name Attribute name to set value for.
205 * @param {string} value Attribute value to set.
206 */
207 devtools.DomNode.prototype.setAttribute = function(name, value) {
208 var self = this;
209 this.ownerDocument.domAgent_.setAttributeAsync(this, name, value,
210 function() {
211 var attr = self.attributesMap_[name];
212 if (attr) {
213 attr.value = value;
214 } else {
215 attr = self.addAttribute_(name, value);
216 }
217 });
218 };
219
220
221 /**
222 * Creates an attribute-like object and adds it to the object.
223 * @param {string} name Attribute name to set value for.
224 * @param {string} value Attribute value to set.
225 */
226 devtools.DomNode.prototype.addAttribute_ = function(name, value) {
227 var attr = {
228 'name': name,
229 'value': value,
230 node_: this
231 };
232
233 this.attributesMap_[name] = attr;
234 this.attributes.push(attr);
235 };
236
237
238 /**
239 * Sends 'remove attribute' command to the remote agent.
240 * @param {string} name Attribute name to set value for.
241 */
242 devtools.DomNode.prototype.removeAttribute = function(name) {
243 var self = this;
244 this.ownerDocument.domAgent_.removeAttributeAsync(this, name, function() {
245 delete self.attributesMap_[name];
246 for (var i = 0; i < self.attributes.length; ++i) {
247 if (self.attributes[i].name == name) {
248 self.attributes.splice(i, 1);
249 break;
250 }
251 }
252 });
253 };
254
255
256 /**
257 * Makes available the following methods and properties:
258 * - node.style property
259 * - node.document.defaultView.getComputedStyles(node)
260 * - node.document.defaultView.getMatchedCSSRules(node, ...)
261 * - style attribute of node's attributes
262 * @param {string} computedStyle is a cssText of result of getComputedStyle().
263 * @param {string} inlineStyle is a style.cssText (defined in the STYLE
264 * attribute).
265 * @param {Object} styleAttributes represents 'style' property
266 * of attributes.
267 * @param {Array.<object>} matchedCSSRules represents result of the
268 * getMatchedCSSRules(node, '', authorOnly). Each elemet consists of:
269 * selector, rule.style.cssText[, rule.parentStyleSheet.href
270 * [, rule.parentStyleSheet.ownerNode.nodeName]].
271 */
272 devtools.DomNode.prototype.setStyles = function(computedStyle, inlineStyle,
273 styleAttributes, matchedCSSRules) {
274 this.computedStyle_ = this.makeStyle_(computedStyle);
275 this.style = this.makeStyle_(inlineStyle);
276
277 for (var name in styleAttributes) {
278 if (this.attributesMap_[name]) {
279 this.attributesMap_[name].style =
280 this.makeStyle_(styleAttributes[name]);
281 }
282 }
283
284 this.matchedCSSRules_ = [];
285 for (var i = 0; i < matchedCSSRules.length; i++) {
286 var descr = matchedCSSRules[i];
287
288 var rule = {};
289 rule.selectorText = descr['selector'];
290 rule.style = this.makeStyle_(descr['style']);
291
292 if (descr['parentStyleSheet']) {
293 var parentStyleMock = {};
294 parentStyleMock.href = descr['parentStyleSheet']['href'];
295 var nodeName = descr['parentStyleSheet']['ownerNodeName'];
296 if (nodeName) {
297 parentStyleMock.ownerNode = {
298 'nodeName': nodeName
299 };
300 }
301 rule.parentStyleSheet = parentStyleMock;
302 }
303 this.matchedCSSRules_.push(rule);
304 }
305 };
306
307
308 /**
309 * Creates a style declaration.
310 * @param {payload} payload
311 * @return {devtools.CSSStyleDeclaration:undefined}
312 * @see devtools.CSSStyleDeclaration
313 */
314 devtools.DomNode.prototype.makeStyle_ = function(payload) {
315 var style = new devtools.CSSStyleDeclaration(payload);
316 style.nodeId_ = this.id_;
317 return style;
318 };
319
320
321 /**
322 * Remove references to the style information to release
323 * resources when styles are not going to be used.
324 * @see setStyles.
325 */
326 devtools.DomNode.prototype.clearStyles = function() {
327 this.computedStyle = null;
328 this.style = null;
329 for (var name in this.attributesMap_) {
330 this.attributesMap_[name].style = null;
331 }
332 this.matchedCSSRules_ = null;
333 };
334
335
336 /**
337 * Remote Dom document abstraction.
338 * @param {devtools.DomAgent} domAgent owner agent.
339 * @param {devtools.DomWindow} defaultView owner window.
340 * @constructor.
341 */
342 devtools.DomDocument = function(domAgent, defaultView) {
343 devtools.DomNode.call(this, null,
344 [
345 0, // id
346 9, // type = Node.DOCUMENT_NODE,
347 '', // nodeName
348 '', // nodeValue
349 [], // attributes
350 0, // childNodeCount
351 ]);
352 this.listeners_ = {};
353 this.domAgent_ = domAgent;
354 this.defaultView = defaultView;
355 };
356 goog.inherits(devtools.DomDocument, devtools.DomNode);
357
358
359 /**
360 * Adds event listener to the Dom.
361 * @param {string} name Event name.
362 * @param {function(Event):undefined} callback Listener callback.
363 * @param {bool} useCapture Listener's useCapture settings.
364 */
365 devtools.DomDocument.prototype.addEventListener =
366 function(name, callback, useCapture) {
367 var listeners = this.listeners_[name];
368 if (!listeners) {
369 listeners = [];
370 this.listeners_[name] = listeners;
371 }
372 listeners.push(callback);
373 };
374
375
376 /**
377 * Removes event listener from the Dom.
378 * @param {string} name Event name.
379 * @param {function(Event):undefined} callback Listener callback.
380 * @param {bool} useCapture Listener's useCapture settings.
381 */
382 devtools.DomDocument.prototype.removeEventListener =
383 function(name, callback, useCapture) {
384 var listeners = this.listeners_[name];
385 if (!listeners) {
386 return;
387 }
388 var index = listeners.indexOf(callback);
389 if (index != -1) {
390 listeners.splice(index, 1);
391 }
392 };
393
394
395 /**
396 * Fires Dom event to the listeners for given event type.
397 * @param {string} name Event type.
398 * @param {Event} event Event to fire.
399 * @private
400 */
401 devtools.DomDocument.prototype.fireDomEvent_ = function(name, event) {
402 var listeners = this.listeners_[name];
403 if (!listeners) {
404 return;
405 }
406 for (var i = 0; i < listeners.length; ++i) {
407 listeners[i](event);
408 }
409 };
410
411
412
413 /**
414 * Simulation of inspected DOMWindow.
415 * @param {devtools.DomAgent} domAgent owner agent.
416 * @constructor
417 */
418 devtools.DomWindow = function(domAgent) {
419 this.document = new devtools.DomDocument(domAgent, this);
420 };
421
422 /**
423 * Represents DOM Node class.
424 */
425 devtools.DomWindow.prototype.__defineGetter__('Node', function() {
426 return devtools.DomNode;
427 });
428
429 /**
430 * Represents DOM Element class.
431 * @constructor
432 */
433 devtools.DomWindow.prototype.__defineGetter__('Element', function() {
434 return devtools.DomNode;
435 });
436
437
438 /**
439 * See usages in ScopeChainSidebarPane.js where it's called as
440 * constructor.
441 */
442 devtools.DomWindow.prototype.Object = function() {
443 };
444
445
446 /**
447 * Simulates the DOM interface for styles.
448 * @param {devtools.DomNode} node
449 * @return {CSSStyleDescription}
450 */
451 devtools.DomWindow.prototype.getComputedStyle = function(node) {
452 return node.computedStyle_;
453 };
454
455
456 /**
457 * Simulates the DOM interface for styles.
458 * @param {devtools.DomNode} nodeStyles
459 * @param {string} pseudoElement assumed to be empty string.
460 * @param {boolean} authorOnly assumed to be equal to authorOnly argument of
461 * getNodeStylesAsync.
462 * @return {CSSStyleDescription}
463 */
464 devtools.DomWindow.prototype.getMatchedCSSRules = function(node,
465 pseudoElement, authorOnly) {
466 return node.matchedCSSRules_;
467 };
468
469
470 /**
471 * Creates DomAgent Js representation.
472 * @constructor
473 */
474 devtools.DomAgent = function() {
475 RemoteDomAgent.DidGetChildNodes =
476 devtools.Callback.processCallback;
477 RemoteDomAgent.DidPerformSearch =
478 devtools.Callback.processCallback;
479 RemoteDomAgent.DidApplyDomChange =
480 devtools.Callback.processCallback;
481 RemoteDomAgent.DidRemoveAttribute =
482 devtools.Callback.processCallback;
483 RemoteDomAgent.DidSetTextNodeValue =
484 devtools.Callback.processCallback;
485 RemoteDomAgent.AttributesUpdated =
486 goog.bind(this.attributesUpdated, this);
487 RemoteDomAgent.SetDocumentElement =
488 goog.bind(this.setDocumentElement, this);
489 RemoteDomAgent.SetChildNodes =
490 goog.bind(this.setChildNodes, this);
491 RemoteDomAgent.HasChildrenUpdated =
492 goog.bind(this.hasChildrenUpdated, this);
493 RemoteDomAgent.ChildNodeInserted =
494 goog.bind(this.childNodeInserted, this);
495 RemoteDomAgent.ChildNodeRemoved =
496 goog.bind(this.childNodeRemoved, this);
497
498 /**
499 * Top-level (and the only) document.
500 * @type {devtools.DomWindow}
501 * @private
502 */
503 this.window_ = null;
504
505 /**
506 * Id to node mapping.
507 * @type {Object}
508 * @private
509 */
510 this.idToDomNode_ = null;
511
512 /**
513 * @type {Array.<number>} Node ids for search results.
514 * @private
515 */
516 this.searchResults_ = null;
517 };
518
519
520 /**
521 * Resets dom agent to its initial state.
522 */
523 devtools.DomAgent.prototype.reset = function() {
524 this.window_ = new devtools.DomWindow(this);
525 this.idToDomNode_ = { 0 : this.getDocument() };
526 this.searchResults_ = [];
527 };
528
529
530 /**
531 * @return {devtools.DomWindow} Window for the top level (and the only) document .
532 */
533 devtools.DomAgent.prototype.getWindow = function() {
534 return this.window_;
535 };
536
537
538 /**
539 * @return {devtools.DomDocument} A document of the top level window.
540 */
541 devtools.DomAgent.prototype.getDocument = function() {
542 return this.window_.document;
543 };
544
545
546 /**
547 * Requests that the document element is sent from the agent.
548 */
549 devtools.DomAgent.prototype.getDocumentElementAsync = function() {
550 if (this.getDocument().documentElement) {
551 return;
552 }
553 RemoteDomAgent.GetDocumentElement();
554 };
555
556
557 /**
558 * Asynchronously fetches children from the element with given id.
559 * @param {devtools.DomNode} parent Element to get children for.
560 * @param {function(devtools.DomNode):undefined} opt_callback Callback with
561 * the result.
562 */
563 devtools.DomAgent.prototype.getChildNodesAsync = function(parent,
564 opt_callback) {
565 var children = parent.children;
566 if (children && opt_callback) {
567 opt_callback(children);
568 return;
569 }
570 var mycallback = function() {
571 if (opt_callback) {
572 opt_callback(parent.children);
573 }
574 };
575 var callId = devtools.Callback.wrap(mycallback);
576 RemoteDomAgent.GetChildNodes(callId, parent.id_);
577 };
578
579
580 /**
581 * Sends 'set attribute' command to the remote agent.
582 * @param {devtools.DomNode} node Node to change.
583 * @param {string} name Attribute name to set value for.
584 * @param {string} value Attribute value to set.
585 * @param {function():undefined} opt_callback Callback on success.
586 */
587 devtools.DomAgent.prototype.setAttributeAsync = function(node, name, value,
588 callback) {
589 var mycallback = goog.bind(this.didApplyDomChange_, this, node, callback);
590 RemoteDomAgent.SetAttribute(devtools.Callback.wrap(mycallback),
591 node.id_, name, value);
592 };
593
594
595 /**
596 * Sends 'remove attribute' command to the remote agent.
597 * @param {devtools.DomNode} node Node to change.
598 * @param {string} name Attribute name to set value for.
599 * @param {function():undefined} opt_callback Callback on success.
600 */
601 devtools.DomAgent.prototype.removeAttributeAsync = function(node, name,
602 callback) {
603 var mycallback = goog.bind(this.didApplyDomChange_, this, node, callback);
604 RemoteDomAgent.RemoveAttribute(devtools.Callback.wrap(mycallback),
605 node.id_, name);
606 };
607
608
609 /**
610 * Sends 'set text node value' command to the remote agent.
611 * @param {devtools.DomNode} node Node to change.
612 * @param {string} text Text value to set.
613 * @param {function():undefined} opt_callback Callback on success.
614 */
615 devtools.DomAgent.prototype.setTextNodeValueAsync = function(node, text,
616 callback) {
617 var mycallback = goog.bind(this.didApplyDomChange_, this, node, callback);
618 RemoteDomAgent.SetTextNodeValue(devtools.Callback.wrap(mycallback),
619 node.id_, text);
620 };
621
622
623 /**
624 * Universal callback wrapper for edit dom operations.
625 * @param {devtools.DomNode} node Node to apply local changes on.
626 * @param {Function} callback Post-operation call.
627 * @param {boolean} success True iff operation has completed successfully.
628 */
629 devtools.DomAgent.prototype.didApplyDomChange_ = function(node,
630 callback, success) {
631 if (!success) {
632 return;
633 }
634 callback();
635 var elem = WebInspector.panels.elements.treeOutline.findTreeElement(node);
636 if (elem) {
637 elem._updateTitle();
638 }
639 };
640
641
642 /**
643 * @see DomAgentDelegate.
644 * {@inheritDoc}.
645 */
646 devtools.DomAgent.prototype.attributesUpdated = function(nodeId, attrsArray) {
647 var node = this.idToDomNode_[nodeId];
648 node.setAttributesPayload_(attrsArray);
649 };
650
651
652 /**
653 * Returns node for id.
654 * @param {number} nodeId Id to get node for.
655 * @return {devtools.DomNode} Node with given id.
656 */
657 devtools.DomAgent.prototype.getNodeForId = function(nodeId) {
658 return this.idToDomNode_[nodeId];
659 };
660
661
662 /**
663 * @see DomAgentDelegate.
664 * {@inheritDoc}.
665 */
666 devtools.DomAgent.prototype.setDocumentElement = function(payload) {
667 var doc = this.getDocument();
668 if (doc.documentElement) {
669 this.reset();
670 doc = this.getDocument();
671 }
672 this.setChildNodes(0, [payload]);
673 doc.documentElement = doc.firstChild;
674 doc.documentElement.ownerDocument = doc;
675 WebInspector.panels.elements.reset();
676 };
677
678
679 /**
680 * @see DomAgentDelegate.
681 * {@inheritDoc}.
682 */
683 devtools.DomAgent.prototype.setChildNodes = function(parentId, payloads) {
684 var parent = this.idToDomNode_[parentId];
685 if (parent.children) {
686 return;
687 }
688 parent.setChildrenPayload_(payloads);
689 this.bindNodes_(parent.children);
690 };
691
692
693 /**
694 * Binds nodes to ids recursively.
695 * @param {Array.<devtools.DomNode>} children Nodes to bind.
696 */
697 devtools.DomAgent.prototype.bindNodes_ = function(children) {
698 for (var i = 0; i < children.length; ++i) {
699 var child = children[i];
700 this.idToDomNode_[child.id_] = child;
701 if (child.children) {
702 this.bindNodes_(child.children);
703 }
704 }
705 };
706
707
708 /**
709 * @see DomAgentDelegate.
710 * {@inheritDoc}.
711 */
712 devtools.DomAgent.prototype.hasChildrenUpdated = function(nodeId, newValue) {
713 var node = this.idToDomNode_[nodeId];
714 var outline = WebInspector.panels.elements.treeOutline;
715 var treeElement = outline.findTreeElement(node);
716 if (treeElement) {
717 treeElement.hasChildren = newValue;
718 treeElement.whitespaceIgnored = Preferences.ignoreWhitespace;
719 }
720 };
721
722
723 /**
724 * @see DomAgentDelegate.
725 * {@inheritDoc}.
726 */
727 devtools.DomAgent.prototype.childNodeInserted = function(
728 parentId, prevId, payload) {
729 var parent = this.idToDomNode_[parentId];
730 var prev = this.idToDomNode_[prevId];
731 var node = parent.insertChild_(prev, payload);
732 this.idToDomNode_[node.id_] = node;
733 var event = { target : node, relatedNode : parent };
734 this.getDocument().fireDomEvent_('DOMNodeInserted', event);
735 };
736
737
738 /**
739 * @see DomAgentDelegate.
740 * {@inheritDoc}.
741 */
742 devtools.DomAgent.prototype.childNodeRemoved = function(
743 parentId, nodeId) {
744 var parent = this.idToDomNode_[parentId];
745 var node = this.idToDomNode_[nodeId];
746 parent.removeChild_(node);
747 var event = { target : node, relatedNode : parent };
748 this.getDocument().fireDomEvent_('DOMNodeRemoved', event);
749 delete this.idToDomNode_[nodeId];
750 };
751
752
753 /**
754 * @see DomAgentDelegate.
755 * {@inheritDoc}.
756 */
757 devtools.DomAgent.prototype.performSearch = function(query, callback) {
758 this.searchResults_ = [];
759 RemoteDomAgent.PerformSearch(
760 devtools.Callback.wrap(
761 goog.bind(this.performSearchCallback_, this, callback,
762 this.searchResults_)),
763 query);
764 };
765
766
767 /**
768 * Invokes callback for nodes that needs to clear highlighting.
769 * @param {function(Array.<devtools.DomNode>)} callback to accept the result.
770 */
771 devtools.DomAgent.prototype.searchCanceled = function(callback) {
772 if (!this.searchResults_)
773 return;
774
775 var nodes = [];
776 for (var i = 0; i < this.searchResults_.length; ++i) {
777 var nodeId = this.searchResults_[i];
778 var node = this.idToDomNode_[nodeId];
779 nodes.push(node);
780 }
781
782 callback(nodes);
783 this.searchResults_ = null;
784 };
785
786
787 /**
788 * Invokes callback for each node that needs to gain highlighting.
789 * @param {function(Array.<devtools.DomNode>)} callback to accept the result.
790 * @param {Array.<number>} searchResults to be populated.
791 * @param {Array.<number>} nodeIds Ids to highlight.
792 */
793 devtools.DomAgent.prototype.performSearchCallback_ = function(callback,
794 searchResults, nodeIds) {
795
796 if (this.searchResults_ !== searchResults)
797 return; // another search has requested and this results are obsolete
798
799 var nodes = [];
800
801 for (var i = 0; i < nodeIds.length; ++i) {
802 var node = this.idToDomNode_[nodeIds[i]];
803 searchResults.push(nodeIds[i]);
804 nodes.push(node);
805 }
806
807 callback(nodes);
808 };
809
810
811 /**
812 * Returns a node by index from the actual search results
813 * (last performSearch).
814 * @param {number} index in the results.
815 * @return {devtools.DomNode}
816 */
817 devtools.DomAgent.prototype.getSearchResultNode = function(index) {
818 return this.idToDomNode_[this.searchResults_[index]];
819 };
820
821
822 /**
823 * Returns all properties of the given node.
824 * @param {number} nodeId Node to get properties for.
825 * @param {Array.<string>} path Path to the object.
826 * @param {number} protoDepth Depth to the exact proto level.
827 * @param {function(string):undefined} callback Function to call with the
828 * result.
829 */
830 devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId,
831 path, protoDepth, callback) {
832 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
833 RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
834 'getProperties', nodeId,
835 JSON.stringify([path, protoDepth]));
836 };
837
838
839 /**
840 * Returns prototype chain for a given node.
841 * @param {number} nodeId Node to get prototypes for.
842 * @param {Function} callback.
843 */
844 devtools.DomAgent.prototype.getNodePrototypesAsync = function(nodeId,
845 callback) {
846 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
847 RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
848 'getPrototypes', nodeId, '[]');
849 };
850
851
852 /**
853 * Returns styles for given node.
854 * @param {devtools.DomNode} node Node to get prototypes for.
855 * @param {boolean} authorOnly Returns only author styles if true.
856 * @param {Function} callback.
857 */
858 devtools.DomAgent.prototype.getNodeStylesAsync = function(node,
859 authorOnly, callback) {
860 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
861 RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
862 'getStyles',
863 node.id_,
864 JSON.stringify([authorOnly]));
865 };
866
867
868 /**
869 * Toggles style with given id on/off.
870 * @param {devtools.CSSStyleDeclaration} style Style to toggle.
871 * @param {boolean} enabled True if style should be enabled.
872 * @param {string} name Style name.
873 * @param {Function} callback.
874 */
875 devtools.DomAgent.prototype.toggleNodeStyleAsync = function(
876 style, enabled, name, callback) {
877 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
878 RemoteToolsAgent.ExecuteUtilityFunction(callbackId,
879 'toggleNodeStyle',
880 style.nodeId_,
881 JSON.stringify([style.id_, enabled, name]));
882 };
883
884
885 /**
886 * Applies new text to a style.
887 * @param {devtools.CSSStyleDeclaration} style Style to edit.
888 * @param {string} name Property name to edit.
889 * @param {string} styleText Text to set the style from.
890 * @param {Function} callback.
891 */
892 devtools.DomAgent.prototype.applyStyleTextAsync = function(
893 style, name, styleText, callback) {
894 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
895 RemoteToolsAgent.ExecuteUtilityFunction(
896 callbackId,
897 'applyStyleText',
898 style.nodeId_,
899 JSON.stringify([style.id_, name, styleText]));
900 };
901
902
903 /**
904 * Sets style property with given name to a value.
905 * @param {devtools.DomNode} node Node to edit style for.
906 * @param {string} name Property name to edit.
907 * @param {string} value New value.
908 * @param {Function} callback.
909 */
910 devtools.DomAgent.prototype.setStylePropertyAsync = function(
911 node, name, value, callback) {
912 var callbackId = this.utilityFunctionCallbackWrapper_(callback);
913 RemoteToolsAgent.ExecuteUtilityFunction(
914 callbackId,
915 'setStyleProperty',
916 node.id_,
917 JSON.stringify([name, value]));
918 };
919
920
921 /**
922 * Dumps exception if something went wrong in ExecuteUtilityFunction.
923 * @param {Function} callback Callback to wrap.
924 * @return {number} Callback id.
925 */
926 devtools.DomAgent.prototype.utilityFunctionCallbackWrapper_ =
927 function(callback) {
928 var mycallback = function(result, exception) {
929 if (exception && exception.length) {
930 debugPrint('Exception in ExecuteUtilityFunction styles:' + exception);
931 return;
932 }
933 callback(result);
934 };
935 return devtools.Callback.wrap(mycallback);
936 };
937
938
939 /**
940 * Represents remote CSSStyleDeclaration for using in StyleSidebarPane.
941 * @param {id, Array<Object>} payload built by inject's getStyle from the
942 * injected js.
943 * @constructor
944 */
945 devtools.CSSStyleDeclaration = function(payload) {
946 this.id_ = payload[0];
947 this.width = payload[1];
948 this.height = payload[2];
949 this.__disabledProperties = payload[3];
950 this.__disabledPropertyValues = payload[4];
951 this.__disabledPropertyPriorities = payload[5];
952
953 this.length = payload.length - 6;
954 this.priority_ = {};
955 this.implicit_ = {};
956 this.shorthand_ = {};
957 this.value_ = {};
958
959 for (var i = 6; i < payload.length; ++i) {
960 var p = payload[i];
961 var name = p[0];
962
963 this.priority_[name] = p[1];
964 this.implicit_[name] = p[2];
965 this.shorthand_[name] = p[3];
966 this.value_[name] = p[4];
967
968 this[i - 6] = name;
969 }
970 };
971
972
973 /**
974 * @param {string} name of a CSS property.
975 * @return {string}
976 */
977 devtools.CSSStyleDeclaration.prototype.getPropertyValue = function(name) {
978 return this.value_[name] || '';
979 };
980
981
982 /**
983 * @param {string} name of a CSS property.
984 * @return {string} 'important' | ''.
985 */
986 devtools.CSSStyleDeclaration.prototype.getPropertyPriority = function(name) {
987 return this.priority_[name] || '';
988 };
989
990
991 /**
992 * @param {string} name of a CSS property.
993 * @return {string} shorthand name or ''
994 */
995 devtools.CSSStyleDeclaration.prototype.getPropertyShorthand = function(name) {
996 return this.shorthand_[name] || '';
997 };
998
999
1000 /**
1001 * @param {string} name of a CSS property.
1002 * @return {boolean}
1003 */
1004 devtools.CSSStyleDeclaration.prototype.isPropertyImplicit = function(name) {
1005 return !!this.implicit_[name];
1006 };
1007
1008
1009 function firstChildSkippingWhitespace() {
1010 return this.firstChild;
1011 }
1012
1013
1014 function onlyTextChild() {
1015 if (!this.children) {
1016 return null;
1017 } else if (this.children.length == 1 &&
1018 this.children[0].nodeType == Node.TEXT_NODE) {
1019 return this.children[0];
1020 } else {
1021 return null;
1022 }
1023 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698