| 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();
|
|
|
|
|