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

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: Reworked the way titles are updated (through updateTitle() now) 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 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 return WebInspector.UIString("%d descendant with forced state", desc endantCount); 1011 return WebInspector.UIString("%d descendant with forced state", desc endantCount);
1012 return WebInspector.UIString("%d descendants with forced state", descend antCount); 1012 return WebInspector.UIString("%d descendants with forced state", descend antCount);
1013 } 1013 }
1014 } 1014 }
1015 1015
1016 /** 1016 /**
1017 * @constructor 1017 * @constructor
1018 * @extends {TreeElement} 1018 * @extends {TreeElement}
1019 * @param {!WebInspector.DOMNode} node 1019 * @param {!WebInspector.DOMNode} node
1020 * @param {boolean=} elementCloseTag 1020 * @param {boolean=} elementCloseTag
1021 * @param {boolean=} isUpdated
1021 */ 1022 */
1022 WebInspector.ElementsTreeElement = function(node, elementCloseTag) 1023 WebInspector.ElementsTreeElement = function(node, elementCloseTag, isUpdated)
1023 { 1024 {
1024 // The title will be updated in onattach. 1025 // The title will be updated in onattach.
1025 TreeElement.call(this, "", node); 1026 TreeElement.call(this, "", node);
1026 this._node = node; 1027 this._node = node;
1027 1028
1028 this._elementCloseTag = elementCloseTag; 1029 this._elementCloseTag = elementCloseTag;
1029 this._updateHasChildren(); 1030 this._updateHasChildren();
1030 1031
1031 if (this._node.nodeType() == Node.ELEMENT_NODE && !elementCloseTag) 1032 if (this._node.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
1032 this._canAddAttributes = true; 1033 this._canAddAttributes = true;
1034 this._isUpdated = isUpdated;
1033 this._searchQuery = null; 1035 this._searchQuery = null;
1034 this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildr enLimit; 1036 this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildr enLimit;
1035 } 1037 }
1036 1038
1037 WebInspector.ElementsTreeElement.InitialChildrenLimit = 500; 1039 WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
1038 1040
1039 // A union of HTML4 and HTML5-Draft elements that explicitly 1041 // A union of HTML4 and HTML5-Draft elements that explicitly
1040 // or implicitly (for HTML5) forbid the closing tag. 1042 // or implicitly (for HTML5) forbid the closing tag.
1041 WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [ 1043 WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
1042 "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "fram e", 1044 "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "fram e",
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 return this._expandedChildrenLimit; 1146 return this._expandedChildrenLimit;
1145 }, 1147 },
1146 1148
1147 set expandedChildrenLimit(x) 1149 set expandedChildrenLimit(x)
1148 { 1150 {
1149 if (this._expandedChildrenLimit === x) 1151 if (this._expandedChildrenLimit === x)
1150 return; 1152 return;
1151 1153
1152 this._expandedChildrenLimit = x; 1154 this._expandedChildrenLimit = x;
1153 if (this.treeOutline && !this._updateChildrenInProgress) 1155 if (this.treeOutline && !this._updateChildrenInProgress)
1154 this._updateChildren(true, this.children); 1156 this._updateChildren(true, undefined, this.children);
1155 }, 1157 },
1156 1158
1157 get expandedChildCount() 1159 get expandedChildCount()
1158 { 1160 {
1159 var count = this.children.length; 1161 var count = this.children.length;
1160 if (count && this.children[count - 1]._elementCloseTag) 1162 if (count && this.children[count - 1]._elementCloseTag)
1161 count--; 1163 count--;
1162 if (count && this.children[count - 1].expandAllButton) 1164 if (count && this.children[count - 1].expandAllButton)
1163 count--; 1165 count--;
1164 return count; 1166 return count;
1165 }, 1167 },
1166 1168
1167 /** 1169 /**
1168 * @param {!WebInspector.DOMNode} child 1170 * @param {!WebInspector.DOMNode} child
1169 * @return {?WebInspector.ElementsTreeElement} 1171 * @return {?WebInspector.ElementsTreeElement}
1170 */ 1172 */
1171 _showChild: function(child) 1173 _showChild: function(child)
1172 { 1174 {
1173 if (this._elementCloseTag) 1175 if (this._elementCloseTag)
1174 return null; 1176 return null;
1175 1177
1176 var index = this._visibleChildren().indexOf(child); 1178 var index = this._visibleChildren().indexOf(child);
1177 if (index === -1) 1179 if (index === -1)
1178 return null; 1180 return null;
1179 1181
1180 if (index >= this.expandedChildrenLimit) { 1182 if (index >= this.expandedChildrenLimit) {
1181 this._expandedChildrenLimit = index + 1; 1183 this._expandedChildrenLimit = index + 1;
1182 this._updateChildren(true, this.children); 1184 this._updateChildren(true, undefined, this.children);
1183 } 1185 }
1184 1186
1185 // Whether index-th child is visible in the children tree 1187 // Whether index-th child is visible in the children tree
1186 return this.expandedChildCount > index ? this.children[index] : null; 1188 return this.expandedChildCount > index ? this.children[index] : null;
1187 }, 1189 },
1188 1190
1189 updateSelection: function() 1191 updateSelection: function()
1190 { 1192 {
1191 var listItemElement = this.listItemElement; 1193 var listItemElement = this.listItemElement;
1192 if (!listItemElement) 1194 if (!listItemElement)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 { 1239 {
1238 this.populated = true; 1240 this.populated = true;
1239 if (this.children.length || !this.hasChildren) 1241 if (this.children.length || !this.hasChildren)
1240 return; 1242 return;
1241 1243
1242 this.updateChildren(); 1244 this.updateChildren();
1243 }, 1245 },
1244 1246
1245 /** 1247 /**
1246 * @param {boolean=} fullRefresh 1248 * @param {boolean=} fullRefresh
1249 * @param {!WebInspector.ElementsTreeUpdater.Record=} updates
1247 */ 1250 */
1248 updateChildren: function(fullRefresh) 1251 updateChildren: function(fullRefresh, updates)
1249 { 1252 {
1250 if (!this.hasChildren) 1253 if (!this.hasChildren)
1251 return; 1254 return;
1252 console.assert(!this._elementCloseTag); 1255 console.assert(!this._elementCloseTag);
1253 this._node.getChildNodes(this._updateChildren.bind(this, fullRefresh || false)); 1256 this._node.getChildNodes(this._updateChildren.bind(this, fullRefresh || false, updates));
1254 }, 1257 },
1255 1258
1256 /** 1259 /**
1257 * @param {!WebInspector.DOMNode} child 1260 * @param {!WebInspector.DOMNode} child
1258 * @param {number} index 1261 * @param {number} index
1259 * @param {boolean=} closingTag 1262 * @param {boolean=} closingTag
1263 * @param {boolean=} isUpdated
1260 * @return {!WebInspector.ElementsTreeElement} 1264 * @return {!WebInspector.ElementsTreeElement}
1261 */ 1265 */
1262 insertChildElement: function(child, index, closingTag) 1266 insertChildElement: function(child, index, closingTag, isUpdated)
1263 { 1267 {
1264 var newElement = new WebInspector.ElementsTreeElement(child, closingTag) ; 1268 var newElement = new WebInspector.ElementsTreeElement(child, closingTag, isUpdated);
1265 newElement.selectable = this.treeOutline._selectEnabled; 1269 newElement.selectable = this.treeOutline._selectEnabled;
1266 this.insertChild(newElement, index); 1270 this.insertChild(newElement, index);
1267 return newElement; 1271 return newElement;
1268 }, 1272 },
1269 1273
1270 moveChild: function(child, targetIndex) 1274 moveChild: function(child, targetIndex)
1271 { 1275 {
1272 var wasSelected = child.selected; 1276 var wasSelected = child.selected;
1273 this.removeChild(child); 1277 this.removeChild(child);
1274 this.insertChild(child, targetIndex); 1278 this.insertChild(child, targetIndex);
1275 if (wasSelected) 1279 if (wasSelected)
1276 child.select(); 1280 child.select();
1277 }, 1281 },
1278 1282
1279 /** 1283 /**
1280 * @param {boolean} fullRefresh 1284 * @param {boolean} fullRefresh
1285 * @param {!WebInspector.ElementsTreeUpdater.Record|undefined} childUpdates
1281 * @param {?Array.<!WebInspector.DOMNode>} children 1286 * @param {?Array.<!WebInspector.DOMNode>} children
1282 */ 1287 */
1283 _updateChildren: function(fullRefresh, children) 1288 _updateChildren: function(fullRefresh, childUpdates, children)
1284 { 1289 {
1285 if (!children || this._updateChildrenInProgress || !this.treeOutline._vi sible) 1290 if (!children || this._updateChildrenInProgress || !this.treeOutline._vi sible)
1286 return; 1291 return;
1287 1292
1288 this._updateChildrenInProgress = true; 1293 this._updateChildrenInProgress = true;
1289 var selectedNode = this.treeOutline.selectedDOMNode(); 1294 var selectedNode = this.treeOutline.selectedDOMNode();
1290 var originalScrollTop = 0; 1295 var originalScrollTop = 0;
1291 if (fullRefresh) { 1296 if (fullRefresh) {
1292 var treeOutlineContainerElement = this.treeOutline.element.parentNod e; 1297 var treeOutlineContainerElement = this.treeOutline.element.parentNod e;
1293 originalScrollTop = treeOutlineContainerElement.scrollTop; 1298 originalScrollTop = treeOutlineContainerElement.scrollTop;
(...skipping 26 matching lines...) Expand all
1320 break; 1325 break;
1321 } 1326 }
1322 } 1327 }
1323 1328
1324 if (existingTreeElement && existingTreeElement.parent === th is) { 1329 if (existingTreeElement && existingTreeElement.parent === th is) {
1325 // If an existing element was found and it has the same parent, just move it. 1330 // If an existing element was found and it has the same parent, just move it.
1326 this.moveChild(existingTreeElement, treeChildIndex); 1331 this.moveChild(existingTreeElement, treeChildIndex);
1327 } else { 1332 } else {
1328 // No existing element found, insert a new element. 1333 // No existing element found, insert a new element.
1329 if (treeChildIndex < this.expandedChildrenLimit) { 1334 if (treeChildIndex < this.expandedChildrenLimit) {
1330 var newElement = this.insertChildElement(child, tree ChildIndex); 1335 var newElement = this.insertChildElement(child, tree ChildIndex, false, !!childUpdates && childUpdates.isNodeInserted(child));
pfeldman 2014/11/07 12:54:15 Can you do something like: if (childUpdates.isNod
apavlov 2014/11/10 09:52:56 Done something along these lines with mыrging...
1331 if (child === selectedNode) 1336 if (child === selectedNode)
1332 elementToSelect = newElement; 1337 elementToSelect = newElement;
1333 if (this.expandedChildCount > this.expandedChildrenL imit) 1338 if (this.expandedChildCount > this.expandedChildrenL imit)
1334 this.expandedChildrenLimit++; 1339 this.expandedChildrenLimit++;
1335 } 1340 }
1336 } 1341 }
1337 } 1342 }
1338 1343
1339 ++treeChildIndex; 1344 ++treeChildIndex;
1340 } 1345 }
(...skipping 12 matching lines...) Expand all
1353 continue; 1358 continue;
1354 1359
1355 var selectedTreeElement = this.treeOutline.selectedTreeElement; 1360 var selectedTreeElement = this.treeOutline.selectedTreeElement;
1356 if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild))) 1361 if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
1357 this.select(); 1362 this.select();
1358 1363
1359 this.removeChildAtIndex(i); 1364 this.removeChildAtIndex(i);
1360 } 1365 }
1361 1366
1362 var elementToSelect = updateChildrenOfNode.call(this); 1367 var elementToSelect = updateChildrenOfNode.call(this);
1363 this.updateTitle(); 1368 this.updateTitle(false, childUpdates);
1364 this._adjustCollapsedRange(); 1369 this._adjustCollapsedRange();
1365 1370
1366 var lastChild = this.children[this.children.length - 1]; 1371 var lastChild = this.children[this.children.length - 1];
1367 if (this._node.nodeType() === Node.ELEMENT_NODE && this.hasChildren) 1372 if (this._node.nodeType() === Node.ELEMENT_NODE && this.hasChildren)
1368 this.insertChildElement(this._node, this.children.length, true); 1373 this.insertChildElement(this._node, this.children.length, true);
1369 1374
1370 // We want to restore the original selection and tree scroll position af ter a full refresh, if possible. 1375 // We want to restore the original selection and tree scroll position af ter a full refresh, if possible.
1371 if (fullRefresh && elementToSelect) { 1376 if (fullRefresh && elementToSelect) {
1372 elementToSelect.select(); 1377 elementToSelect.select();
1373 if (treeOutlineContainerElement && originalScrollTop <= treeOutlineC ontainerElement.scrollHeight) 1378 if (treeOutlineContainerElement && originalScrollTop <= treeOutlineC ontainerElement.scrollHeight)
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 2160
2156 // Remaining cases are single line non-expanded elements with a closing 2161 // Remaining cases are single line non-expanded elements with a closing
2157 // tag, or HTML elements without a closing tag (such as <br>). Return 2162 // tag, or HTML elements without a closing tag (such as <br>). Return
2158 // null in the case where there isn't a closing tag. 2163 // null in the case where there isn't a closing tag.
2159 var tags = this.listItemElement.getElementsByClassName("webkit-html-tag" ); 2164 var tags = this.listItemElement.getElementsByClassName("webkit-html-tag" );
2160 return (tags.length === 1 ? null : tags[tags.length-1]); 2165 return (tags.length === 1 ? null : tags[tags.length-1]);
2161 }, 2166 },
2162 2167
2163 /** 2168 /**
2164 * @param {boolean=} onlySearchQueryChanged 2169 * @param {boolean=} onlySearchQueryChanged
2170 * @param {!WebInspector.ElementsTreeUpdater.Record=} updates
2165 */ 2171 */
2166 updateTitle: function(onlySearchQueryChanged) 2172 updateTitle: function(onlySearchQueryChanged, updates)
2167 { 2173 {
2168 // If we are editing, return early to prevent canceling the edit. 2174 // If we are editing, return early to prevent canceling the edit.
2169 // After editing is committed updateTitle will be called. 2175 // After editing is committed updateTitle will be called.
2170 if (this._editing) 2176 if (this._editing)
2171 return; 2177 return;
2172 2178
2179 this._updates = updates;
2173 if (onlySearchQueryChanged) { 2180 if (onlySearchQueryChanged) {
2174 if (this._highlightResult) 2181 if (this._highlightResult)
2175 this._updateSearchHighlight(false); 2182 this._updateSearchHighlight(false);
2176 } else { 2183 } else {
2177 var nodeInfo = this._nodeTitleInfo(WebInspector.linkifyURLAsNode); 2184 var nodeInfo = this._nodeTitleInfo(WebInspector.linkifyURLAsNode);
2178 if (nodeInfo.shadowRoot) 2185 if (nodeInfo.shadowRoot)
2179 this.listItemElement.classList.add("shadow-root"); 2186 this.listItemElement.classList.add("shadow-root");
2180 var highlightElement = createElement("span"); 2187 var highlightElement = createElement("span");
2181 highlightElement.className = "highlight"; 2188 highlightElement.className = "highlight";
2182 highlightElement.appendChild(nodeInfo.titleDOM); 2189 highlightElement.appendChild(nodeInfo.titleDOM);
2183 this.title = highlightElement; 2190 this.title = highlightElement;
2184 this._updateDecorations(); 2191 this._updateDecorations();
2185 delete this._highlightResult; 2192 delete this._highlightResult;
2186 } 2193 }
2187 2194
2195 delete this._isUpdated;
2188 delete this.selectionElement; 2196 delete this.selectionElement;
2189 if (this.selected) 2197 if (this.selected)
2190 this.updateSelection(); 2198 this.updateSelection();
2191 this._preventFollowingLinksOnDoubleClick(); 2199 this._preventFollowingLinksOnDoubleClick();
2192 this._highlightSearchResults(); 2200 this._highlightSearchResults();
2193 }, 2201 },
2194 2202
2195 /** 2203 /**
2196 * @return {?Element} 2204 * @return {?Element}
2197 */ 2205 */
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 var hasText = (forceValue || value.length > 0); 2294 var hasText = (forceValue || value.length > 0);
2287 var attrSpanElement = parentElement.createChild("span", "webkit-html-att ribute"); 2295 var attrSpanElement = parentElement.createChild("span", "webkit-html-att ribute");
2288 var attrNameElement = attrSpanElement.createChild("span", "webkit-html-a ttribute-name"); 2296 var attrNameElement = attrSpanElement.createChild("span", "webkit-html-a ttribute-name");
2289 attrNameElement.textContent = name; 2297 attrNameElement.textContent = name;
2290 2298
2291 if (hasText) 2299 if (hasText)
2292 attrSpanElement.createTextChild("=\u200B\""); 2300 attrSpanElement.createTextChild("=\u200B\"");
2293 2301
2294 var attrValueElement = attrSpanElement.createChild("span", "webkit-html- attribute-value"); 2302 var attrValueElement = attrSpanElement.createChild("span", "webkit-html- attribute-value");
2295 2303
2304 if (this._updates && this._updates.isAttributeModified(name))
2305 WebInspector.runCSSAnimationOnce(hasText ? attrValueElement : attrNa meElement, "dom-update-highlight");
2306
2296 /** 2307 /**
2297 * @this {WebInspector.ElementsTreeElement} 2308 * @this {WebInspector.ElementsTreeElement}
2298 * @param {string} value 2309 * @param {string} value
2299 * @return {!Element} 2310 * @return {!Element}
2300 */ 2311 */
2301 function linkifyValue(value) 2312 function linkifyValue(value)
2302 { 2313 {
2303 var rewrittenHref = node.resolveURL(value); 2314 var rewrittenHref = node.resolveURL(value);
2304 if (rewrittenHref === null) { 2315 if (rewrittenHref === null) {
2305 var span = createElement("span"); 2316 var span = createElement("span");
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeE lement, linkify) 2368 _buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeE lement, linkify)
2358 { 2369 {
2359 var node = this._node; 2370 var node = this._node;
2360 var classes = [ "webkit-html-tag" ]; 2371 var classes = [ "webkit-html-tag" ];
2361 if (isClosingTag && isDistinctTreeElement) 2372 if (isClosingTag && isDistinctTreeElement)
2362 classes.push("close"); 2373 classes.push("close");
2363 var tagElement = parentElement.createChild("span", classes.join(" ")); 2374 var tagElement = parentElement.createChild("span", classes.join(" "));
2364 tagElement.createTextChild("<"); 2375 tagElement.createTextChild("<");
2365 var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name"); 2376 var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
2366 tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName; 2377 tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
2367 if (!isClosingTag && node.hasAttributes()) { 2378 if (!isClosingTag) {
2368 var attributes = node.attributes(); 2379 if (node.hasAttributes()) {
2369 for (var i = 0; i < attributes.length; ++i) { 2380 var attributes = node.attributes();
2370 var attr = attributes[i]; 2381 for (var i = 0; i < attributes.length; ++i) {
2371 tagElement.createTextChild(" "); 2382 var attr = attributes[i];
2372 this._buildAttributeDOM(tagElement, attr.name, attr.value, false , node, linkify); 2383 tagElement.createTextChild(" ");
2384 this._buildAttributeDOM(tagElement, attr.name, attr.value, f alse, node, linkify);
2385 }
2373 } 2386 }
2387 if (this._isUpdated || (this._updates && (this._updates.hasRemovedAt tributes() || this._updates.hasChangedChildren())))
2388 WebInspector.runCSSAnimationOnce(tagNameElement, "dom-update-hig hlight");
2374 } 2389 }
2390
2375 tagElement.createTextChild(">"); 2391 tagElement.createTextChild(">");
2376 parentElement.createTextChild("\u200B"); 2392 parentElement.createTextChild("\u200B");
2377 }, 2393 },
2378 2394
2379 /** 2395 /**
2380 * @param {string} text 2396 * @param {string} text
2381 * @return {!{text: string, entityRanges: !Array.<!WebInspector.SourceRange> }} 2397 * @return {!{text: string, entityRanges: !Array.<!WebInspector.SourceRange> }}
2382 */ 2398 */
2383 _convertWhitespaceToEntities: function(text) 2399 _convertWhitespaceToEntities: function(text)
2384 { 2400 {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 // create a subtree for them 2463 // create a subtree for them
2448 if (showInlineText) { 2464 if (showInlineText) {
2449 console.assert(!this.hasChildren); 2465 console.assert(!this.hasChildren);
2450 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node"); 2466 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node");
2451 var result = this._convertWhitespaceToEntities(node.firstChi ld.nodeValue()); 2467 var result = this._convertWhitespaceToEntities(node.firstChi ld.nodeValue());
2452 textNodeElement.textContent = result.text; 2468 textNodeElement.textContent = result.text;
2453 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value"); 2469 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
2454 info.titleDOM.createTextChild("\u200B"); 2470 info.titleDOM.createTextChild("\u200B");
2455 this._buildTagDOM(info.titleDOM, tagName, true, false); 2471 this._buildTagDOM(info.titleDOM, tagName, true, false);
2456 info.hasChildren = false; 2472 info.hasChildren = false;
2473 if (this._updates && (this._updates.isCharDataModified() || this._updates.hasInsertedNodes()))
2474 WebInspector.runCSSAnimationOnce(textNodeElement, "dom-u pdate-highlight");
2457 } 2475 }
2458 break; 2476 break;
2459 2477
2460 case Node.TEXT_NODE: 2478 case Node.TEXT_NODE:
2461 if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") { 2479 if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
2462 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-js-node"); 2480 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-js-node");
2463 newNode.textContent = node.nodeValue(); 2481 newNode.textContent = node.nodeValue();
2464 2482
2465 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntax Highlighter("text/javascript", true); 2483 var javascriptSyntaxHighlighter = new WebInspector.DOMSyntax Highlighter("text/javascript", true);
2466 javascriptSyntaxHighlighter.syntaxHighlightNode(newNode); 2484 javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
2467 } else if (node.parentNode && node.parentNode.nodeName().toLower Case() === "style") { 2485 } else if (node.parentNode && node.parentNode.nodeName().toLower Case() === "style") {
2468 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-css-node"); 2486 var newNode = info.titleDOM.createChild("span", "webkit-html -text-node webkit-html-css-node");
2469 newNode.textContent = node.nodeValue(); 2487 newNode.textContent = node.nodeValue();
2470 2488
2471 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlig hter("text/css", true); 2489 var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlig hter("text/css", true);
2472 cssSyntaxHighlighter.syntaxHighlightNode(newNode); 2490 cssSyntaxHighlighter.syntaxHighlightNode(newNode);
2473 } else { 2491 } else {
2474 info.titleDOM.createTextChild("\""); 2492 info.titleDOM.createTextChild("\"");
2475 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node"); 2493 var textNodeElement = info.titleDOM.createChild("span", "web kit-html-text-node");
2476 var result = this._convertWhitespaceToEntities(node.nodeValu e()); 2494 var result = this._convertWhitespaceToEntities(node.nodeValu e());
2477 textNodeElement.textContent = result.text; 2495 textNodeElement.textContent = result.text;
2478 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value"); 2496 WebInspector.highlightRangesWithStyleClass(textNodeElement, result.entityRanges, "webkit-html-entity-value");
2479 info.titleDOM.createTextChild("\""); 2497 info.titleDOM.createTextChild("\"");
2498 if (this._isUpdated || (this._updates && this._updates.isCha rDataModified()))
2499 WebInspector.runCSSAnimationOnce(textNodeElement, "dom-u pdate-highlight");
2480 } 2500 }
2481 break; 2501 break;
2482 2502
2483 case Node.COMMENT_NODE: 2503 case Node.COMMENT_NODE:
2484 var commentElement = info.titleDOM.createChild("span", "webkit-h tml-comment"); 2504 var commentElement = info.titleDOM.createChild("span", "webkit-h tml-comment");
2485 commentElement.createTextChild("<!--" + node.nodeValue() + "-->" ); 2505 commentElement.createTextChild("<!--" + node.nodeValue() + "-->" );
2486 break; 2506 break;
2487 2507
2488 case Node.DOCUMENT_TYPE_NODE: 2508 case Node.DOCUMENT_TYPE_NODE:
2489 var docTypeElement = info.titleDOM.createChild("span", "webkit-h tml-doctype"); 2509 var docTypeElement = info.titleDOM.createChild("span", "webkit-h tml-doctype");
2490 docTypeElement.createTextChild("<!DOCTYPE " + node.nodeName()); 2510 docTypeElement.createTextChild("<!DOCTYPE " + node.nodeName());
2491 if (node.publicId) { 2511 if (node.publicId) {
2492 docTypeElement.createTextChild(" PUBLIC \"" + node.publicId + "\""); 2512 docTypeElement.createTextChild(" PUBLIC \"" + node.publicId + "\"");
2493 if (node.systemId) 2513 if (node.systemId)
2494 docTypeElement.createTextChild(" \"" + node.systemId + " \""); 2514 docTypeElement.createTextChild(" \"" + node.systemId + " \"");
2495 } else if (node.systemId) 2515 } else if (node.systemId)
2496 docTypeElement.createTextChild(" SYSTEM \"" + node.systemId + "\""); 2516 docTypeElement.createTextChild(" SYSTEM \"" + node.systemId + "\"");
2497 2517
2498 if (node.internalSubset) 2518 if (node.internalSubset)
2499 docTypeElement.createTextChild(" [" + node.internalSubset + "]"); 2519 docTypeElement.createTextChild(" [" + node.internalSubset + "]");
2500 2520
2501 docTypeElement.createTextChild(">"); 2521 docTypeElement.createTextChild(">");
2502 break; 2522 break;
2503 2523
2504 case Node.CDATA_SECTION_NODE: 2524 case Node.CDATA_SECTION_NODE:
2505 var cdataElement = info.titleDOM.createChild("span", "webkit-htm l-text-node"); 2525 var cdataElement = info.titleDOM.createChild("span", "webkit-htm l-text-node");
2506 cdataElement.createTextChild("<![CDATA[" + node.nodeValue() + "] ]>"); 2526 cdataElement.createTextChild("<![CDATA[" + node.nodeValue() + "] ]>");
2507 break; 2527 break;
2528
2508 case Node.DOCUMENT_FRAGMENT_NODE: 2529 case Node.DOCUMENT_FRAGMENT_NODE:
2509 var fragmentElement = info.titleDOM.createChild("span", "webkit- html-fragment"); 2530 var fragmentElement = info.titleDOM.createChild("span", "webkit- html-fragment");
2510 if (node.isInShadowTree()) { 2531 if (node.isInShadowTree()) {
2511 var shadowRootType = node.shadowRootType(); 2532 var shadowRootType = node.shadowRootType();
2512 if (shadowRootType) { 2533 if (shadowRootType) {
2513 info.shadowRoot = true; 2534 info.shadowRoot = true;
2514 fragmentElement.classList.add("shadow-root"); 2535 fragmentElement.classList.add("shadow-root");
2515 } 2536 }
2516 } 2537 }
2517 fragmentElement.textContent = node.nodeNameInCorrectCase().colla pseWhitespace(); 2538 fragmentElement.textContent = node.nodeNameInCorrectCase().colla pseWhitespace();
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 2749
2729 /** 2750 /**
2730 * @constructor 2751 * @constructor
2731 * @param {!WebInspector.DOMModel} domModel 2752 * @param {!WebInspector.DOMModel} domModel
2732 * @param {!WebInspector.ElementsTreeOutline} treeOutline 2753 * @param {!WebInspector.ElementsTreeOutline} treeOutline
2733 */ 2754 */
2734 WebInspector.ElementsTreeUpdater = function(domModel, treeOutline) 2755 WebInspector.ElementsTreeUpdater = function(domModel, treeOutline)
2735 { 2756 {
2736 domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._n odeInserted, this); 2757 domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._n odeInserted, this);
2737 domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._no deRemoved, this); 2758 domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._no deRemoved, this);
2738 domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._a ttributesUpdated, this); 2759 domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._a ttributeModified, this);
2739 domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._at tributesUpdated, this); 2760 domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._at tributeRemoved, this);
2740 domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified , this._characterDataModified, this); 2761 domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified , this._characterDataModified, this);
2741 domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this ._documentUpdated, this); 2762 domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this ._documentUpdated, this);
2742 domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated , this._childNodeCountUpdated, this); 2763 domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated , this._childNodeCountUpdated, this);
2743 2764
2744 this._domModel = domModel; 2765 this._domModel = domModel;
2745 this._treeOutline = treeOutline; 2766 this._treeOutline = treeOutline;
2746 /** @type {!Set.<!WebInspector.DOMNode>} */ 2767 /** @type {!Map.<!WebInspector.DOMNode, !WebInspector.ElementsTreeUpdater.Re cord>} */
2747 this._recentlyModifiedNodes = new Set(); 2768 this._recentlyModifiedNodes = new Map();
2748 /** @type {!Set.<!WebInspector.DOMNode>} */ 2769 /** @type {!Map.<!WebInspector.DOMNode, !WebInspector.ElementsTreeUpdater.Re cord>} */
2749 this._recentlyModifiedParentNodes = new Set(); 2770 this._recentlyModifiedParentNodes = new Map();
2750 } 2771 }
2751 2772
2752 WebInspector.ElementsTreeUpdater.prototype = { 2773 WebInspector.ElementsTreeUpdater.prototype = {
2753 dispose: function() 2774 dispose: function()
2754 { 2775 {
2755 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInse rted, this._nodeInserted, this); 2776 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInse rted, this._nodeInserted, this);
2756 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemo ved, this._nodeRemoved, this); 2777 this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemo ved, this._nodeRemoved, this);
2757 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModi fied, this._attributesUpdated, this); 2778 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModi fied, this._attributeModified, this);
2758 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemo ved, this._attributesUpdated, this); 2779 this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemo ved, this._attributeRemoved, this);
2759 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Characte rDataModified, this._characterDataModified, this); 2780 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Characte rDataModified, this._characterDataModified, this);
2760 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Document Updated, this._documentUpdated, this); 2781 this._domModel.removeEventListener(WebInspector.DOMModel.Events.Document Updated, this._documentUpdated, this);
2761 this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNod eCountUpdated, this._childNodeCountUpdated, this); 2782 this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNod eCountUpdated, this._childNodeCountUpdated, this);
2762 }, 2783 },
2763 2784
2764 /** 2785 /**
2765 * @param {?WebInspector.DOMNode} parentNode 2786 * @param {?WebInspector.DOMNode} parentNode
2787 * @param {!WebInspector.ElementsTreeUpdater.Record.ChangeType} changeType
2788 * @param {string|!WebInspector.DOMNode=} relatedTarget
2766 */ 2789 */
2767 _parentNodeModified: function(parentNode) 2790 _parentNodeModified: function(parentNode, changeType, relatedTarget)
2768 { 2791 {
2769 if (!parentNode) 2792 if (!parentNode)
2770 return; 2793 return;
2771 this._recentlyModifiedParentNodes.add(parentNode); 2794 var record = this._recentlyModifiedParentNodes.get(parentNode);
2795 if (!record) {
2796 record = new WebInspector.ElementsTreeUpdater.Record();
2797 this._recentlyModifiedParentNodes.set(parentNode, record);
2798 }
2799 record.merge(parentNode, changeType, relatedTarget);
2772 2800
2773 var treeElement = this._treeOutline.findTreeElement(parentNode); 2801 var treeElement = this._treeOutline.findTreeElement(parentNode);
2774 if (treeElement) { 2802 if (treeElement) {
2775 var oldHasChildren = treeElement.hasChildren; 2803 var oldHasChildren = treeElement.hasChildren;
2776 var oldShowInlineText = treeElement._showInlineText(); 2804 var oldShowInlineText = treeElement._showInlineText();
2777 treeElement._updateHasChildren(); 2805 treeElement._updateHasChildren();
2778 if (treeElement.hasChildren !== oldHasChildren || oldShowInlineText || treeElement._showInlineText()) 2806 if (treeElement.hasChildren !== oldHasChildren || oldShowInlineText || treeElement._showInlineText())
2779 this._nodeModified(parentNode); 2807 this._nodeModified(parentNode, changeType, relatedTarget);
2780 } 2808 }
2781 2809
2782 if (this._treeOutline._visible) 2810 if (this._treeOutline._visible)
2783 this._updateModifiedNodesSoon(); 2811 this._updateModifiedNodesSoon();
2784 }, 2812 },
2785 2813
2786 /** 2814 /**
2787 * @param {!WebInspector.DOMNode} node 2815 * @param {!WebInspector.DOMNode} node
2816 * @param {!WebInspector.ElementsTreeUpdater.Record.ChangeType} changeType
2817 * @param {string|!WebInspector.DOMNode=} relatedTarget
2788 */ 2818 */
2789 _nodeModified: function(node) 2819 _nodeModified: function(node, changeType, relatedTarget)
2790 { 2820 {
2791 this._recentlyModifiedNodes.add(node); 2821 var record = this._recentlyModifiedNodes.get(node);
2822 if (!record) {
2823 record = new WebInspector.ElementsTreeUpdater.Record();
2824 this._recentlyModifiedNodes.set(node, record);
2825 }
2826 record.merge(node, changeType, relatedTarget);
2792 if (this._treeOutline._visible) 2827 if (this._treeOutline._visible)
2793 this._updateModifiedNodesSoon(); 2828 this._updateModifiedNodesSoon();
2794 }, 2829 },
2795 2830
2796 /** 2831 /**
2797 * @param {!WebInspector.Event} event 2832 * @param {!WebInspector.Event} event
2798 */ 2833 */
2799 _documentUpdated: function(event) 2834 _documentUpdated: function(event)
2800 { 2835 {
2801 var inspectedRootDocument = event.data; 2836 var inspectedRootDocument = event.data;
2802 2837
2803 this._reset(); 2838 this._reset();
2804 2839
2805 if (!inspectedRootDocument) 2840 if (!inspectedRootDocument)
2806 return; 2841 return;
2807 2842
2808 this._treeOutline.rootDOMNode = inspectedRootDocument; 2843 this._treeOutline.rootDOMNode = inspectedRootDocument;
2809 }, 2844 },
2810 2845
2811 /** 2846 /**
2812 * @param {!WebInspector.Event} event 2847 * @param {!WebInspector.Event} event
2813 */ 2848 */
2814 _attributesUpdated: function(event) 2849 _attributeModified: function(event)
2815 { 2850 {
2816 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node); 2851 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2817 this._nodeModified(node); 2852 this._nodeModified(node, WebInspector.ElementsTreeUpdater.Record.ChangeT ype.AttrModified, event.data.name);
pfeldman 2014/11/07 12:54:15 Lets inline record creation here.
apavlov 2014/11/10 09:52:56 This will result in one record per single DOM upda
2818 }, 2853 },
2819 2854
2820 /** 2855 /**
2856 * @param {!WebInspector.Event} event
2857 */
2858 _attributeRemoved: function(event)
2859 {
2860 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2861 this._nodeModified(node, WebInspector.ElementsTreeUpdater.Record.ChangeT ype.AttrRemoved, event.data.name);
2862 },
2863
2864 /**
2821 * @param {!WebInspector.Event} event 2865 * @param {!WebInspector.Event} event
2822 */ 2866 */
2823 _characterDataModified: function(event) 2867 _characterDataModified: function(event)
2824 { 2868 {
2825 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2869 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2826 this._parentNodeModified(node.parentNode); 2870 this._parentNodeModified(node.parentNode, WebInspector.ElementsTreeUpdat er.Record.ChangeType.CharDataModified, node);
2827 this._nodeModified(node); 2871 this._nodeModified(node, WebInspector.ElementsTreeUpdater.Record.ChangeT ype.CharDataModified);
2828 }, 2872 },
2829 2873
2830 /** 2874 /**
2831 * @param {!WebInspector.Event} event 2875 * @param {!WebInspector.Event} event
2832 */ 2876 */
2833 _nodeInserted: function(event) 2877 _nodeInserted: function(event)
2834 { 2878 {
2835 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2879 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2836 this._parentNodeModified(node.parentNode); 2880 this._parentNodeModified(node.parentNode, WebInspector.ElementsTreeUpdat er.Record.ChangeType.NodeInserted, node);
2837 }, 2881 },
2838 2882
2839 /** 2883 /**
2840 * @param {!WebInspector.Event} event 2884 * @param {!WebInspector.Event} event
2841 */ 2885 */
2842 _nodeRemoved: function(event) 2886 _nodeRemoved: function(event)
2843 { 2887 {
2844 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node); 2888 var node = /** @type {!WebInspector.DOMNode} */ (event.data.node);
2845 var parentNode = /** @type {!WebInspector.DOMNode} */ (event.data.parent ); 2889 var parentNode = /** @type {!WebInspector.DOMNode} */ (event.data.parent );
2846 this._treeOutline._resetClipboardIfNeeded(node); 2890 this._treeOutline._resetClipboardIfNeeded(node);
2847 this._parentNodeModified(parentNode); 2891 this._parentNodeModified(parentNode, WebInspector.ElementsTreeUpdater.Re cord.ChangeType.ChildNodeRemoved);
2848 }, 2892 },
2849 2893
2850 /** 2894 /**
2851 * @param {!WebInspector.Event} event 2895 * @param {!WebInspector.Event} event
2852 */ 2896 */
2853 _childNodeCountUpdated: function(event) 2897 _childNodeCountUpdated: function(event)
2854 { 2898 {
2855 var node = /** @type {!WebInspector.DOMNode} */ (event.data); 2899 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
2856 this._parentNodeModified(node); 2900 this._parentNodeModified(node, WebInspector.ElementsTreeUpdater.Record.C hangeType.ChildNodeCountUpdated);
pfeldman 2014/11/07 12:54:15 Lets not use this signal.
apavlov 2014/11/10 09:52:56 Done.
2857 }, 2901 },
2858 2902
2859 _updateModifiedNodesSoon: function() 2903 _updateModifiedNodesSoon: function()
2860 { 2904 {
2861 if (this._updateModifiedNodesTimeout) 2905 if (this._updateModifiedNodesTimeout)
2862 return; 2906 return;
2863 this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes. bind(this), 50); 2907 this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes. bind(this), 50);
2864 }, 2908 },
2865 2909
2866 _updateModifiedNodes: function() 2910 _updateModifiedNodes: function()
2867 { 2911 {
2868 if (this._updateModifiedNodesTimeout) { 2912 if (this._updateModifiedNodesTimeout) {
2869 clearTimeout(this._updateModifiedNodesTimeout); 2913 clearTimeout(this._updateModifiedNodesTimeout);
2870 delete this._updateModifiedNodesTimeout; 2914 delete this._updateModifiedNodesTimeout;
2871 } 2915 }
2872 2916
2873 var updatedNodes = this._recentlyModifiedNodes.valuesArray().concat(this ._recentlyModifiedParentNodes.valuesArray()); 2917 var updatedNodes = this._recentlyModifiedNodes.keysArray().concat(this._ recentlyModifiedParentNodes.keysArray());
2874 var hidePanelWhileUpdating = updatedNodes.length > 10; 2918 var hidePanelWhileUpdating = updatedNodes.length > 10;
2875 if (hidePanelWhileUpdating) { 2919 if (hidePanelWhileUpdating) {
2876 var treeOutlineContainerElement = this._treeOutline.element.parentNo de; 2920 var treeOutlineContainerElement = this._treeOutline.element.parentNo de;
2877 var originalScrollTop = treeOutlineContainerElement ? treeOutlineCon tainerElement.scrollTop : 0; 2921 var originalScrollTop = treeOutlineContainerElement ? treeOutlineCon tainerElement.scrollTop : 0;
2878 this._treeOutline._element.classList.add("hidden"); 2922 this._treeOutline._element.classList.add("hidden");
2879 } 2923 }
2880 2924
2881 if (this._treeOutline._rootDOMNode && this._recentlyModifiedParentNodes. has(this._treeOutline._rootDOMNode)) { 2925 if (this._treeOutline._rootDOMNode && this._recentlyModifiedParentNodes. has(this._treeOutline._rootDOMNode)) {
2882 // Document's children have changed, perform total update. 2926 // Document's children have changed, perform total update.
2883 this._treeOutline.update(); 2927 this._treeOutline.update();
2884 } else { 2928 } else {
2885 var nodes = this._recentlyModifiedNodes.valuesArray(); 2929 var highlightDOMUpdates = WebInspector.settings.highlightDOMUpdates. get();
2930 var nodes = this._recentlyModifiedNodes.keysArray();
2886 for (var i = 0, size = nodes.length; i < size; ++i) { 2931 for (var i = 0, size = nodes.length; i < size; ++i) {
2887 var nodeItem = this._treeOutline.findTreeElement(nodes[i]); 2932 var nodeItem = this._treeOutline.findTreeElement(nodes[i]);
2888 if (nodeItem) 2933 if (nodeItem)
2889 nodeItem.updateTitle(); 2934 nodeItem.updateTitle(false, highlightDOMUpdates ? this._rece ntlyModifiedNodes.get(nodes[i]) : undefined);
pfeldman 2014/11/07 12:54:15 updateTitle can reach out for it on its own
apavlov 2014/11/10 09:52:56 Done.
2890 } 2935 }
2891 2936
2892 var parentNodes = this._recentlyModifiedParentNodes.valuesArray(); 2937 var parentNodes = this._recentlyModifiedParentNodes.keysArray();
2893 for (var i = 0, size = parentNodes.length; i < size; ++i) { 2938 for (var i = 0, size = parentNodes.length; i < size; ++i) {
2894 var parentNodeItem = this._treeOutline.findTreeElement(parentNod es[i]); 2939 var parentNodeItem = this._treeOutline.findTreeElement(parentNod es[i]);
2895 if (parentNodeItem && parentNodeItem.populated) 2940 if (parentNodeItem && parentNodeItem.populated)
2896 parentNodeItem.updateChildren(); 2941 parentNodeItem.updateChildren(false, highlightDOMUpdates ? t his._recentlyModifiedParentNodes.get(parentNodes[i]) : undefined);
pfeldman 2014/11/07 12:54:16 ditto
apavlov 2014/11/10 09:52:56 Done.
2897 } 2942 }
2898 } 2943 }
2899 2944
2900 if (hidePanelWhileUpdating) { 2945 if (hidePanelWhileUpdating) {
2901 this._treeOutline._element.classList.remove("hidden"); 2946 this._treeOutline._element.classList.remove("hidden");
2902 if (originalScrollTop) 2947 if (originalScrollTop)
2903 treeOutlineContainerElement.scrollTop = originalScrollTop; 2948 treeOutlineContainerElement.scrollTop = originalScrollTop;
2904 this._treeOutline.updateSelection(); 2949 this._treeOutline.updateSelection();
2905 } 2950 }
2906 this._recentlyModifiedNodes.clear(); 2951 this._recentlyModifiedNodes.clear();
2907 this._recentlyModifiedParentNodes.clear(); 2952 this._recentlyModifiedParentNodes.clear();
2908 this._treeOutline._fireElementsTreeUpdated(updatedNodes); 2953 this._treeOutline._fireElementsTreeUpdated(updatedNodes);
2909 }, 2954 },
2910 2955
2911 _reset: function() 2956 _reset: function()
2912 { 2957 {
2913 this._treeOutline.rootDOMNode = null; 2958 this._treeOutline.rootDOMNode = null;
2914 this._treeOutline.selectDOMNode(null, false); 2959 this._treeOutline.selectDOMNode(null, false);
2915 this._domModel.hideDOMNodeHighlight(); 2960 this._domModel.hideDOMNodeHighlight();
2916 this._recentlyModifiedNodes.clear(); 2961 this._recentlyModifiedNodes.clear();
2917 this._recentlyModifiedParentNodes.clear(); 2962 this._recentlyModifiedParentNodes.clear();
2918 delete this._treeOutline._clipboardNodeData; 2963 delete this._treeOutline._clipboardNodeData;
2919 } 2964 }
2920 } 2965 }
2921 2966
2922 /** 2967 /**
2923 * @constructor 2968 * @constructor
2969 */
2970 WebInspector.ElementsTreeUpdater.Record = function()
2971 {
2972 this._removedAttributeCount = 0;
2973 }
2974
2975 WebInspector.ElementsTreeUpdater.Record.prototype = {
pfeldman 2014/11/07 12:54:15 Since you merge those, I'd call it UpdateInfo
apavlov 2014/11/10 09:52:56 Done.
2976 /**
2977 * @param {!WebInspector.DOMNode} node
2978 * @param {!WebInspector.ElementsTreeUpdater.Record.ChangeType} changeType
2979 * @param {!WebInspector.DOMNode|string|undefined} relatedTarget
2980 */
2981 merge: function(node, changeType, relatedTarget)
2982 {
2983 var attrName;
2984 switch (changeType) {
2985 case WebInspector.ElementsTreeUpdater.Record.ChangeType.AttrModified:
2986 attrName = /** @type {string} */ (relatedTarget);
2987 if (this.removedAttributes && this.removedAttributes.has(attrName)) {
2988 this.removedAttributes.delete(attrName);
2989 --this._removedAttributeCount;
2990 }
2991 if (!this.modifiedAttributes)
pfeldman 2014/11/07 12:54:15 make them all private.
apavlov 2014/11/10 09:52:56 Done.
2992 this.modifiedAttributes = /** @type {!Set.<string>} */ (new Set( ));
2993 this.modifiedAttributes.add(attrName);
2994 break;
2995 case WebInspector.ElementsTreeUpdater.Record.ChangeType.AttrRemoved:
2996 attrName = /** @type {string} */ (relatedTarget);
2997 if (this.modifiedAttributes && this.modifiedAttributes.has(attrName) )
2998 this.modifiedAttributes.delete(attrName);
2999 if (!this.removedAttributes)
3000 this.removedAttributes = /** @type {!Set.<string>} */ (new Set() );
3001 this.removedAttributes.add(attrName);
3002 ++this._removedAttributeCount;
3003 break;
3004 case WebInspector.ElementsTreeUpdater.Record.ChangeType.NodeInserted:
3005 if (!this.insertedNodes)
3006 this.insertedNodes = /** @type {!Set.<!WebInspector.DOMNode>} */ (new Set());
3007 this.insertedNodes.add(/** @type {!WebInspector.DOMNode} */ (related Target));
3008 break;
3009 case WebInspector.ElementsTreeUpdater.Record.ChangeType.CharDataModified :
3010 this._charDataModified = true;
3011 break;
3012 case WebInspector.ElementsTreeUpdater.Record.ChangeType.ChildNodeRemoved :
3013 case WebInspector.ElementsTreeUpdater.Record.ChangeType.ChildNodeCountUp dated:
3014 this._hasChangedChildren = true;
3015 break;
3016 default:
3017 console.error("Invalid change type: " + changeType);
3018 }
3019 },
3020
3021 /**
3022 * @param {string} attributeName
3023 * @return {boolean}
3024 */
3025 isAttributeModified: function(attributeName)
3026 {
3027 return this.modifiedAttributes && this.modifiedAttributes.has(attributeN ame);
3028 },
3029
3030 /**
3031 * @return {boolean}
3032 */
3033 hasRemovedAttributes: function()
3034 {
3035 return !!this._removedAttributeCount;
3036 },
3037
3038 /**
3039 * @return {boolean}
3040 */
3041 hasInsertedNodes: function()
3042 {
3043 return !!this.insertedNodes && !!this.insertedNodes.size;
3044 },
3045
3046 /**
3047 * @return {boolean}
3048 */
3049 isCharDataModified: function()
3050 {
3051 return !!this._charDataModified;
3052 },
3053
3054 /**
3055 * @return {boolean}
3056 */
3057 isNodeInserted: function(node)
3058 {
3059 return !!this.insertedNodes && this.insertedNodes.has(node);
3060 },
3061
3062 /**
3063 * @return {boolean}
3064 */
3065 hasChangedChildren: function()
3066 {
3067 return !!this._hasChangedChildren;
3068 }
3069 }
3070
3071 /**
3072 * @enum {number}
3073 */
3074 WebInspector.ElementsTreeUpdater.Record.ChangeType = {
3075 AttrModified: 1,
3076 AttrRemoved: 2,
3077 CharDataModified: 3,
3078 NodeInserted: 4,
3079 ChildNodeRemoved: 5,
3080 ChildNodeCountUpdated: 6
3081 }
3082
3083 /**
3084 * @constructor
2924 * @implements {WebInspector.Renderer} 3085 * @implements {WebInspector.Renderer}
2925 */ 3086 */
2926 WebInspector.ElementsTreeOutline.Renderer = function() 3087 WebInspector.ElementsTreeOutline.Renderer = function()
2927 { 3088 {
2928 } 3089 }
2929 3090
2930 WebInspector.ElementsTreeOutline.Renderer.prototype = { 3091 WebInspector.ElementsTreeOutline.Renderer.prototype = {
2931 /** 3092 /**
2932 * @param {!Object} object 3093 * @param {!Object} object
2933 * @return {!Promise.<!Element>} 3094 * @return {!Promise.<!Element>}
(...skipping 30 matching lines...) Expand all
2964 treeOutline.rootDOMNode = node; 3125 treeOutline.rootDOMNode = node;
2965 if (!treeOutline.children[0].hasChildren) 3126 if (!treeOutline.children[0].hasChildren)
2966 treeOutline._element.classList.add("single-node"); 3127 treeOutline._element.classList.add("single-node");
2967 treeOutline.setVisible(true); 3128 treeOutline.setVisible(true);
2968 treeOutline.element.treeElementForTest = treeOutline.children[0] ; 3129 treeOutline.element.treeElementForTest = treeOutline.children[0] ;
2969 resolve(treeOutline.element); 3130 resolve(treeOutline.element);
2970 } 3131 }
2971 } 3132 }
2972 } 3133 }
2973 } 3134 }
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