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

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

Issue 206313004: DevTools: Rename WebInspector.DOMAgent into WebInspector.DOMModel (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase on master Created 6 years, 9 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) 2009, 2010 Google Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /**
33 * @constructor
34 * @param {!WebInspector.DOMAgent} domAgent
35 * @param {?WebInspector.DOMDocument} doc
36 * @param {boolean} isInShadowTree
37 * @param {!DOMAgent.Node} payload
38 */
39 WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
40 this._domAgent = domAgent;
41 this.ownerDocument = doc;
42 this._isInShadowTree = isInShadowTree;
43
44 this.id = payload.nodeId;
45 domAgent._idToDOMNode[this.id] = this;
46 this._nodeType = payload.nodeType;
47 this._nodeName = payload.nodeName;
48 this._localName = payload.localName;
49 this._nodeValue = payload.nodeValue;
50 this._pseudoType = payload.pseudoType;
51 this._shadowRootType = payload.shadowRootType;
52 this._frameId = payload.frameId || null;
53
54 this._shadowRoots = [];
55
56 this._attributes = [];
57 this._attributesMap = {};
58 if (payload.attributes)
59 this._setAttributesPayload(payload.attributes);
60
61 this._userProperties = {};
62 this._descendantUserPropertyCounters = {};
63
64 this._childNodeCount = payload.childNodeCount || 0;
65 this._children = null;
66
67 this.nextSibling = null;
68 this.previousSibling = null;
69 this.firstChild = null;
70 this.lastChild = null;
71 this.parentNode = null;
72
73 if (payload.shadowRoots) {
74 for (var i = 0; i < payload.shadowRoots.length; ++i) {
75 var root = payload.shadowRoots[i];
76 var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocume nt, true, root);
77 this._shadowRoots.push(node);
78 node.parentNode = this;
79 }
80 }
81
82 if (payload.templateContent) {
83 this._templateContent = new WebInspector.DOMNode(this._domAgent, this.ow nerDocument, true, payload.templateContent);
84 this._templateContent.parentNode = this;
85 }
86
87 if (payload.importedDocument) {
88 this._importedDocument = new WebInspector.DOMNode(this._domAgent, this.o wnerDocument, true, payload.importedDocument);
89 this._importedDocument.parentNode = this;
90 }
91
92 if (payload.children)
93 this._setChildrenPayload(payload.children);
94
95 this._setPseudoElements(payload.pseudoElements);
96
97 if (payload.contentDocument) {
98 this._contentDocument = new WebInspector.DOMDocument(domAgent, payload.c ontentDocument);
99 this._children = [this._contentDocument];
100 this._renumber();
101 }
102
103 if (this._nodeType === Node.ELEMENT_NODE) {
104 // HTML and BODY from internal iframes should not overwrite top-level on es.
105 if (this.ownerDocument && !this.ownerDocument.documentElement && this._n odeName === "HTML")
106 this.ownerDocument.documentElement = this;
107 if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === "BODY")
108 this.ownerDocument.body = this;
109 } else if (this._nodeType === Node.DOCUMENT_TYPE_NODE) {
110 this.publicId = payload.publicId;
111 this.systemId = payload.systemId;
112 this.internalSubset = payload.internalSubset;
113 } else if (this._nodeType === Node.ATTRIBUTE_NODE) {
114 this.name = payload.name;
115 this.value = payload.value;
116 }
117 }
118
119 /**
120 * @enum {string}
121 */
122 WebInspector.DOMNode.PseudoElementNames = {
123 Before: "before",
124 After: "after"
125 }
126
127 /**
128 * @enum {string}
129 */
130 WebInspector.DOMNode.ShadowRootTypes = {
131 UserAgent: "user-agent",
132 Author: "author"
133 }
134
135 WebInspector.DOMNode.prototype = {
136 /**
137 * @return {?Array.<!WebInspector.DOMNode>}
138 */
139 children: function()
140 {
141 return this._children ? this._children.slice() : null;
142 },
143
144 /**
145 * @return {boolean}
146 */
147 hasAttributes: function()
148 {
149 return this._attributes.length > 0;
150 },
151
152 /**
153 * @return {number}
154 */
155 childNodeCount: function()
156 {
157 return this._childNodeCount;
158 },
159
160 /**
161 * @return {boolean}
162 */
163 hasShadowRoots: function()
164 {
165 return !!this._shadowRoots.length;
166 },
167
168 /**
169 * @return {!Array.<!WebInspector.DOMNode>}
170 */
171 shadowRoots: function()
172 {
173 return this._shadowRoots.slice();
174 },
175
176 /**
177 * @return {?WebInspector.DOMNode}
178 */
179 templateContent: function()
180 {
181 return this._templateContent;
182 },
183
184 /**
185 * @return {?WebInspector.DOMNode}
186 */
187 importedDocument: function()
188 {
189 return this._importedDocument;
190 },
191
192 /**
193 * @return {number}
194 */
195 nodeType: function()
196 {
197 return this._nodeType;
198 },
199
200 /**
201 * @return {string}
202 */
203 nodeName: function()
204 {
205 return this._nodeName;
206 },
207
208 /**
209 * @return {string|undefined}
210 */
211 pseudoType: function()
212 {
213 return this._pseudoType;
214 },
215
216 /**
217 * @return {boolean}
218 */
219 hasPseudoElements: function()
220 {
221 return Object.keys(this._pseudoElements).length !== 0;
222 },
223
224 /**
225 * @return {!Object.<string, !WebInspector.DOMNode>}
226 */
227 pseudoElements: function()
228 {
229 return this._pseudoElements;
230 },
231
232 /**
233 * @return {boolean}
234 */
235 isInShadowTree: function()
236 {
237 return this._isInShadowTree;
238 },
239
240 /**
241 * @return {?WebInspector.DOMNode}
242 */
243 ancestorUserAgentShadowRoot: function()
244 {
245 if (!this._isInShadowTree)
246 return null;
247
248 var current = this;
249 while (!current.isShadowRoot())
250 current = current.parentNode;
251 return current.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes .UserAgent ? current : null;
252 },
253
254 /**
255 * @return {boolean}
256 */
257 isShadowRoot: function()
258 {
259 return !!this._shadowRootType;
260 },
261
262 /**
263 * @return {?string}
264 */
265 shadowRootType: function()
266 {
267 return this._shadowRootType || null;
268 },
269
270 /**
271 * @return {string}
272 */
273 nodeNameInCorrectCase: function()
274 {
275 var shadowRootType = this.shadowRootType();
276 if (shadowRootType)
277 return "#shadow-root" + (shadowRootType === WebInspector.DOMNode.Sha dowRootTypes.UserAgent ? " (user-agent)" : "");
278 return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase( );
279 },
280
281 /**
282 * @param {string} name
283 * @param {function(?Protocol.Error)=} callback
284 */
285 setNodeName: function(name, callback)
286 {
287 DOMAgent.setNodeName(this.id, name, WebInspector.domAgent._markRevision( this, callback));
288 },
289
290 /**
291 * @return {string}
292 */
293 localName: function()
294 {
295 return this._localName;
296 },
297
298 /**
299 * @return {string}
300 */
301 nodeValue: function()
302 {
303 return this._nodeValue;
304 },
305
306 /**
307 * @param {string} value
308 * @param {function(?Protocol.Error)=} callback
309 */
310 setNodeValue: function(value, callback)
311 {
312 DOMAgent.setNodeValue(this.id, value, WebInspector.domAgent._markRevisio n(this, callback));
313 },
314
315 /**
316 * @param {string} name
317 * @return {string}
318 */
319 getAttribute: function(name)
320 {
321 var attr = this._attributesMap[name];
322 return attr ? attr.value : undefined;
323 },
324
325 /**
326 * @param {string} name
327 * @param {string} text
328 * @param {function(?Protocol.Error)=} callback
329 */
330 setAttribute: function(name, text, callback)
331 {
332 DOMAgent.setAttributesAsText(this.id, text, name, WebInspector.domAgent. _markRevision(this, callback));
333 },
334
335 /**
336 * @param {string} name
337 * @param {string} value
338 * @param {function(?Protocol.Error)=} callback
339 */
340 setAttributeValue: function(name, value, callback)
341 {
342 DOMAgent.setAttributeValue(this.id, name, value, WebInspector.domAgent._ markRevision(this, callback));
343 },
344
345 /**
346 * @return {!Object}
347 */
348 attributes: function()
349 {
350 return this._attributes;
351 },
352
353 /**
354 * @param {string} name
355 * @param {function(?Protocol.Error)=} callback
356 */
357 removeAttribute: function(name, callback)
358 {
359 /**
360 * @param {?Protocol.Error} error
361 * @this {WebInspector.DOMNode}
362 */
363 function mycallback(error)
364 {
365 if (!error) {
366 delete this._attributesMap[name];
367 for (var i = 0; i < this._attributes.length; ++i) {
368 if (this._attributes[i].name === name) {
369 this._attributes.splice(i, 1);
370 break;
371 }
372 }
373 }
374
375 WebInspector.domAgent._markRevision(this, callback)(error);
376 }
377 DOMAgent.removeAttribute(this.id, name, mycallback.bind(this));
378 },
379
380 /**
381 * @param {function(?Array.<!WebInspector.DOMNode>)=} callback
382 */
383 getChildNodes: function(callback)
384 {
385 if (this._children) {
386 if (callback)
387 callback(this.children());
388 return;
389 }
390
391 /**
392 * @this {WebInspector.DOMNode}
393 * @param {?Protocol.Error} error
394 */
395 function mycallback(error)
396 {
397 if (callback)
398 callback(error ? null : this.children());
399 }
400
401 DOMAgent.requestChildNodes(this.id, undefined, mycallback.bind(this));
402 },
403
404 /**
405 * @param {number} depth
406 * @param {function(?Array.<!WebInspector.DOMNode>)=} callback
407 */
408 getSubtree: function(depth, callback)
409 {
410 /**
411 * @this {WebInspector.DOMNode}
412 * @param {?Protocol.Error} error
413 */
414 function mycallback(error)
415 {
416 if (callback)
417 callback(error ? null : this._children);
418 }
419
420 DOMAgent.requestChildNodes(this.id, depth, mycallback.bind(this));
421 },
422
423 /**
424 * @param {function(?Protocol.Error)=} callback
425 */
426 getOuterHTML: function(callback)
427 {
428 DOMAgent.getOuterHTML(this.id, callback);
429 },
430
431 /**
432 * @param {string} html
433 * @param {function(?Protocol.Error)=} callback
434 */
435 setOuterHTML: function(html, callback)
436 {
437 DOMAgent.setOuterHTML(this.id, html, WebInspector.domAgent._markRevision (this, callback));
438 },
439
440 /**
441 * @param {function(?Protocol.Error, !DOMAgent.NodeId=)=} callback
442 */
443 removeNode: function(callback)
444 {
445 DOMAgent.removeNode(this.id, WebInspector.domAgent._markRevision(this, c allback));
446 },
447
448 copyNode: function()
449 {
450 function copy(error, text)
451 {
452 if (!error)
453 InspectorFrontendHost.copyText(text);
454 }
455 DOMAgent.getOuterHTML(this.id, copy);
456 },
457
458 /**
459 * @param {string} objectGroupId
460 * @param {function(?Protocol.Error)=} callback
461 */
462 eventListeners: function(objectGroupId, callback)
463 {
464 DOMAgent.getEventListenersForNode(this.id, objectGroupId, callback);
465 },
466
467 /**
468 * @return {string}
469 */
470 path: function()
471 {
472 /**
473 * @param {?WebInspector.DOMNode} node
474 */
475 function canPush(node)
476 {
477 return node && ("index" in node || (node.isShadowRoot() && node.pare ntNode)) && node._nodeName.length;
478 }
479
480 var path = [];
481 var node = this;
482 while (canPush(node)) {
483 var index = typeof node.index === "number" ? node.index : (node.shad owRootType() === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? "u" : "a");
484 path.push([index, node._nodeName]);
485 node = node.parentNode;
486 }
487 path.reverse();
488 return path.join(",");
489 },
490
491 /**
492 * @param {!WebInspector.DOMNode} node
493 * @return {boolean}
494 */
495 isAncestor: function(node)
496 {
497 if (!node)
498 return false;
499
500 var currentNode = node.parentNode;
501 while (currentNode) {
502 if (this === currentNode)
503 return true;
504 currentNode = currentNode.parentNode;
505 }
506 return false;
507 },
508
509 /**
510 * @param {!WebInspector.DOMNode} descendant
511 * @return {boolean}
512 */
513 isDescendant: function(descendant)
514 {
515 return descendant !== null && descendant.isAncestor(this);
516 },
517
518 /**
519 * @return {?PageAgent.FrameId}
520 */
521 frameId: function()
522 {
523 var node = this;
524 while (!node._frameId && node.parentNode)
525 node = node.parentNode;
526 return node._frameId;
527 },
528
529 /**
530 * @param {!Array.<string>} attrs
531 * @return {boolean}
532 */
533 _setAttributesPayload: function(attrs)
534 {
535 var attributesChanged = !this._attributes || attrs.length !== this._attr ibutes.length * 2;
536 var oldAttributesMap = this._attributesMap || {};
537
538 this._attributes = [];
539 this._attributesMap = {};
540
541 for (var i = 0; i < attrs.length; i += 2) {
542 var name = attrs[i];
543 var value = attrs[i + 1];
544 this._addAttribute(name, value);
545
546 if (attributesChanged)
547 continue;
548
549 if (!oldAttributesMap[name] || oldAttributesMap[name].value !== valu e)
550 attributesChanged = true;
551 }
552 return attributesChanged;
553 },
554
555 /**
556 * @param {!WebInspector.DOMNode} prev
557 * @param {!DOMAgent.Node} payload
558 * @return {!WebInspector.DOMNode}
559 */
560 _insertChild: function(prev, payload)
561 {
562 var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
563 this._children.splice(this._children.indexOf(prev) + 1, 0, node);
564 this._renumber();
565 return node;
566 },
567
568 /**
569 * @param {!WebInspector.DOMNode} node
570 */
571 _removeChild: function(node)
572 {
573 if (node.pseudoType()) {
574 delete this._pseudoElements[node.pseudoType()];
575 } else {
576 var shadowRootIndex = this._shadowRoots.indexOf(node);
577 if (shadowRootIndex !== -1)
578 this._shadowRoots.splice(shadowRootIndex, 1);
579 else
580 this._children.splice(this._children.indexOf(node), 1);
581 }
582 node.parentNode = null;
583 node._updateChildUserPropertyCountsOnRemoval(this);
584 this._renumber();
585 },
586
587 /**
588 * @param {!Array.<!DOMAgent.Node>} payloads
589 */
590 _setChildrenPayload: function(payloads)
591 {
592 // We set children in the constructor.
593 if (this._contentDocument)
594 return;
595
596 this._children = [];
597 for (var i = 0; i < payloads.length; ++i) {
598 var payload = payloads[i];
599 var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocume nt, this._isInShadowTree, payload);
600 this._children.push(node);
601 }
602 this._renumber();
603 },
604
605 /**
606 * @param {!Array.<!DOMAgent.Node>|undefined} payloads
607 */
608 _setPseudoElements: function(payloads)
609 {
610 this._pseudoElements = {};
611 if (!payloads)
612 return;
613
614 for (var i = 0; i < payloads.length; ++i) {
615 var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocume nt, this._isInShadowTree, payloads[i]);
616 node.parentNode = this;
617 this._pseudoElements[node.pseudoType()] = node;
618 }
619 },
620
621 _renumber: function()
622 {
623 this._childNodeCount = this._children.length;
624 if (this._childNodeCount == 0) {
625 this.firstChild = null;
626 this.lastChild = null;
627 return;
628 }
629 this.firstChild = this._children[0];
630 this.lastChild = this._children[this._childNodeCount - 1];
631 for (var i = 0; i < this._childNodeCount; ++i) {
632 var child = this._children[i];
633 child.index = i;
634 child.nextSibling = i + 1 < this._childNodeCount ? this._children[i + 1] : null;
635 child.previousSibling = i - 1 >= 0 ? this._children[i - 1] : null;
636 child.parentNode = this;
637 }
638 },
639
640 /**
641 * @param {string} name
642 * @param {string} value
643 */
644 _addAttribute: function(name, value)
645 {
646 var attr = {
647 name: name,
648 value: value,
649 _node: this
650 };
651 this._attributesMap[name] = attr;
652 this._attributes.push(attr);
653 },
654
655 /**
656 * @param {string} name
657 * @param {string} value
658 */
659 _setAttribute: function(name, value)
660 {
661 var attr = this._attributesMap[name];
662 if (attr)
663 attr.value = value;
664 else
665 this._addAttribute(name, value);
666 },
667
668 /**
669 * @param {string} name
670 */
671 _removeAttribute: function(name)
672 {
673 var attr = this._attributesMap[name];
674 if (attr) {
675 this._attributes.remove(attr);
676 delete this._attributesMap[name];
677 }
678 },
679
680 /**
681 * @param {!WebInspector.DOMNode} targetNode
682 * @param {?WebInspector.DOMNode} anchorNode
683 * @param {function(?Protocol.Error, !DOMAgent.NodeId=)=} callback
684 */
685 moveTo: function(targetNode, anchorNode, callback)
686 {
687 DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : und efined, WebInspector.domAgent._markRevision(this, callback));
688 },
689
690 /**
691 * @return {boolean}
692 */
693 isXMLNode: function()
694 {
695 return !!this.ownerDocument && !!this.ownerDocument.xmlVersion;
696 },
697
698 _updateChildUserPropertyCountsOnRemoval: function(parentNode)
699 {
700 var result = {};
701 if (this._userProperties) {
702 for (var name in this._userProperties)
703 result[name] = (result[name] || 0) + 1;
704 }
705
706 if (this._descendantUserPropertyCounters) {
707 for (var name in this._descendantUserPropertyCounters) {
708 var counter = this._descendantUserPropertyCounters[name];
709 result[name] = (result[name] || 0) + counter;
710 }
711 }
712
713 for (var name in result)
714 parentNode._updateDescendantUserPropertyCount(name, -result[name]);
715 },
716
717 _updateDescendantUserPropertyCount: function(name, delta)
718 {
719 if (!this._descendantUserPropertyCounters.hasOwnProperty(name))
720 this._descendantUserPropertyCounters[name] = 0;
721 this._descendantUserPropertyCounters[name] += delta;
722 if (!this._descendantUserPropertyCounters[name])
723 delete this._descendantUserPropertyCounters[name];
724 if (this.parentNode)
725 this.parentNode._updateDescendantUserPropertyCount(name, delta);
726 },
727
728 setUserProperty: function(name, value)
729 {
730 if (value === null) {
731 this.removeUserProperty(name);
732 return;
733 }
734
735 if (this.parentNode && !this._userProperties.hasOwnProperty(name))
736 this.parentNode._updateDescendantUserPropertyCount(name, 1);
737
738 this._userProperties[name] = value;
739 },
740
741 removeUserProperty: function(name)
742 {
743 if (!this._userProperties.hasOwnProperty(name))
744 return;
745
746 delete this._userProperties[name];
747 if (this.parentNode)
748 this.parentNode._updateDescendantUserPropertyCount(name, -1);
749 },
750
751 /**
752 * @param {string} name
753 * @return {?T}
754 * @template T
755 */
756 getUserProperty: function(name)
757 {
758 return (this._userProperties && this._userProperties[name]) || null;
759 },
760
761 /**
762 * @param {string} name
763 * @return {number}
764 */
765 descendantUserPropertyCount: function(name)
766 {
767 return this._descendantUserPropertyCounters && this._descendantUserPrope rtyCounters[name] ? this._descendantUserPropertyCounters[name] : 0;
768 },
769
770 /**
771 * @param {string} url
772 * @return {?string}
773 */
774 resolveURL: function(url)
775 {
776 if (!url)
777 return url;
778 for (var frameOwnerCandidate = this; frameOwnerCandidate; frameOwnerCand idate = frameOwnerCandidate.parentNode) {
779 if (frameOwnerCandidate.baseURL)
780 return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.ba seURL, url);
781 }
782 return null;
783 }
784 }
785
786 /**
787 * @extends {WebInspector.DOMNode}
788 * @constructor
789 * @param {!WebInspector.DOMAgent} domAgent
790 * @param {!DOMAgent.Node} payload
791 */
792 WebInspector.DOMDocument = function(domAgent, payload)
793 {
794 WebInspector.DOMNode.call(this, domAgent, this, false, payload);
795 this.documentURL = payload.documentURL || "";
796 this.baseURL = payload.baseURL || "";
797 this.xmlVersion = payload.xmlVersion;
798 this._listeners = {};
799 }
800
801 WebInspector.DOMDocument.prototype = {
802 __proto__: WebInspector.DOMNode.prototype
803 }
804
805 /**
806 * @extends {WebInspector.Object}
807 * @constructor
808 */
809 WebInspector.DOMAgent = function() {
810 /** @type {!Object.<number, !WebInspector.DOMNode>} */
811 this._idToDOMNode = {};
812 /** @type {?WebInspector.DOMDocument} */
813 this._document = null;
814 /** @type {!Object.<number, boolean>} */
815 this._attributeLoadNodeIds = {};
816 InspectorBackend.registerDOMDispatcher(new WebInspector.DOMDispatcher(this)) ;
817
818 this._defaultHighlighter = new WebInspector.DefaultDOMNodeHighlighter();
819 this._highlighter = this._defaultHighlighter;
820 }
821
822 WebInspector.DOMAgent.Events = {
823 AttrModified: "AttrModified",
824 AttrRemoved: "AttrRemoved",
825 CharacterDataModified: "CharacterDataModified",
826 NodeInserted: "NodeInserted",
827 NodeRemoved: "NodeRemoved",
828 DocumentUpdated: "DocumentUpdated",
829 ChildNodeCountUpdated: "ChildNodeCountUpdated",
830 UndoRedoRequested: "UndoRedoRequested",
831 UndoRedoCompleted: "UndoRedoCompleted",
832 }
833
834 WebInspector.DOMAgent.prototype = {
835 /**
836 * @param {function(!WebInspector.DOMDocument)=} callback
837 */
838 requestDocument: function(callback)
839 {
840 if (this._document) {
841 if (callback)
842 callback(this._document);
843 return;
844 }
845
846 if (this._pendingDocumentRequestCallbacks) {
847 this._pendingDocumentRequestCallbacks.push(callback);
848 return;
849 }
850
851 this._pendingDocumentRequestCallbacks = [callback];
852
853 /**
854 * @this {WebInspector.DOMAgent}
855 * @param {?Protocol.Error} error
856 * @param {!DOMAgent.Node} root
857 */
858 function onDocumentAvailable(error, root)
859 {
860 if (!error)
861 this._setDocument(root);
862
863 for (var i = 0; i < this._pendingDocumentRequestCallbacks.length; ++ i) {
864 var callback = this._pendingDocumentRequestCallbacks[i];
865 if (callback)
866 callback(this._document);
867 }
868 delete this._pendingDocumentRequestCallbacks;
869 }
870
871 DOMAgent.getDocument(onDocumentAvailable.bind(this));
872 },
873
874 /**
875 * @return {?WebInspector.DOMDocument}
876 */
877 existingDocument: function()
878 {
879 return this._document;
880 },
881
882 /**
883 * @param {!RuntimeAgent.RemoteObjectId} objectId
884 * @param {function(?DOMAgent.NodeId)=} callback
885 */
886 pushNodeToFrontend: function(objectId, callback)
887 {
888 this._dispatchWhenDocumentAvailable(DOMAgent.requestNode.bind(DOMAgent, objectId), callback);
889 },
890
891 /**
892 * @param {string} path
893 * @param {function(?number)=} callback
894 */
895 pushNodeByPathToFrontend: function(path, callback)
896 {
897 this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByPathToFrontend.bi nd(DOMAgent, path), callback);
898 },
899
900 /**
901 * @param {!Array.<number>} backendNodeIds
902 * @param {function(?Array.<number>)=} callback
903 */
904 pushNodesByBackendIdsToFrontend: function(backendNodeIds, callback)
905 {
906 this._dispatchWhenDocumentAvailable(DOMAgent.pushNodesByBackendIdsToFron tend.bind(DOMAgent, backendNodeIds), callback);
907 },
908
909 /**
910 * @param {function(!T)=} callback
911 * @return {function(?Protocol.Error, !T=)|undefined}
912 * @template T
913 */
914 _wrapClientCallback: function(callback)
915 {
916 if (!callback)
917 return;
918 /**
919 * @param {?Protocol.Error} error
920 * @param {!T=} result
921 * @template T
922 */
923 return function(error, result)
924 {
925 // Caller is responsible for handling the actual error.
926 callback(error ? null : result);
927 }
928 },
929
930 /**
931 * @param {function(function(?Protocol.Error, !T=)=)} func
932 * @param {function(!T)=} callback
933 * @template T
934 */
935 _dispatchWhenDocumentAvailable: function(func, callback)
936 {
937 var callbackWrapper = this._wrapClientCallback(callback);
938
939 /**
940 * @this {WebInspector.DOMAgent}
941 */
942 function onDocumentAvailable()
943 {
944 if (this._document)
945 func(callbackWrapper);
946 else {
947 if (callbackWrapper)
948 callbackWrapper("No document");
949 }
950 }
951 this.requestDocument(onDocumentAvailable.bind(this));
952 },
953
954 /**
955 * @param {!DOMAgent.NodeId} nodeId
956 * @param {string} name
957 * @param {string} value
958 */
959 _attributeModified: function(nodeId, name, value)
960 {
961 var node = this._idToDOMNode[nodeId];
962 if (!node)
963 return;
964
965 node._setAttribute(name, value);
966 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: name });
967 },
968
969 /**
970 * @param {!DOMAgent.NodeId} nodeId
971 * @param {string} name
972 */
973 _attributeRemoved: function(nodeId, name)
974 {
975 var node = this._idToDOMNode[nodeId];
976 if (!node)
977 return;
978 node._removeAttribute(name);
979 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrRemoved, { node: node, name: name });
980 },
981
982 /**
983 * @param {!Array.<!DOMAgent.NodeId>} nodeIds
984 */
985 _inlineStyleInvalidated: function(nodeIds)
986 {
987 for (var i = 0; i < nodeIds.length; ++i)
988 this._attributeLoadNodeIds[nodeIds[i]] = true;
989 if ("_loadNodeAttributesTimeout" in this)
990 return;
991 this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bi nd(this), 20);
992 },
993
994 _loadNodeAttributes: function()
995 {
996 /**
997 * @this {WebInspector.DOMAgent}
998 * @param {!DOMAgent.NodeId} nodeId
999 * @param {?Protocol.Error} error
1000 * @param {!Array.<string>} attributes
1001 */
1002 function callback(nodeId, error, attributes)
1003 {
1004 if (error) {
1005 // We are calling _loadNodeAttributes asynchronously, it is ok i f node is not found.
1006 return;
1007 }
1008 var node = this._idToDOMNode[nodeId];
1009 if (node) {
1010 if (node._setAttributesPayload(attributes))
1011 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.A ttrModified, { node: node, name: "style" });
1012 }
1013 }
1014
1015 delete this._loadNodeAttributesTimeout;
1016
1017 for (var nodeId in this._attributeLoadNodeIds) {
1018 var nodeIdAsNumber = parseInt(nodeId, 10);
1019 DOMAgent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsN umber));
1020 }
1021 this._attributeLoadNodeIds = {};
1022 },
1023
1024 /**
1025 * @param {!DOMAgent.NodeId} nodeId
1026 * @param {string} newValue
1027 */
1028 _characterDataModified: function(nodeId, newValue)
1029 {
1030 var node = this._idToDOMNode[nodeId];
1031 node._nodeValue = newValue;
1032 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.CharacterData Modified, node);
1033 },
1034
1035 /**
1036 * @param {!DOMAgent.NodeId} nodeId
1037 * @return {?WebInspector.DOMNode}
1038 */
1039 nodeForId: function(nodeId)
1040 {
1041 return this._idToDOMNode[nodeId] || null;
1042 },
1043
1044 _documentUpdated: function()
1045 {
1046 this._setDocument(null);
1047 },
1048
1049 /**
1050 * @param {?DOMAgent.Node} payload
1051 */
1052 _setDocument: function(payload)
1053 {
1054 this._idToDOMNode = {};
1055 if (payload && "nodeId" in payload)
1056 this._document = new WebInspector.DOMDocument(this, payload);
1057 else
1058 this._document = null;
1059 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.DocumentUpdat ed, this._document);
1060 },
1061
1062 /**
1063 * @param {!DOMAgent.Node} payload
1064 */
1065 _setDetachedRoot: function(payload)
1066 {
1067 if (payload.nodeName === "#document")
1068 new WebInspector.DOMDocument(this, payload);
1069 else
1070 new WebInspector.DOMNode(this, null, false, payload);
1071 },
1072
1073 /**
1074 * @param {!DOMAgent.NodeId} parentId
1075 * @param {!Array.<!DOMAgent.Node>} payloads
1076 */
1077 _setChildNodes: function(parentId, payloads)
1078 {
1079 if (!parentId && payloads.length) {
1080 this._setDetachedRoot(payloads[0]);
1081 return;
1082 }
1083
1084 var parent = this._idToDOMNode[parentId];
1085 parent._setChildrenPayload(payloads);
1086 },
1087
1088 /**
1089 * @param {!DOMAgent.NodeId} nodeId
1090 * @param {number} newValue
1091 */
1092 _childNodeCountUpdated: function(nodeId, newValue)
1093 {
1094 var node = this._idToDOMNode[nodeId];
1095 node._childNodeCount = newValue;
1096 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.ChildNodeCoun tUpdated, node);
1097 },
1098
1099 /**
1100 * @param {!DOMAgent.NodeId} parentId
1101 * @param {!DOMAgent.NodeId} prevId
1102 * @param {!DOMAgent.Node} payload
1103 */
1104 _childNodeInserted: function(parentId, prevId, payload)
1105 {
1106 var parent = this._idToDOMNode[parentId];
1107 var prev = this._idToDOMNode[prevId];
1108 var node = parent._insertChild(prev, payload);
1109 this._idToDOMNode[node.id] = node;
1110 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
1111 },
1112
1113 /**
1114 * @param {!DOMAgent.NodeId} parentId
1115 * @param {!DOMAgent.NodeId} nodeId
1116 */
1117 _childNodeRemoved: function(parentId, nodeId)
1118 {
1119 var parent = this._idToDOMNode[parentId];
1120 var node = this._idToDOMNode[nodeId];
1121 parent._removeChild(node);
1122 this._unbind(node);
1123 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: node, parent: parent});
1124 },
1125
1126 /**
1127 * @param {!DOMAgent.NodeId} hostId
1128 * @param {!DOMAgent.Node} root
1129 */
1130 _shadowRootPushed: function(hostId, root)
1131 {
1132 var host = this._idToDOMNode[hostId];
1133 if (!host)
1134 return;
1135 var node = new WebInspector.DOMNode(this, host.ownerDocument, true, root );
1136 node.parentNode = host;
1137 this._idToDOMNode[node.id] = node;
1138 host._shadowRoots.push(node);
1139 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
1140 },
1141
1142 /**
1143 * @param {!DOMAgent.NodeId} hostId
1144 * @param {!DOMAgent.NodeId} rootId
1145 */
1146 _shadowRootPopped: function(hostId, rootId)
1147 {
1148 var host = this._idToDOMNode[hostId];
1149 if (!host)
1150 return;
1151 var root = this._idToDOMNode[rootId];
1152 if (!root)
1153 return;
1154 host._removeChild(root);
1155 this._unbind(root);
1156 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: root, parent: host});
1157 },
1158
1159 /**
1160 * @param {!DOMAgent.NodeId} parentId
1161 * @param {!DOMAgent.Node} pseudoElement
1162 */
1163 _pseudoElementAdded: function(parentId, pseudoElement)
1164 {
1165 var parent = this._idToDOMNode[parentId];
1166 if (!parent)
1167 return;
1168 var node = new WebInspector.DOMNode(this, parent.ownerDocument, false, p seudoElement);
1169 node.parentNode = parent;
1170 this._idToDOMNode[node.id] = node;
1171 console.assert(!parent._pseudoElements[node.pseudoType()]);
1172 parent._pseudoElements[node.pseudoType()] = node;
1173 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
1174 },
1175
1176 /**
1177 * @param {!DOMAgent.NodeId} parentId
1178 * @param {!DOMAgent.NodeId} pseudoElementId
1179 */
1180 _pseudoElementRemoved: function(parentId, pseudoElementId)
1181 {
1182 var parent = this._idToDOMNode[parentId];
1183 if (!parent)
1184 return;
1185 var pseudoElement = this._idToDOMNode[pseudoElementId];
1186 if (!pseudoElement)
1187 return;
1188 parent._removeChild(pseudoElement);
1189 this._unbind(pseudoElement);
1190 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: pseudoElement, parent: parent});
1191 },
1192
1193 /**
1194 * @param {!WebInspector.DOMNode} node
1195 */
1196 _unbind: function(node)
1197 {
1198 delete this._idToDOMNode[node.id];
1199 for (var i = 0; node._children && i < node._children.length; ++i)
1200 this._unbind(node._children[i]);
1201 for (var i = 0; i < node._shadowRoots.length; ++i)
1202 this._unbind(node._shadowRoots[i]);
1203 var pseudoElements = node.pseudoElements();
1204 for (var id in pseudoElements)
1205 this._unbind(pseudoElements[id]);
1206 if (node._templateContent)
1207 this._unbind(node._templateContent);
1208 },
1209
1210 /**
1211 * @param {number} nodeId
1212 */
1213 inspectElement: function(nodeId)
1214 {
1215 WebInspector.Revealer.reveal(this.nodeForId(nodeId));
1216 },
1217
1218 /**
1219 * @param {!DOMAgent.NodeId} nodeId
1220 */
1221 _inspectNodeRequested: function(nodeId)
1222 {
1223 this.inspectElement(nodeId);
1224 },
1225
1226 /**
1227 * @param {string} query
1228 * @param {function(number)} searchCallback
1229 */
1230 performSearch: function(query, searchCallback)
1231 {
1232 this.cancelSearch();
1233
1234 /**
1235 * @param {?Protocol.Error} error
1236 * @param {string} searchId
1237 * @param {number} resultsCount
1238 * @this {WebInspector.DOMAgent}
1239 */
1240 function callback(error, searchId, resultsCount)
1241 {
1242 this._searchId = searchId;
1243 searchCallback(resultsCount);
1244 }
1245 DOMAgent.performSearch(query, callback.bind(this));
1246 },
1247
1248 /**
1249 * @param {number} index
1250 * @param {?function(?WebInspector.DOMNode)} callback
1251 */
1252 searchResult: function(index, callback)
1253 {
1254 if (this._searchId)
1255 DOMAgent.getSearchResults(this._searchId, index, index + 1, searchRe sultsCallback.bind(this));
1256 else
1257 callback(null);
1258
1259 /**
1260 * @param {?Protocol.Error} error
1261 * @param {!Array.<number>} nodeIds
1262 * @this {WebInspector.DOMAgent}
1263 */
1264 function searchResultsCallback(error, nodeIds)
1265 {
1266 if (error) {
1267 console.error(error);
1268 callback(null);
1269 return;
1270 }
1271 if (nodeIds.length != 1)
1272 return;
1273
1274 callback(this.nodeForId(nodeIds[0]));
1275 }
1276 },
1277
1278 cancelSearch: function()
1279 {
1280 if (this._searchId) {
1281 DOMAgent.discardSearchResults(this._searchId);
1282 delete this._searchId;
1283 }
1284 },
1285
1286 /**
1287 * @param {!DOMAgent.NodeId} nodeId
1288 * @param {string} selectors
1289 * @param {function(?DOMAgent.NodeId)=} callback
1290 */
1291 querySelector: function(nodeId, selectors, callback)
1292 {
1293 DOMAgent.querySelector(nodeId, selectors, this._wrapClientCallback(callb ack));
1294 },
1295
1296 /**
1297 * @param {!DOMAgent.NodeId} nodeId
1298 * @param {string} selectors
1299 * @param {function(!Array.<!DOMAgent.NodeId>=)=} callback
1300 */
1301 querySelectorAll: function(nodeId, selectors, callback)
1302 {
1303 DOMAgent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(ca llback));
1304 },
1305
1306 /**
1307 * @param {!DOMAgent.NodeId=} nodeId
1308 * @param {string=} mode
1309 * @param {!RuntimeAgent.RemoteObjectId=} objectId
1310 */
1311 highlightDOMNode: function(nodeId, mode, objectId)
1312 {
1313 if (this._hideDOMNodeHighlightTimeout) {
1314 clearTimeout(this._hideDOMNodeHighlightTimeout);
1315 delete this._hideDOMNodeHighlightTimeout;
1316 }
1317 this._highlighter.highlightDOMNode(nodeId || 0, this._buildHighlightConf ig(mode), objectId);
1318 },
1319
1320 hideDOMNodeHighlight: function()
1321 {
1322 this.highlightDOMNode(0);
1323 },
1324
1325 /**
1326 * @param {!DOMAgent.NodeId} nodeId
1327 */
1328 highlightDOMNodeForTwoSeconds: function(nodeId)
1329 {
1330 this.highlightDOMNode(nodeId);
1331 this._hideDOMNodeHighlightTimeout = setTimeout(this.hideDOMNodeHighlight .bind(this), 2000);
1332 },
1333
1334 /**
1335 * @param {boolean} enabled
1336 * @param {boolean} inspectUAShadowDOM
1337 * @param {function(?Protocol.Error)=} callback
1338 */
1339 setInspectModeEnabled: function(enabled, inspectUAShadowDOM, callback)
1340 {
1341 /**
1342 * @this {WebInspector.DOMAgent}
1343 */
1344 function onDocumentAvailable()
1345 {
1346 this._highlighter.setInspectModeEnabled(enabled, inspectUAShadowDOM, this._buildHighlightConfig(), callback);
1347 }
1348 this.requestDocument(onDocumentAvailable.bind(this));
1349 },
1350
1351 /**
1352 * @param {string=} mode
1353 * @return {!DOMAgent.HighlightConfig}
1354 */
1355 _buildHighlightConfig: function(mode)
1356 {
1357 mode = mode || "all";
1358 var highlightConfig = { showInfo: mode === "all", showRulers: WebInspect or.settings.showMetricsRulers.get() };
1359 if (mode === "all" || mode === "content")
1360 highlightConfig.contentColor = WebInspector.Color.PageHighlight.Cont ent.toProtocolRGBA();
1361
1362 if (mode === "all" || mode === "padding")
1363 highlightConfig.paddingColor = WebInspector.Color.PageHighlight.Padd ing.toProtocolRGBA();
1364
1365 if (mode === "all" || mode === "border")
1366 highlightConfig.borderColor = WebInspector.Color.PageHighlight.Borde r.toProtocolRGBA();
1367
1368 if (mode === "all" || mode === "margin")
1369 highlightConfig.marginColor = WebInspector.Color.PageHighlight.Margi n.toProtocolRGBA();
1370
1371 if (mode === "all")
1372 highlightConfig.eventTargetColor = WebInspector.Color.PageHighlight. EventTarget.toProtocolRGBA();
1373
1374 return highlightConfig;
1375 },
1376
1377 /**
1378 * @param {!WebInspector.DOMNode} node
1379 * @param {function(?Protocol.Error, !A=, !B=)=} callback
1380 * @return {function(?Protocol.Error, !A=, !B=)}
1381 * @template A,B
1382 */
1383 _markRevision: function(node, callback)
1384 {
1385 /**
1386 * @param {?Protocol.Error} error
1387 * @this {WebInspector.DOMAgent}
1388 */
1389 function wrapperFunction(error)
1390 {
1391 if (!error)
1392 this.markUndoableState();
1393
1394 if (callback)
1395 callback.apply(this, arguments);
1396 }
1397 return wrapperFunction.bind(this);
1398 },
1399
1400 /**
1401 * @param {boolean} emulationEnabled
1402 */
1403 emulateTouchEventObjects: function(emulationEnabled)
1404 {
1405 const injectedFunction = function() {
1406 const touchEvents = ["ontouchstart", "ontouchend", "ontouchmove", "o ntouchcancel"];
1407 var recepients = [window.__proto__, document.__proto__];
1408 for (var i = 0; i < touchEvents.length; ++i) {
1409 for (var j = 0; j < recepients.length; ++j) {
1410 if (!(touchEvents[i] in recepients[j]))
1411 Object.defineProperty(recepients[j], touchEvents[i], { v alue: null, writable: true, configurable: true, enumerable: true });
1412 }
1413 }
1414 }
1415
1416 if (emulationEnabled && !this._addTouchEventsScriptInjecting) {
1417 this._addTouchEventsScriptInjecting = true;
1418 PageAgent.addScriptToEvaluateOnLoad("(" + injectedFunction.toString( ) + ")()", scriptAddedCallback.bind(this));
1419 } else {
1420 if (typeof this._addTouchEventsScriptId !== "undefined") {
1421 PageAgent.removeScriptToEvaluateOnLoad(this._addTouchEventsScrip tId);
1422 delete this._addTouchEventsScriptId;
1423 }
1424 }
1425
1426 /**
1427 * @param {?Protocol.Error} error
1428 * @param {string} scriptId
1429 * @this {WebInspector.DOMAgent}
1430 */
1431 function scriptAddedCallback(error, scriptId)
1432 {
1433 delete this._addTouchEventsScriptInjecting;
1434 if (error)
1435 return;
1436 this._addTouchEventsScriptId = scriptId;
1437 }
1438
1439 PageAgent.setTouchEmulationEnabled(emulationEnabled);
1440 },
1441
1442 markUndoableState: function()
1443 {
1444 DOMAgent.markUndoableState();
1445 },
1446
1447 /**
1448 * @param {function(?Protocol.Error)=} callback
1449 */
1450 undo: function(callback)
1451 {
1452 /**
1453 * @param {?Protocol.Error} error
1454 * @this {WebInspector.DOMAgent}
1455 */
1456 function mycallback(error)
1457 {
1458 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoC ompleted);
1459 callback(error);
1460 }
1461
1462 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoReque sted);
1463 DOMAgent.undo(callback);
1464 },
1465
1466 /**
1467 * @param {function(?Protocol.Error)=} callback
1468 */
1469 redo: function(callback)
1470 {
1471 /**
1472 * @param {?Protocol.Error} error
1473 * @this {WebInspector.DOMAgent}
1474 */
1475 function mycallback(error)
1476 {
1477 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoC ompleted);
1478 callback(error);
1479 }
1480
1481 this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoReque sted);
1482 DOMAgent.redo(callback);
1483 },
1484
1485 /**
1486 * @param {?WebInspector.DOMNodeHighlighter} highlighter
1487 */
1488 setHighlighter: function(highlighter)
1489 {
1490 this._highlighter = highlighter || this._defaultHighlighter;
1491 },
1492
1493 __proto__: WebInspector.Object.prototype
1494 }
1495
1496 /**
1497 * @constructor
1498 * @implements {DOMAgent.Dispatcher}
1499 * @param {!WebInspector.DOMAgent} domAgent
1500 */
1501 WebInspector.DOMDispatcher = function(domAgent)
1502 {
1503 this._domAgent = domAgent;
1504 }
1505
1506 WebInspector.DOMDispatcher.prototype = {
1507 documentUpdated: function()
1508 {
1509 this._domAgent._documentUpdated();
1510 },
1511
1512 /**
1513 * @param {!DOMAgent.NodeId} nodeId
1514 */
1515 inspectNodeRequested: function(nodeId)
1516 {
1517 this._domAgent._inspectNodeRequested(nodeId);
1518 },
1519
1520 /**
1521 * @param {!DOMAgent.NodeId} nodeId
1522 * @param {string} name
1523 * @param {string} value
1524 */
1525 attributeModified: function(nodeId, name, value)
1526 {
1527 this._domAgent._attributeModified(nodeId, name, value);
1528 },
1529
1530 /**
1531 * @param {!DOMAgent.NodeId} nodeId
1532 * @param {string} name
1533 */
1534 attributeRemoved: function(nodeId, name)
1535 {
1536 this._domAgent._attributeRemoved(nodeId, name);
1537 },
1538
1539 /**
1540 * @param {!Array.<!DOMAgent.NodeId>} nodeIds
1541 */
1542 inlineStyleInvalidated: function(nodeIds)
1543 {
1544 this._domAgent._inlineStyleInvalidated(nodeIds);
1545 },
1546
1547 /**
1548 * @param {!DOMAgent.NodeId} nodeId
1549 * @param {string} characterData
1550 */
1551 characterDataModified: function(nodeId, characterData)
1552 {
1553 this._domAgent._characterDataModified(nodeId, characterData);
1554 },
1555
1556 /**
1557 * @param {!DOMAgent.NodeId} parentId
1558 * @param {!Array.<!DOMAgent.Node>} payloads
1559 */
1560 setChildNodes: function(parentId, payloads)
1561 {
1562 this._domAgent._setChildNodes(parentId, payloads);
1563 },
1564
1565 /**
1566 * @param {!DOMAgent.NodeId} nodeId
1567 * @param {number} childNodeCount
1568 */
1569 childNodeCountUpdated: function(nodeId, childNodeCount)
1570 {
1571 this._domAgent._childNodeCountUpdated(nodeId, childNodeCount);
1572 },
1573
1574 /**
1575 * @param {!DOMAgent.NodeId} parentNodeId
1576 * @param {!DOMAgent.NodeId} previousNodeId
1577 * @param {!DOMAgent.Node} payload
1578 */
1579 childNodeInserted: function(parentNodeId, previousNodeId, payload)
1580 {
1581 this._domAgent._childNodeInserted(parentNodeId, previousNodeId, payload) ;
1582 },
1583
1584 /**
1585 * @param {!DOMAgent.NodeId} parentNodeId
1586 * @param {!DOMAgent.NodeId} nodeId
1587 */
1588 childNodeRemoved: function(parentNodeId, nodeId)
1589 {
1590 this._domAgent._childNodeRemoved(parentNodeId, nodeId);
1591 },
1592
1593 /**
1594 * @param {!DOMAgent.NodeId} hostId
1595 * @param {!DOMAgent.Node} root
1596 */
1597 shadowRootPushed: function(hostId, root)
1598 {
1599 this._domAgent._shadowRootPushed(hostId, root);
1600 },
1601
1602 /**
1603 * @param {!DOMAgent.NodeId} hostId
1604 * @param {!DOMAgent.NodeId} rootId
1605 */
1606 shadowRootPopped: function(hostId, rootId)
1607 {
1608 this._domAgent._shadowRootPopped(hostId, rootId);
1609 },
1610
1611 /**
1612 * @param {!DOMAgent.NodeId} parentId
1613 * @param {!DOMAgent.Node} pseudoElement
1614 */
1615 pseudoElementAdded: function(parentId, pseudoElement)
1616 {
1617 this._domAgent._pseudoElementAdded(parentId, pseudoElement);
1618 },
1619
1620 /**
1621 * @param {!DOMAgent.NodeId} parentId
1622 * @param {!DOMAgent.NodeId} pseudoElementId
1623 */
1624 pseudoElementRemoved: function(parentId, pseudoElementId)
1625 {
1626 this._domAgent._pseudoElementRemoved(parentId, pseudoElementId);
1627 }
1628 }
1629
1630 /**
1631 * @interface
1632 */
1633 WebInspector.DOMNodeHighlighter = function() {
1634 }
1635
1636 WebInspector.DOMNodeHighlighter.prototype = {
1637 /**
1638 * @param {!DOMAgent.NodeId} nodeId
1639 * @param {!DOMAgent.HighlightConfig} config
1640 * @param {!RuntimeAgent.RemoteObjectId=} objectId
1641 */
1642 highlightDOMNode: function(nodeId, config, objectId) {},
1643
1644 /**
1645 * @param {boolean} enabled
1646 * @param {boolean} inspectUAShadowDOM
1647 * @param {!DOMAgent.HighlightConfig} config
1648 * @param {function(?Protocol.Error)=} callback
1649 */
1650 setInspectModeEnabled: function(enabled, inspectUAShadowDOM, config, callbac k) {}
1651 }
1652
1653 /**
1654 * @constructor
1655 * @implements {WebInspector.DOMNodeHighlighter}
1656 */
1657 WebInspector.DefaultDOMNodeHighlighter = function() {
1658 }
1659
1660 WebInspector.DefaultDOMNodeHighlighter.prototype = {
1661 /**
1662 * @param {!DOMAgent.NodeId} nodeId
1663 * @param {!DOMAgent.HighlightConfig} config
1664 * @param {!RuntimeAgent.RemoteObjectId=} objectId
1665 */
1666 highlightDOMNode: function(nodeId, config, objectId)
1667 {
1668 if (objectId || nodeId)
1669 DOMAgent.highlightNode(config, objectId ? undefined : nodeId, object Id);
1670 else
1671 DOMAgent.hideHighlight();
1672 },
1673
1674 /**
1675 * @param {boolean} enabled
1676 * @param {boolean} inspectUAShadowDOM
1677 * @param {!DOMAgent.HighlightConfig} config
1678 * @param {function(?Protocol.Error)=} callback
1679 */
1680 setInspectModeEnabled: function(enabled, inspectUAShadowDOM, config, callbac k)
1681 {
1682 DOMAgent.setInspectModeEnabled(enabled, inspectUAShadowDOM, config, call back);
1683 }
1684 }
1685
1686 /**
1687 * @type {!WebInspector.DOMAgent}
1688 */
1689 WebInspector.domAgent;
OLDNEW
« no previous file with comments | « Source/devtools/front_end/ConsoleViewMessage.js ('k') | Source/devtools/front_end/DOMBreakpointsSidebarPane.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698