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

Unified Diff: Source/core/dom/Element.cpp

Issue 22508006: Refactor adding and removing named and IDed elements (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address review comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/dom/Element.h ('k') | Source/core/dom/TreeScope.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/Element.cpp
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index eac6701bb21300997e9e7664766516463f8ec1e5..fb140aa7121841e15f0e4c28faafb9f052580128 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -1238,21 +1238,28 @@ Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertio
if (isUpgradedCustomElement() && inDocument())
CustomElement::didEnterDocument(this, document());
- TreeScope* scope = insertionPoint->treeScope();
- if (scope != treeScope())
+ if (insertionPoint->treeScope() != treeScope())
return InsertionDone;
+ HTMLDocument* newDocument = inDocument() && !isInShadowTree() && document()->isHTMLDocument() ? toHTMLDocument(document()) : 0;
+
const AtomicString& idValue = getIdAttribute();
- if (!idValue.isNull())
- updateId(scope, nullAtom, idValue);
+ if (!idValue.isNull()) {
+ updateIdForTreeScope(treeScope(), nullAtom, idValue);
+ if (newDocument)
+ updateIdForDocument(newDocument, nullAtom, idValue);
+ }
const AtomicString& nameValue = getNameAttribute();
- if (!nameValue.isNull())
- updateName(nullAtom, nameValue);
+ if (!nameValue.isNull()) {
+ updateNameForTreeScope(treeScope(), nullAtom, nameValue);
+ if (newDocument)
+ updateNameForDocument(newDocument, nullAtom, nameValue);
+ }
if (hasTagName(labelTag)) {
- if (scope->shouldCacheLabelsByForAttribute())
- updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
+ if (treeScope()->shouldCacheLabelsByForAttribute())
+ updateLabel(treeScope(), nullAtom, fastGetAttribute(forAttr));
}
if (parentElement() && parentElement()->isInCanvasSubtree())
@@ -1264,6 +1271,7 @@ Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertio
void Element::removedFrom(ContainerNode* insertionPoint)
{
bool wasInDocument = insertionPoint->inDocument();
+ bool wasInShadowTree = isInShadowTree(); // Of course, we might still be in a shadow tree...
if (Element* before = pseudoElement(BEFORE))
before->removedFrom(insertionPoint);
@@ -1284,22 +1292,31 @@ void Element::removedFrom(ContainerNode* insertionPoint)
setSavedLayerScrollOffset(IntSize());
if (insertionPoint->isInTreeScope() && treeScope() == document()) {
+ TreeScope* oldScope = insertionPoint->treeScope();
+ HTMLDocument* oldDocument = wasInDocument && !wasInShadowTree && oldScope->documentScope()->isHTMLDocument() ? toHTMLDocument(oldScope->documentScope()) : 0;
+
const AtomicString& idValue = getIdAttribute();
- if (!idValue.isNull())
- updateId(insertionPoint->treeScope(), idValue, nullAtom);
+ if (!idValue.isNull()) {
+ updateIdForTreeScope(oldScope, idValue, nullAtom);
+ if (oldDocument)
+ updateIdForDocument(oldDocument, idValue, nullAtom);
+ }
const AtomicString& nameValue = getNameAttribute();
- if (!nameValue.isNull())
- updateName(nameValue, nullAtom);
+ if (!nameValue.isNull()) {
+ updateNameForTreeScope(oldScope, nameValue, nullAtom);
+ if (oldDocument)
+ updateNameForDocument(oldDocument, nameValue, nullAtom);
+ }
if (hasTagName(labelTag)) {
- TreeScope* treeScope = insertionPoint->treeScope();
- if (treeScope->shouldCacheLabelsByForAttribute())
- updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
+ if (oldScope->shouldCacheLabelsByForAttribute())
+ updateLabel(oldScope, fastGetAttribute(forAttr), nullAtom);
}
}
ContainerNode::removedFrom(insertionPoint);
+
if (wasInDocument) {
if (hasPendingResources())
document()->accessSVGExtensions()->removeElementFromPendingResources(this);
@@ -2760,19 +2777,47 @@ bool Element::hasNamedNodeMap() const
}
#endif
-inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
+void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
{
- if (!inDocument() || isInShadowTree())
+ if (!isInTreeScope())
return;
if (oldName == newName)
return;
+ updateNameForTreeScope(treeScope(), oldName, newName);
+
+ if (!inDocument() || isInShadowTree())
+ return;
+
+ Document* htmlDocument = document();
+ if (!htmlDocument->isHTMLDocument())
+ return;
+
+ updateNameForDocument(toHTMLDocument(htmlDocument), oldName, newName);
+}
+
+void Element::updateNameForTreeScope(TreeScope* scope, const AtomicString& oldName, const AtomicString& newName)
+{
+ ASSERT(isInTreeScope());
+ ASSERT(oldName != newName);
+
+ if (!oldName.isEmpty())
+ scope->removeElementByName(oldName, this);
+ if (!newName.isEmpty())
+ scope->addElementByName(newName, this);
+}
+
+void Element::updateNameForDocument(HTMLDocument* document, const AtomicString& oldName, const AtomicString& newName)
+{
+ ASSERT(inDocument() && !isInShadowTree());
+ ASSERT(oldName != newName);
+
if (shouldRegisterAsNamedItem())
updateNamedItemRegistration(oldName, newName);
}
-inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
+void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
{
if (!isInTreeScope())
return;
@@ -2780,10 +2825,19 @@ inline void Element::updateId(const AtomicString& oldId, const AtomicString& new
if (oldId == newId)
return;
- updateId(treeScope(), oldId, newId);
+ updateIdForTreeScope(treeScope(), oldId, newId);
+
+ if (!inDocument() || isInShadowTree())
+ return;
+
+ Document* htmlDocument = document();
+ if (!htmlDocument->isHTMLDocument())
+ return;
+
+ updateIdForDocument(toHTMLDocument(htmlDocument), oldId, newId);
}
-inline void Element::updateId(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
+void Element::updateIdForTreeScope(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
{
ASSERT(isInTreeScope());
ASSERT(oldId != newId);
@@ -2792,6 +2846,12 @@ inline void Element::updateId(TreeScope* scope, const AtomicString& oldId, const
scope->removeElementById(oldId, this);
if (!newId.isEmpty())
scope->addElementById(newId, this);
+}
+
+void Element::updateIdForDocument(HTMLDocument* document, const AtomicString& oldId, const AtomicString& newId)
+{
+ ASSERT(inDocument() && !isInShadowTree());
+ ASSERT(oldId != newId);
if (shouldRegisterAsExtraNamedItem())
updateExtraNamedItemRegistration(oldId, newId);
@@ -2882,8 +2942,7 @@ void Element::didMoveToNewDocument(Document* oldDocument)
void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
{
- if (!document()->isHTMLDocument())
- return;
+ ASSERT(document()->isHTMLDocument());
if (!oldName.isEmpty())
toHTMLDocument(document())->removeNamedItem(oldName);
@@ -2894,8 +2953,7 @@ void Element::updateNamedItemRegistration(const AtomicString& oldName, const Ato
void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
{
- if (!document()->isHTMLDocument())
- return;
+ ASSERT(document()->isHTMLDocument());
if (!oldId.isEmpty())
toHTMLDocument(document())->removeExtraNamedItem(oldId);
@@ -3033,6 +3091,10 @@ void Element::cloneAttributesFromElement(const Element& other)
return;
}
+ // We can't update window and document's named item maps since the presence of image and object elements depend on other attributes and children.
+ // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
+ ASSERT(!inDocument());
+
const AtomicString& oldID = getIdAttribute();
const AtomicString& newID = other.getIdAttribute();
« no previous file with comments | « Source/core/dom/Element.h ('k') | Source/core/dom/TreeScope.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698