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

Side by Side Diff: Source/devtools/front_end/elements/ElementsTreeOutline.js

Issue 701153002: DevTools: [Elements] Highlight DOM updates (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix tests (for ETO not wired to DOMModel) Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4 * Copyright (C) 2009 Joseph Pecoraro 4 * Copyright (C) 2009 Joseph Pecoraro
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 "html", "head", "body" 1046 "html", "head", "body"
1047 ].keySet(); 1047 ].keySet();
1048 1048
1049 /** @enum {number} */ 1049 /** @enum {number} */
1050 WebInspector.ElementsTreeElement.ChildrenDisplayMode = { 1050 WebInspector.ElementsTreeElement.ChildrenDisplayMode = {
1051 NoChildren: 0, 1051 NoChildren: 0,
1052 InlineText: 1, 1052 InlineText: 1,
1053 HasChildren: 2 1053 HasChildren: 2
1054 } 1054 }
1055 1055
1056 /**
1057 * @param {!WebInspector.ElementsTreeElement} treeElement
1058 */
1059 WebInspector.ElementsTreeElement.animateOnDOMUpdate = function(treeElement)
1060 {
1061 var tagName = treeElement.listItemElement.querySelector(".webkit-html-tag-na me");
1062 WebInspector.runCSSAnimationOnce(tagName || treeElement.listItemElement, "do m-update-highlight");
1063 }
1064
1056 WebInspector.ElementsTreeElement.prototype = { 1065 WebInspector.ElementsTreeElement.prototype = {
1057 /** 1066 /**
1058 * @return {!WebInspector.DOMNode} 1067 * @return {!WebInspector.DOMNode}
1059 */ 1068 */
1060 node: function() 1069 node: function()
1061 { 1070 {
1062 return this._node; 1071 return this._node;
1063 }, 1072 },
1064 1073
1065 /** 1074 /**
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 moveChild: function(child, targetIndex) 1298 moveChild: function(child, targetIndex)
1290 { 1299 {
1291 var wasSelected = child.selected; 1300 var wasSelected = child.selected;
1292 this.removeChild(child); 1301 this.removeChild(child);
1293 this.insertChild(child, targetIndex); 1302 this.insertChild(child, targetIndex);
1294 if (wasSelected) 1303 if (wasSelected)
1295 child.select(); 1304 child.select();
1296 }, 1305 },
1297 1306
1298 /** 1307 /**
1308 * @param {!WebInspector.DOMNode=} node
1309 * @return {!WebInspector.ElementsTreeUpdater.UpdateInfo|undefined}
1310 */
1311 _updateInfo: function(node)
1312 {
1313 if (!WebInspector.settings.highlightDOMUpdates.get())
1314 return undefined;
1315 var updater = this.treeOutline._elementsTreeUpdater;
1316 if (!updater)
1317 return undefined;
1318 var effectiveNode = node || this._node;
1319 return updater._recentlyModifiedNodes.get(effectiveNode) || updater._rec entlyModifiedParentNodes.get(effectiveNode);
1320 },
1321
1322 /**
1299 * @param {boolean} fullRefresh 1323 * @param {boolean} fullRefresh
1300 * @param {?Array.<!WebInspector.DOMNode>} children 1324 * @param {?Array.<!WebInspector.DOMNode>} children
1301 */ 1325 */
1302 _updateChildren: function(fullRefresh, children) 1326 _updateChildren: function(fullRefresh, children)
1303 { 1327 {
1304 if (!children || this._updateChildrenInProgress || !this.treeOutline._vi sible) 1328 if (!children || this._updateChildrenInProgress || !this.treeOutline._vi sible)
1305 return; 1329 return;
1306 1330
1307 this._updateChildrenInProgress = true; 1331 this._updateChildrenInProgress = true;
1308 var selectedNode = this.treeOutline.selectedDOMNode(); 1332 var selectedNode = this.treeOutline.selectedDOMNode();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 var elementToSelect; 1365 var elementToSelect;
1342 var visibleChildren = this._visibleChildren(); 1366 var visibleChildren = this._visibleChildren();
1343 for (var i = 0; i < visibleChildren.length && i < this.expandedChildrenL imit; ++i) { 1367 for (var i = 0; i < visibleChildren.length && i < this.expandedChildrenL imit; ++i) {
1344 var child = visibleChildren[i]; 1368 var child = visibleChildren[i];
1345 if (existingTreeElements.has(child)) { 1369 if (existingTreeElements.has(child)) {
1346 // If an existing element was found, just move it. 1370 // If an existing element was found, just move it.
1347 this.moveChild(existingTreeElements.get(child), i); 1371 this.moveChild(existingTreeElements.get(child), i);
1348 } else { 1372 } else {
1349 // No existing element found, insert a new element. 1373 // No existing element found, insert a new element.
1350 var newElement = this.insertChildElement(child, i); 1374 var newElement = this.insertChildElement(child, i);
1375 var updateRecord = this._updateInfo();
1376 if (updateRecord)
1377 WebInspector.ElementsTreeElement.animateOnDOMUpdate(newEleme nt);
1351 if (child === selectedNode) 1378 if (child === selectedNode)
1352 elementToSelect = newElement; 1379 elementToSelect = newElement;
1353 // If a node was inserted in the middle of existing list dynamic ally we might need to increase the limit. 1380 // If a node was inserted in the middle of existing list dynamic ally we might need to increase the limit.
1354 if (this.expandedChildCount > this.expandedChildrenLimit) 1381 if (this.expandedChildCount > this.expandedChildrenLimit)
1355 this.expandedChildrenLimit++; 1382 this.expandedChildrenLimit++;
1356 } 1383 }
1357 } 1384 }
1358 1385
1359 this.updateTitle(); 1386 this.updateTitle();
1360 this._adjustCollapsedRange(); 1387 this._adjustCollapsedRange();
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 var hasText = (forceValue || value.length > 0); 2305 var hasText = (forceValue || value.length > 0);
2279 var attrSpanElement = parentElement.createChild("span", "webkit-html-att ribute"); 2306 var attrSpanElement = parentElement.createChild("span", "webkit-html-att ribute");
2280 var attrNameElement = attrSpanElement.createChild("span", "webkit-html-a ttribute-name"); 2307 var attrNameElement = attrSpanElement.createChild("span", "webkit-html-a ttribute-name");
2281 attrNameElement.textContent = name; 2308 attrNameElement.textContent = name;
2282 2309
2283 if (hasText) 2310 if (hasText)
2284 attrSpanElement.createTextChild("=\u200B\""); 2311 attrSpanElement.createTextChild("=\u200B\"");
2285 2312
2286 var attrValueElement = attrSpanElement.createChild("span", "webkit-html- attribute-value"); 2313 var attrValueElement = attrSpanElement.createChild("span", "webkit-html- attribute-value");
2287 2314
2315 var updates = this._updateInfo();
2316 if (updates && updates.isAttributeModified(name))
2317 WebInspector.runCSSAnimationOnce(hasText ? attrValueElement : attrNa meElement, "dom-update-highlight");
2318
2288 /** 2319 /**
2289 * @this {WebInspector.ElementsTreeElement} 2320 * @this {WebInspector.ElementsTreeElement}
2290 * @param {string} value 2321 * @param {string} value
2291 * @return {!Element} 2322 * @return {!Element}
2292 */ 2323 */
2293 function linkifyValue(value) 2324 function linkifyValue(value)
2294 { 2325 {
2295 var rewrittenHref = node.resolveURL(value); 2326 var rewrittenHref = node.resolveURL(value);
2296 if (rewrittenHref === null) { 2327 if (rewrittenHref === null) {
2297 var span = createElement("span"); 2328 var span = createElement("span");
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeE lement, linkify) 2380 _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeE lement, linkify)
2350 { 2381 {
2351 var node = this._node; 2382 var node = this._node;
2352 var classes = [ "webkit-html-tag" ]; 2383 var classes = [ "webkit-html-tag" ];
2353 if (isClosingTag && isDistinctTreeElement) 2384 if (isClosingTag && isDistinctTreeElement)
2354 classes.push("close"); 2385 classes.push("close");
2355 var tagElement = parentElement.createChild("span", classes.join(" ")); 2386 var tagElement = parentElement.createChild("span", classes.join(" "));
2356 tagElement.createTextChild("<"); 2387 tagElement.createTextChild("<");
2357 var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name"); 2388 var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
2358 tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName; 2389 tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
2359 if (!isClosingTag && node.hasAttributes()) { 2390 if (!isClosingTag) {
2360 var attributes = node.attributes(); 2391 if (node.hasAttributes()) {
2361 for (var i = 0; i < attributes.length; ++i) { 2392 var attributes = node.attributes();
2362 var attr = attributes[i]; 2393 for (var i = 0; i < attributes.length; ++i) {
2363 tagElement.createTextChild(" "); 2394 var attr = attributes[i];
2364 this._buildAttributeDOM(tagElement, attr.name, attr.value, false , node, linkify); 2395 tagElement.createTextChild(" ");
2396 this._buildAttributeDOM(tagElement, attr.name, attr.value, f alse, node, linkify);
2397 }
2365 } 2398 }
2399 var hasUpdates;
2400 var updates = this._updateInfo();
2401 if (updates) {
2402 hasUpdates |= updates.hasRemovedAttributes();
2403 var hasInlineText = this._childrenDisplayMode === WebInspector.E lementsTreeElement.ChildrenDisplayMode.InlineText;
2404
2405 hasUpdates |= (!hasInlineText || this.expanded) && updates.hasCh angedChildren();
2406
2407 // Highlight the tag name, as the inserted node is not visible ( either child of a collapsed tree element or empty inline text).
2408 hasUpdates |= !this.expanded && updates.hasInsertedNodes() && (! hasInlineText || this._node.firstChild.nodeValue().length === 0);
2409
2410 // Highlight the tag name, as the inline text node value has bee n cleared.
2411 // The respective empty node will be highlighted, but the highli ght will not be visible to the user.
2412 hasUpdates |= hasInlineText && (updates.isCharDataModified() || updates.hasChangedChildren()) && this._node.firstChild.nodeValue().length === 0;
2413 }
2414 if (hasUpdates)
2415 WebInspector.runCSSAnimationOnce(tagNameElement, "dom-update-hig hlight");
2366 } 2416 }
2417
2367 tagElement.createTextChild(">"); 2418 tagElement.createTextChild(">");
2368 parentElement.createTextChild("\u200B"); 2419 parentElement.createTextChild("\u200B");
2369 }, 2420 },
2370 2421
2371 /** 2422 /**
2372 * @param {string} text 2423 * @param {string} text
2373 * @return {!{text: string, entityRanges: !Array.<!WebInspector.SourceRange> }} 2424 * @return {!{text: string, entityRanges: !Array.<!WebInspector.SourceRange> }}
2374 */ 2425 */
2375 _convertWhitespaceToEntities: function(text) 2426 _convertWhitespaceToEntities: function(text)
2376 { 2427 {
2377 var result = ""; 2428 var result = "";
2378 var resultLength = 0;
2379 var lastIndexAfterEntity = 0; 2429 var lastIndexAfterEntity = 0;
2380 var entityRanges = []; 2430 var entityRanges = [];
2381 var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity; 2431 var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
2382 for (var i = 0, size = text.length; i < size; ++i) { 2432 for (var i = 0, size = text.length; i < size; ++i) {
2383 var char = text.charAt(i); 2433 var char = text.charAt(i);
2384 if (charToEntity[char]) { 2434 if (charToEntity[char]) {
2385 result += text.substring(lastIndexAfterEntity, i); 2435 result += text.substring(lastIndexAfterEntity, i);
2386 var entityValue = "&" + charToEntity[char] + ";"; 2436 var entityValue = "&" + charToEntity[char] + ";";
2387 entityRanges.push({offset: result.length, length: entityValue.le ngth}); 2437 entityRanges.push({offset: result.length, length: entityValue.le ngth});
2388 result += entityValue; 2438 result += entityValue;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2435 break; 2485 break;
2436 2486
2437 case WebInspector.ElementsTreeElement.ChildrenDisplayMode.Inline Text: 2487 case WebInspector.ElementsTreeElement.ChildrenDisplayMode.Inline Text:
2438 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node"); 2488 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node");
2439 var result = this._convertWhitespaceToEntities(node.firstChi ld.nodeValue()); 2489 var result = this._convertWhitespaceToEntities(node.firstChi ld.nodeValue());
2440 textNodeElement.textContent = result.text; 2490 textNodeElement.textContent = result.text;
2441 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value"); 2491 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
2442 info.titleDOM.createTextChild("\u200B"); 2492 info.titleDOM.createTextChild("\u200B");
2443 info.hasChildren = false; 2493 info.hasChildren = false;
2444 this._buildTagDOM(info.titleDOM, tagName, true, false); 2494 this._buildTagDOM(info.titleDOM, tagName, true, false);
2495 var updates = this._updateInfo();
2496 if (updates && (updates.hasInsertedNodes() || updates.hasCha ngedChildren()))
2497 WebInspector.runCSSAnimationOnce(textNodeElement, "dom-u pdate-highlight");
2498 updates = this._updateInfo(this._node.firstChild);
2499 if (updates && updates.isCharDataModified())
2500 WebInspector.runCSSAnimationOnce(textNodeElement, "dom-u pdate-highlight");
2445 break; 2501 break;
2446 2502
2447 case WebInspector.ElementsTreeElement.ChildrenDisplayMode.NoChil dren: 2503 case WebInspector.ElementsTreeElement.ChildrenDisplayMode.NoChil dren:
2448 if (this.treeOutline.isXMLMimeType || !WebInspector.Elements TreeElement.ForbiddenClosingTagElements[tagName]) 2504 if (this.treeOutline.isXMLMimeType || !WebInspector.Elements TreeElement.ForbiddenClosingTagElements[tagName])
2449 this._buildTagDOM(info.titleDOM, tagName, true, false); 2505 this._buildTagDOM(info.titleDOM, tagName, true, false);
2450 break; 2506 break;
2451 } 2507 }
2452 break; 2508 break;
2453 2509
2454 case Node.TEXT_NODE: 2510 case Node.TEXT_NODE:
2455 if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") { 2511 if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
2456 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-js-node"); 2512 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-js-node");
2457 newNode.textContent = node.nodeValue(); 2513 newNode.textContent = node.nodeValue();
2458 2514
2459 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntax Highlighter("text/javascript", true); 2515 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntax Highlighter("text/javascript", true);
2460 javascriptSyntaxHighlighter.syntaxHighlightNode(newNode); 2516 javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
2461 } else if (node.parentNode && node.parentNode.nodeName().toLower Case() === "style") { 2517 } else if (node.parentNode && node.parentNode.nodeName().toLower Case() === "style") {
2462 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-css-node"); 2518 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-css-node");
2463 newNode.textContent = node.nodeValue(); 2519 newNode.textContent = node.nodeValue();
2464 2520
2465 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlig hter("text/css", true); 2521 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlig hter("text/css", true);
2466 cssSyntaxHighlighter.syntaxHighlightNode(newNode); 2522 cssSyntaxHighlighter.syntaxHighlightNode(newNode);
2467 } else { 2523 } else {
2468 info.titleDOM.createTextChild("\""); 2524 info.titleDOM.createTextChild("\"");
2469 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node"); 2525 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node");
2470 var result = this._convertWhitespaceToEntities(node.nodeValu e()); 2526 var result = this._convertWhitespaceToEntities(node.nodeValu e());
2471 textNodeElement.textContent = result.text; 2527 textNodeElement.textContent = result.text;
2472 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value"); 2528 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
2473 info.titleDOM.createTextChild("\""); 2529 info.titleDOM.createTextChild("\"");
2530 var updates = this._updateInfo();
2531 if (updates && updates.isCharDataModified())
2532 WebInspector.runCSSAnimationOnce(textNodeElement, "dom-u pdate-highlight");
2474 } 2533 }
2475 break; 2534 break;
2476 2535
2477 case Node.COMMENT_NODE: 2536 case Node.COMMENT_NODE:
2478 var commentElement = info.titleDOM.createChild("span", "webkit-h tml-comment"); 2537 var commentElement = info.titleDOM.createChild("span", "webkit-h tml-comment");
2479 commentElement.createTextChild("<!--" + node.nodeValue() + "-->" ); 2538 commentElement.createTextChild("<!--" + node.nodeValue() + "-->" );
2480 break; 2539 break;
2481 2540
2482 case Node.DOCUMENT_TYPE_NODE: 2541 case Node.DOCUMENT_TYPE_NODE:
2483 var docTypeElement = info.titleDOM.createChild("span", "webkit-h tml-doctype"); 2542 var docTypeElement = info.titleDOM.createChild("span", "webkit-h tml-doctype");
2484 docTypeElement.createTextChild("<!DOCTYPE " + node.nodeName()); 2543 docTypeElement.createTextChild("<!DOCTYPE " + node.nodeName());
2485 if (node.publicId) { 2544 if (node.publicId) {
2486 docTypeElement.createTextChild(" PUBLIC \"" + node.publicId + "\""); 2545 docTypeElement.createTextChild(" PUBLIC \"" + node.publicId + "\"");
2487 if (node.systemId) 2546 if (node.systemId)
2488 docTypeElement.createTextChild(" \"" + node.systemId + " \""); 2547 docTypeElement.createTextChild(" \"" + node.systemId + " \"");
2489 } else if (node.systemId) 2548 } else if (node.systemId)
2490 docTypeElement.createTextChild(" SYSTEM \"" + node.systemId + "\""); 2549 docTypeElement.createTextChild(" SYSTEM \"" + node.systemId + "\"");
2491 2550
2492 if (node.internalSubset) 2551 if (node.internalSubset)
2493 docTypeElement.createTextChild(" [" + node.internalSubset + "]"); 2552 docTypeElement.createTextChild(" [" + node.internalSubset + "]");
2494 2553
2495 docTypeElement.createTextChild(">"); 2554 docTypeElement.createTextChild(">");
2496 break; 2555 break;
2497 2556
2498 case Node.CDATA_SECTION_NODE: 2557 case Node.CDATA_SECTION_NODE:
2499 var cdataElement = info.titleDOM.createChild("span", "webkit-htm l-text-node"); 2558 var cdataElement = info.titleDOM.createChild("span", "webkit-htm l-text-node");
2500 cdataElement.createTextChild("<![CDATA[" + node.nodeValue() + "] ]>"); 2559 cdataElement.createTextChild("<![CDATA[" + node.nodeValue() + "] ]>");
2501 break; 2560 break;
2561
2502 case Node.DOCUMENT_FRAGMENT_NODE: 2562 case Node.DOCUMENT_FRAGMENT_NODE:
2503 var fragmentElement = info.titleDOM.createChild("span", "webkit- html-fragment"); 2563 var fragmentElement = info.titleDOM.createChild("span", "webkit- html-fragment");
2504 if (node.isInShadowTree()) { 2564 if (node.isInShadowTree()) {
2505 var shadowRootType = node.shadowRootType(); 2565 var shadowRootType = node.shadowRootType();
2506 if (shadowRootType) { 2566 if (shadowRootType) {
2507 info.shadowRoot = true; 2567 info.shadowRoot = true;
2508 fragmentElement.classList.add("shadow-root"); 2568 fragmentElement.classList.add("shadow-root");
2509 } 2569 }
2510 } 2570 }
2511 fragmentElement.textContent = node.nodeNameInCorrectCase().colla pseWhitespace(); 2571 fragmentElement.textContent = node.nodeNameInCorrectCase().colla pseWhitespace();
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2740 2800
2741 /** 2801 /**
2742 * @constructor 2802 * @constructor
2743 * @param {!WebInspector.DOMModel} domModel 2803 * @param {!WebInspector.DOMModel} domModel
2744 * @param {!WebInspector.ElementsTreeOutline} treeOutline 2804 * @param {!WebInspector.ElementsTreeOutline} treeOutline
2745 */ 2805 */
2746 WebInspector.ElementsTreeUpdater = function(domModel, treeOutline) 2806 WebInspector.ElementsTreeUpdater = function(domModel, treeOutline)
2747 { 2807 {
2748 domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._n odeInserted, this); 2808 domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._n odeInserted, this);
2749 domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._no deRemoved, this); 2809 domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._no deRemoved, this);
2750 domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._a ttributesUpdated, this); 2810 domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._a ttributeModified, this);
2751 domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._at tributesUpdated, this); 2811 domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._at tributeRemoved, this);
2752 domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified , this._characterDataModified, this); 2812 domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified , this._characterDataModified, this);
2753 domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this ._documentUpdated, this); 2813 domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this ._documentUpdated, this);
2754 domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated , this._childNodeCountUpdated, this); 2814 domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated , this._childNodeCountUpdated, this);
2755 2815
2756 this._domModel = domModel; 2816 this._domModel = domModel;
2757 this._treeOutline = treeOutline; 2817 this._treeOutline = treeOutline;
2758 /** @type {!Set.<!WebInspector.DOMNode>} */ 2818 /** @type {!Map.<!WebInspector.DOMNode, !WebInspector.ElementsTreeUpdater.Up dateInfo>} */
2759 this._recentlyModifiedNodes = new Set(); 2819 this._recentlyModifiedNodes = new Map();
2760 /** @type {!Set.<!WebInspector.DOMNode>} */ 2820 /** @type {!Map.<!WebInspector.DOMNode, !WebInspector.ElementsTreeUpdater.Up dateInfo>} */
2761 this._recentlyModifiedParentNodes = new Set(); 2821 this._recentlyModifiedParentNodes = new Map();
2762 } 2822 }
2763 2823
2764 WebInspector.ElementsTreeUpdater.prototype = { 2824 WebInspector.ElementsTreeUpdater.prototype = {
2765 dispose: function() 2825 dispose: function()
2766 { 2826 {
2767 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInse rted, this._nodeInserted, this); 2827 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInse rted, this._nodeInserted, this);
2768 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemo ved, this._nodeRemoved, this); 2828 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemo ved, this._nodeRemoved, this);
2769 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModi fied, this._attributesUpdated, this); 2829 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModi fied, this._attributeModified, this);
2770 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemo ved, this._attributesUpdated, this); 2830 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemo ved, this._attributeRemoved, this);
2771 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Characte rDataModified, this._characterDataModified, this); 2831 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Characte rDataModified, this._characterDataModified, this);
2772 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Document Updated, this._documentUpdated, this); 2832 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Document Updated, this._documentUpdated, this);
2773 this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNod eCountUpdated, this._childNodeCountUpdated, this); 2833 this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNod eCountUpdated, this._childNodeCountUpdated, this);
2774 }, 2834 },
2775 2835
2776 /** 2836 /**
2777 * @param {?WebInspector.DOMNode} parentNode 2837 * @param {?WebInspector.DOMNode} parentNode
2838 * @return {!WebInspector.ElementsTreeUpdater.UpdateInfo}
2778 */ 2839 */
2779 _parentNodeModified: function(parentNode) 2840 _parentNodeModified: function(parentNode)
2780 { 2841 {
2781 if (!parentNode) 2842 if (!parentNode)
2782 return; 2843 return new WebInspector.ElementsTreeUpdater.UpdateInfo(); // Bogus i nfo.
2783 this._recentlyModifiedParentNodes.add(parentNode); 2844
2845 var record = this._recentlyModifiedParentNodes.get(parentNode);
2846 if (!record) {
2847 record = new WebInspector.ElementsTreeUpdater.UpdateInfo();
2848 this._recentlyModifiedParentNodes.set(parentNode, record);
2849 }
2784 2850
2785 var treeElement = this._treeOutline.findTreeElement(parentNode); 2851 var treeElement = this._treeOutline.findTreeElement(parentNode);
2786 if (treeElement) { 2852 if (treeElement) {
2787 var oldDisplayMode = treeElement._childrenDisplayMode; 2853 var oldDisplayMode = treeElement._childrenDisplayMode;
2788 treeElement._updateChildrenDisplayMode(); 2854 treeElement._updateChildrenDisplayMode();
2789 if (treeElement._childrenDisplayMode !== oldDisplayMode) 2855 if (treeElement._childrenDisplayMode !== oldDisplayMode)
2790 this._nodeModified(parentNode); 2856 this._nodeModified(parentNode).childrenModified();
2791 } 2857 }
2792 2858
2793 if (this._treeOutline._visible) 2859 if (this._treeOutline._visible)
2794 this._updateModifiedNodesSoon(); 2860 this._updateModifiedNodesSoon();
2861
2862 return record;
2795 }, 2863 },
2796 2864
2797 /** 2865 /**
2798 * @param {!WebInspector.DOMNode} node 2866 * @param {!WebInspector.DOMNode} node
2867 * @return {!WebInspector.ElementsTreeUpdater.UpdateInfo}
2799 */ 2868 */
2800 _nodeModified: function(node) 2869 _nodeModified: function(node)
2801 { 2870 {
2802 this._recentlyModifiedNodes.add(node);
2803 if (this._treeOutline._visible) 2871 if (this._treeOutline._visible)
2804 this._updateModifiedNodesSoon(); 2872 this._updateModifiedNodesSoon();
2873 var record = this._recentlyModifiedNodes.get(node);
2874 if (!record) {
2875 record = new WebInspector.ElementsTreeUpdater.UpdateInfo();
2876 this._recentlyModifiedNodes.set(node, record);
2877 }
2878 return record;
2805 }, 2879 },
2806 2880
2807 /** 2881 /**
2808 * @param {!WebInspector.Event} event 2882 * @param {!WebInspector.Event} event
2809 */ 2883 */
2810 _documentUpdated: function(event) 2884 _documentUpdated: function(event)
2811 { 2885 {
2812 var inspectedRootDocument = event.data; 2886 var inspectedRootDocument = event.data;
2813 2887
2814 this._reset(); 2888 this._reset();
2815 2889
2816 if (!inspectedRootDocument) 2890 if (!inspectedRootDocument)
2817 return; 2891 return;
2818 2892
2819 this._treeOutline.rootDOMNode = inspectedRootDocument; 2893 this._treeOutline.rootDOMNode = inspectedRootDocument;
2820 }, 2894 },
2821 2895
2822 /** 2896 /**
2823 * @param {!WebInspector.Event} event 2897 * @param {!WebInspector.Event} event
2824 */ 2898 */
2825 _attributesUpdated: function(event) 2899 _attributeModified: function(event)
2826 { 2900 {
2827 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node); 2901 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2828 this._nodeModified(node); 2902 this._nodeModified(node).attributeModified(event.data.name);
2829 }, 2903 },
2830 2904
2831 /** 2905 /**
2906 * @param {!WebInspector.Event} event
2907 */
2908 _attributeRemoved: function(event)
2909 {
2910 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2911 this._nodeModified(node).attributeRemoved(event.data.name);
2912 },
2913
2914 /**
2832 * @param {!WebInspector.Event} event 2915 * @param {!WebInspector.Event} event
2833 */ 2916 */
2834 _characterDataModified: function(event) 2917 _characterDataModified: function(event)
2835 { 2918 {
2836 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2919 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2837 this._parentNodeModified(node.parentNode); 2920 this._parentNodeModified(node.parentNode).charDataModified();
2838 this._nodeModified(node); 2921 this._nodeModified(node).charDataModified();
2839 }, 2922 },
2840 2923
2841 /** 2924 /**
2842 * @param {!WebInspector.Event} event 2925 * @param {!WebInspector.Event} event
2843 */ 2926 */
2844 _nodeInserted: function(event) 2927 _nodeInserted: function(event)
2845 { 2928 {
2846 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2929 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2847 this._parentNodeModified(node.parentNode); 2930 this._parentNodeModified(node.parentNode).nodeInserted(node);
2848 }, 2931 },
2849 2932
2850 /** 2933 /**
2851 * @param {!WebInspector.Event} event 2934 * @param {!WebInspector.Event} event
2852 */ 2935 */
2853 _nodeRemoved: function(event) 2936 _nodeRemoved: function(event)
2854 { 2937 {
2855 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node); 2938 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2856 var parentNode = /** @type {!WebInspector.DOMNode} */ (event.data.parent ); 2939 var parentNode = /** @type {!WebInspector.DOMNode} */ (event.data.parent );
2857 this._treeOutline._resetClipboardIfNeeded(node); 2940 this._treeOutline._resetClipboardIfNeeded(node);
2858 this._parentNodeModified(parentNode); 2941 this._parentNodeModified(parentNode).childrenModified();
2859 }, 2942 },
2860 2943
2861 /** 2944 /**
2862 * @param {!WebInspector.Event} event 2945 * @param {!WebInspector.Event} event
2863 */ 2946 */
2864 _childNodeCountUpdated: function(event) 2947 _childNodeCountUpdated: function(event)
2865 { 2948 {
2866 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2949 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2867 this._parentNodeModified(node); 2950 this._parentNodeModified(node);
2868 }, 2951 },
2869 2952
2870 _updateModifiedNodesSoon: function() 2953 _updateModifiedNodesSoon: function()
2871 { 2954 {
2872 if (this._updateModifiedNodesTimeout) 2955 if (this._updateModifiedNodesTimeout)
2873 return; 2956 return;
2874 this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes. bind(this), 50); 2957 this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes. bind(this), 50);
2875 }, 2958 },
2876 2959
2877 _updateModifiedNodes: function() 2960 _updateModifiedNodes: function()
2878 { 2961 {
2879 if (this._updateModifiedNodesTimeout) { 2962 if (this._updateModifiedNodesTimeout) {
2880 clearTimeout(this._updateModifiedNodesTimeout); 2963 clearTimeout(this._updateModifiedNodesTimeout);
2881 delete this._updateModifiedNodesTimeout; 2964 delete this._updateModifiedNodesTimeout;
2882 } 2965 }
2883 2966
2884 var updatedNodes = this._recentlyModifiedNodes.valuesArray().concat(this ._recentlyModifiedParentNodes.valuesArray()); 2967 var updatedNodes = this._recentlyModifiedNodes.keysArray().concat(this._ recentlyModifiedParentNodes.keysArray());
2885 var hidePanelWhileUpdating = updatedNodes.length > 10; 2968 var hidePanelWhileUpdating = updatedNodes.length > 10;
2886 if (hidePanelWhileUpdating) { 2969 if (hidePanelWhileUpdating) {
2887 var treeOutlineContainerElement = this._treeOutline.element.parentNo de; 2970 var treeOutlineContainerElement = this._treeOutline.element.parentNo de;
2888 var originalScrollTop = treeOutlineContainerElement ? treeOutlineCon tainerElement.scrollTop : 0; 2971 var originalScrollTop = treeOutlineContainerElement ? treeOutlineCon tainerElement.scrollTop : 0;
2889 this._treeOutline._element.classList.add("hidden"); 2972 this._treeOutline._element.classList.add("hidden");
2890 } 2973 }
2891 2974
2892 if (this._treeOutline._rootDOMNode && this._recentlyModifiedParentNodes. has(this._treeOutline._rootDOMNode)) { 2975 if (this._treeOutline._rootDOMNode && this._recentlyModifiedParentNodes. has(this._treeOutline._rootDOMNode)) {
2893 // Document's children have changed, perform total update. 2976 // Document's children have changed, perform total update.
2894 this._treeOutline.update(); 2977 this._treeOutline.update();
2895 } else { 2978 } else {
2896 var nodes = this._recentlyModifiedNodes.valuesArray(); 2979 for (var node of this._recentlyModifiedNodes.keys()) {
2897 for (var i = 0, size = nodes.length; i < size; ++i) { 2980 var nodeItem = this._treeOutline.findTreeElement(node);
2898 var nodeItem = this._treeOutline.findTreeElement(nodes[i]);
2899 if (nodeItem) 2981 if (nodeItem)
2900 nodeItem.updateTitle(); 2982 nodeItem.updateTitle(false);
2901 } 2983 }
2902 2984
2903 var parentNodes = this._recentlyModifiedParentNodes.valuesArray(); 2985 for (var node of this._recentlyModifiedParentNodes.keys()) {
2904 for (var i = 0, size = parentNodes.length; i < size; ++i) { 2986 var parentNodeItem = this._treeOutline.findTreeElement(node);
2905 var parentNodeItem = this._treeOutline.findTreeElement(parentNod es[i]);
2906 if (parentNodeItem && parentNodeItem.populated) 2987 if (parentNodeItem && parentNodeItem.populated)
2907 parentNodeItem.updateChildren(); 2988 parentNodeItem.updateChildren(false);
2908 } 2989 }
2909 } 2990 }
2910 2991
2911 if (hidePanelWhileUpdating) { 2992 if (hidePanelWhileUpdating) {
2912 this._treeOutline._element.classList.remove("hidden"); 2993 this._treeOutline._element.classList.remove("hidden");
2913 if (originalScrollTop) 2994 if (originalScrollTop)
2914 treeOutlineContainerElement.scrollTop = originalScrollTop; 2995 treeOutlineContainerElement.scrollTop = originalScrollTop;
2915 this._treeOutline.updateSelection(); 2996 this._treeOutline.updateSelection();
2916 } 2997 }
2917 this._recentlyModifiedNodes.clear(); 2998 this._recentlyModifiedNodes.clear();
2918 this._recentlyModifiedParentNodes.clear(); 2999 this._recentlyModifiedParentNodes.clear();
2919 this._treeOutline._fireElementsTreeUpdated(updatedNodes); 3000 this._treeOutline._fireElementsTreeUpdated(updatedNodes);
2920 }, 3001 },
2921 3002
2922 _reset: function() 3003 _reset: function()
2923 { 3004 {
2924 this._treeOutline.rootDOMNode = null; 3005 this._treeOutline.rootDOMNode = null;
2925 this._treeOutline.selectDOMNode(null, false); 3006 this._treeOutline.selectDOMNode(null, false);
2926 this._domModel.hideDOMNodeHighlight(); 3007 this._domModel.hideDOMNodeHighlight();
2927 this._recentlyModifiedNodes.clear(); 3008 this._recentlyModifiedNodes.clear();
2928 this._recentlyModifiedParentNodes.clear(); 3009 this._recentlyModifiedParentNodes.clear();
2929 delete this._treeOutline._clipboardNodeData; 3010 delete this._treeOutline._clipboardNodeData;
2930 } 3011 }
2931 } 3012 }
2932 3013
2933 /** 3014 /**
2934 * @constructor 3015 * @constructor
3016 */
3017 WebInspector.ElementsTreeUpdater.UpdateInfo = function()
3018 {
3019 }
3020
3021 WebInspector.ElementsTreeUpdater.UpdateInfo.prototype = {
3022 /**
3023 * @param {string} attrName
3024 */
3025 attributeModified: function(attrName)
3026 {
3027 if (this._removedAttributes && this._removedAttributes.has(attrName))
3028 this._removedAttributes.delete(attrName);
3029 if (!this._modifiedAttributes)
3030 this._modifiedAttributes = /** @type {!Set.<string>} */ (new Set());
3031 this._modifiedAttributes.add(attrName);
3032 },
3033
3034 /**
3035 * @param {string} attrName
3036 */
3037 attributeRemoved: function(attrName)
3038 {
3039 if (this._modifiedAttributes && this._modifiedAttributes.has(attrName))
3040 this._modifiedAttributes.delete(attrName);
3041 if (!this._removedAttributes)
3042 this._removedAttributes = /** @type {!Set.<string>} */ (new Set());
3043 this._removedAttributes.add(attrName);
3044 },
3045
3046 /**
3047 * @param {!WebInspector.DOMNode} node
3048 */
3049 nodeInserted: function(node)
3050 {
3051 if (!this._insertedNodes)
3052 this._insertedNodes = /** @type {!Set.<!WebInspector.DOMNode>} */ (n ew Set());
3053 this._insertedNodes.add(/** @type {!WebInspector.DOMNode} */ (node));
3054 },
3055
3056 charDataModified: function()
3057 {
3058 this._charDataModified = true;
3059 },
3060
3061 childrenModified: function()
3062 {
3063 this._hasChangedChildren = true;
3064 },
3065
3066 /**
3067 * @param {string} attributeName
3068 * @return {boolean}
3069 */
3070 isAttributeModified: function(attributeName)
3071 {
3072 return this._modifiedAttributes && this._modifiedAttributes.has(attribut eName);
3073 },
3074
3075 /**
3076 * @return {boolean}
3077 */
3078 hasRemovedAttributes: function()
3079 {
3080 return !!this._removedAttributes && !!this._removedAttributes.size;
3081 },
3082
3083 /**
3084 * @return {boolean}
3085 */
3086 hasInsertedNodes: function()
3087 {
3088 return !!this._insertedNodes && !!this._insertedNodes.size;
3089 },
3090
3091 /**
3092 * @return {boolean}
3093 */
3094 isCharDataModified: function()
3095 {
3096 return !!this._charDataModified;
3097 },
3098
3099 /**
3100 * @return {boolean}
3101 */
3102 isNodeInserted: function(node)
3103 {
3104 return !!this._insertedNodes && this._insertedNodes.has(node);
3105 },
3106
3107 /**
3108 * @return {boolean}
3109 */
3110 hasChangedChildren: function()
3111 {
3112 return !!this._hasChangedChildren;
3113 }
3114 }
3115
3116 /**
3117 * @constructor
2935 * @implements {WebInspector.Renderer} 3118 * @implements {WebInspector.Renderer}
2936 */ 3119 */
2937 WebInspector.ElementsTreeOutline.Renderer = function() 3120 WebInspector.ElementsTreeOutline.Renderer = function()
2938 { 3121 {
2939 } 3122 }
2940 3123
2941 WebInspector.ElementsTreeOutline.Renderer.prototype = { 3124 WebInspector.ElementsTreeOutline.Renderer.prototype = {
2942 /** 3125 /**
2943 * @param {!Object} object 3126 * @param {!Object} object
2944 * @return {!Promise.<!Element>} 3127 * @return {!Promise.<!Element>}
(...skipping 30 matching lines...) Expand all
2975 treeOutline.rootDOMNode = node; 3158 treeOutline.rootDOMNode = node;
2976 if (!treeOutline.children[0].hasChildren) 3159 if (!treeOutline.children[0].hasChildren)
2977 treeOutline._element.classList.add("single-node"); 3160 treeOutline._element.classList.add("single-node");
2978 treeOutline.setVisible(true); 3161 treeOutline.setVisible(true);
2979 treeOutline.element.treeElementForTest = treeOutline.children[0] ; 3162 treeOutline.element.treeElementForTest = treeOutline.children[0] ;
2980 resolve(treeOutline.element); 3163 resolve(treeOutline.element);
2981 } 3164 }
2982 } 3165 }
2983 } 3166 }
2984 } 3167 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/common/Settings.js ('k') | Source/devtools/front_end/elements/elementsTreeOutline.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698