Skip to content
Permalink
Browse files
Web Inspector: Elements Tab DOM Tree does not update when a top-level…
… item in the DOM tree is added/removed

https://bugs.webkit.org/show_bug.cgi?id=227774
rdar://31137058

Reviewed by Devin Rousso.

While unlikely to affect a majority of users, it is possible to call `document.write("")` followed by `document.close()`
to rewrite the entire documents contents, which means top-level items in the DOM tree outline view will need to be
removed and inserted.

Previously, updates were only performed for node insertion/deletion when that node had a parent node represented in the
DOM tree. However, this means for the above example where one or more nodes will never be represented by a parent node
in the DOM tree no update will be performed to reflect those insertions/deletions. In those cases, we should forgo the
per-item updating and instead update the entire tree, similar to how we handle all other insertions/deletions where we
will update all children of the updated node's parent.

* Source/WebInspectorUI/UserInterface/Views/DOMTreeUpdater.js:
(WI.DOMTreeUpdater.prototype._updateModifiedNodes):

Canonical link: https://commits.webkit.org/254062@main
  • Loading branch information
patrickangle committed Sep 1, 2022
1 parent 5c6c14b commit f6c53589931096ae9cbc668da3bae4dd4e789dc0
Showing 1 changed file with 31 additions and 17 deletions.
@@ -121,40 +121,54 @@ WI.DOMTreeUpdater.prototype = {

_updateModifiedNodes: function()
{
let documentNeedsUpdated = false;

// Update for insertions and deletions before attribute modifications. This ensures
// tree elements get created for newly attached children before we try to update them.
let parentElementsToUpdate = new Set;
let markNodeParentForUpdate = (value, key, map) => {
if (documentNeedsUpdated)
return;

let parentNode = value.parent;
if (parentNode.nodeType() === Node.DOCUMENT_NODE) {
documentNeedsUpdated = true;
return;
}

let parentTreeElement = this._treeOutline.findTreeElement(parentNode);
if (parentTreeElement)
parentElementsToUpdate.add(parentTreeElement);
};
this._recentlyInsertedNodes.forEach(markNodeParentForUpdate);
this._recentlyDeletedNodes.forEach(markNodeParentForUpdate);

for (let parentTreeElement of parentElementsToUpdate) {
if (parentTreeElement.treeOutline && parentTreeElement.listItemElement) {
parentTreeElement.updateTitle();
parentTreeElement.updateChildren();
if (documentNeedsUpdated)
this._treeOutline.update();
else {
for (let parentTreeElement of parentElementsToUpdate) {
if (parentTreeElement.treeOutline && parentTreeElement.listItemElement) {
parentTreeElement.updateTitle();
parentTreeElement.updateChildren();
}
}
}

for (let node of this._recentlyModifiedNodes.values()) {
let nodeTreeElement = this._treeOutline.findTreeElement(node);
if (!nodeTreeElement)
continue;

for (let [attribute, nodes] of this._recentlyModifiedAttributes.entries()) {
// Don't report textContent changes as attribute modifications.
if (attribute === this._textContentAttributeSymbol)
for (let node of this._recentlyModifiedNodes.values()) {
let nodeTreeElement = this._treeOutline.findTreeElement(node);
if (!nodeTreeElement)
continue;

if (nodes.has(node))
nodeTreeElement.attributeDidChange(attribute);
}
for (let [attribute, nodes] of this._recentlyModifiedAttributes.entries()) {
// Don't report textContent changes as attribute modifications.
if (attribute === this._textContentAttributeSymbol)
continue;

nodeTreeElement.updateTitle();
if (nodes.has(node))
nodeTreeElement.attributeDidChange(attribute);
}

nodeTreeElement.updateTitle();
}
}

this._recentlyInsertedNodes.clear();

0 comments on commit f6c5358

Please sign in to comment.