OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |