Merge from Chromium at DEPS revision r212014

This commit was generated by merge_to_master.py.

Change-Id: Ib07d03553a1e81485ac4ffc92b91e977c4875409
diff --git a/Source/core/dom/ActiveDOMObject.h b/Source/core/dom/ActiveDOMObject.h
index bfb47db..f047cea 100644
--- a/Source/core/dom/ActiveDOMObject.h
+++ b/Source/core/dom/ActiveDOMObject.h
@@ -28,8 +28,8 @@
 #define ActiveDOMObject_h
 
 #include "core/dom/ContextLifecycleObserver.h"
-#include <wtf/Assertions.h>
-#include <wtf/Forward.h>
+#include "wtf/Assertions.h"
+#include "wtf/Forward.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Attr.cpp b/Source/core/dom/Attr.cpp
index 2d56cb2..70afc51 100644
--- a/Source/core/dom/Attr.cpp
+++ b/Source/core/dom/Attr.cpp
@@ -98,7 +98,7 @@
 
     if ((prefix == xmlnsAtom && namespaceURI() != XMLNSNames::xmlnsNamespaceURI)
         || static_cast<Attr*>(this)->qualifiedName() == xmlnsAtom) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return;
     }
 
@@ -135,9 +135,9 @@
         m_element->didModifyAttribute(qualifiedName(), value);
 }
 
-void Attr::setNodeValue(const String& v, ExceptionCode& ec)
+void Attr::setNodeValue(const String& v)
 {
-    setValue(v, ec);
+    setValue(v, IGNORE_EXCEPTION);
 }
 
 PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
diff --git a/Source/core/dom/Attr.h b/Source/core/dom/Attr.h
index 5f6004e..82a7e13 100644
--- a/Source/core/dom/Attr.h
+++ b/Source/core/dom/Attr.h
@@ -78,8 +78,8 @@
     virtual void setPrefix(const AtomicString&, ExceptionCode&);
 
     virtual String nodeValue() const OVERRIDE { return value(); }
-    virtual void setNodeValue(const String&, ExceptionCode&);
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual void setNodeValue(const String&);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
 
     virtual bool isAttributeNode() const { return true; }
     virtual bool childTypeAllowed(NodeType) const;
diff --git a/Source/core/dom/CharacterData.cpp b/Source/core/dom/CharacterData.cpp
index e57d138..1a25e91 100644
--- a/Source/core/dom/CharacterData.cpp
+++ b/Source/core/dom/CharacterData.cpp
@@ -82,8 +82,8 @@
     ASSERT(!string.is8Bit() || string.containsOnlyLatin1()); // Latin-1 doesn't have unbreakable boundaries.
     if (characterLengthLimit < characterLength && !string.is8Bit()) {
         NonSharedCharacterBreakIterator it(string.characters16() + offset, (characterLengthLimit + 2 > characterLength) ? characterLength : characterLengthLimit + 2);
-        if (!isTextBreak(it, characterLengthLimit))
-            characterLengthLimit = textBreakPreceding(it, characterLengthLimit);
+        if (!it.isBreak(characterLengthLimit))
+            characterLengthLimit = it.preceding(characterLengthLimit);
     }
 
     if (!characterLengthLimit)
@@ -191,7 +191,7 @@
     return m_data.containsOnlyWhitespace();
 }
 
-void CharacterData::setNodeValue(const String& nodeValue, ExceptionCode&)
+void CharacterData::setNodeValue(const String& nodeValue)
 {
     setData(nodeValue);
 }
@@ -236,10 +236,10 @@
 {
     ec = 0;
 
-    // INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than the number of 16-bit
+    // IndexSizeError: Raised if the specified offset is negative or greater than the number of 16-bit
     // units in data.
     if (offset > length()) {
-        ec = INDEX_SIZE_ERR;
+        ec = IndexSizeError;
         return;
     }
 }
diff --git a/Source/core/dom/CharacterData.h b/Source/core/dom/CharacterData.h
index f8862ba..a985c81 100644
--- a/Source/core/dom/CharacterData.h
+++ b/Source/core/dom/CharacterData.h
@@ -24,7 +24,7 @@
 #define CharacterData_h
 
 #include "core/dom/Node.h"
-#include <wtf/text/WTFString.h>
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
@@ -68,7 +68,7 @@
 
 private:
     virtual String nodeValue() const OVERRIDE FINAL;
-    virtual void setNodeValue(const String&, ExceptionCode&) OVERRIDE FINAL;
+    virtual void setNodeValue(const String&) OVERRIDE FINAL;
     virtual bool isCharacterDataNode() const OVERRIDE FINAL { return true; }
     virtual int maxCharacterOffset() const OVERRIDE FINAL;
     virtual bool offsetInCharacters() const OVERRIDE FINAL;
diff --git a/Source/core/dom/CheckedRadioButtons.cpp b/Source/core/dom/CheckedRadioButtons.cpp
index c377b7a..a628b43 100644
--- a/Source/core/dom/CheckedRadioButtons.cpp
+++ b/Source/core/dom/CheckedRadioButtons.cpp
@@ -22,7 +22,7 @@
 #include "core/dom/CheckedRadioButtons.h"
 
 #include "core/html/HTMLInputElement.h"
-#include <wtf/HashSet.h>
+#include "wtf/HashSet.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/CheckedRadioButtons.h b/Source/core/dom/CheckedRadioButtons.h
index f050faa..32bb5fe 100644
--- a/Source/core/dom/CheckedRadioButtons.h
+++ b/Source/core/dom/CheckedRadioButtons.h
@@ -21,9 +21,9 @@
 #ifndef CheckedRadioButtons_h
 #define CheckedRadioButtons_h
 
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
+#include "wtf/Forward.h"
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ChildListMutationScope.cpp b/Source/core/dom/ChildListMutationScope.cpp
index 835bed7..6acb5b1 100644
--- a/Source/core/dom/ChildListMutationScope.cpp
+++ b/Source/core/dom/ChildListMutationScope.cpp
@@ -29,16 +29,15 @@
  */
 
 #include "config.h"
-
 #include "core/dom/ChildListMutationScope.h"
 
 #include "core/dom/MutationObserverInterestGroup.h"
 #include "core/dom/MutationRecord.h"
 #include "core/dom/Node.h"
 #include "core/dom/StaticNodeList.h"
-#include <wtf/HashMap.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/StdLibExtras.h>
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/StdLibExtras.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ChildNode.idl b/Source/core/dom/ChildNode.idl
index b37f05f..c5fdbba 100644
--- a/Source/core/dom/ChildNode.idl
+++ b/Source/core/dom/ChildNode.idl
@@ -24,6 +24,6 @@
 interface ChildNode {
     [PerWorldBindings] readonly attribute Element previousElementSibling;
     [PerWorldBindings] readonly attribute Element nextElementSibling;
-    [RaisesException] void remove();
+    [RaisesException, DeliverCustomElementCallbacks] void remove();
 };
 
diff --git a/Source/core/dom/ChildNodeList.h b/Source/core/dom/ChildNodeList.h
index 34b4040..af70df3 100644
--- a/Source/core/dom/ChildNodeList.h
+++ b/Source/core/dom/ChildNodeList.h
@@ -25,7 +25,7 @@
 #define ChildNodeList_h
 
 #include "core/dom/LiveNodeList.h"
-#include <wtf/PassRefPtr.h>
+#include "wtf/PassRefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ClientRect.h b/Source/core/dom/ClientRect.h
index 329f34c..9177a3f 100644
--- a/Source/core/dom/ClientRect.h
+++ b/Source/core/dom/ClientRect.h
@@ -29,8 +29,8 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/platform/graphics/FloatRect.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ClientRectList.cpp b/Source/core/dom/ClientRectList.cpp
index 9d3ee0a..d87b696 100644
--- a/Source/core/dom/ClientRectList.cpp
+++ b/Source/core/dom/ClientRectList.cpp
@@ -57,7 +57,7 @@
 {
     if (index >= m_list.size()) {
         // FIXME: this should throw an exception.
-        // ec = INDEX_SIZE_ERR;
+        // ec = IndexSizeError;
         return 0;
     }
 
diff --git a/Source/core/dom/Comment.h b/Source/core/dom/Comment.h
index 5ef2285..6d4b768 100644
--- a/Source/core/dom/Comment.h
+++ b/Source/core/dom/Comment.h
@@ -39,7 +39,7 @@
 
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
     virtual bool childTypeAllowed(NodeType) const;
 };
 
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 1f9b351..9983a2a 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -147,34 +147,35 @@
 
 static inline ExceptionCode checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild)
 {
-    // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null
+    // Not mentioned in spec: throw NotFoundError if newChild is null
     if (!newChild)
-        return NOT_FOUND_ERR;
+        return NotFoundError;
 
     // Use common case fast path if possible.
     if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
         ASSERT(!newParent->isDocumentTypeNode());
         ASSERT(isChildTypeAllowed(newParent, newChild));
         if (containsConsideringHostElements(newChild, newParent))
-            return HIERARCHY_REQUEST_ERR;
+            return HierarchyRequestError;
         return 0;
     }
 
     // This should never happen, but also protect release builds from tree corruption.
     ASSERT(!newChild->isPseudoElement());
     if (newChild->isPseudoElement())
-        return HIERARCHY_REQUEST_ERR;
+        return HierarchyRequestError;
 
     if (newChild->inDocument() && newChild->isDocumentTypeNode())
-        return HIERARCHY_REQUEST_ERR;
+        return HierarchyRequestError;
     if (containsConsideringHostElements(newChild, newParent))
-        return HIERARCHY_REQUEST_ERR;
+        return HierarchyRequestError;
 
     if (oldChild && newParent->isDocumentNode()) {
         if (!toDocument(newParent)->canReplaceChild(newChild, oldChild))
-            return HIERARCHY_REQUEST_ERR;
-    } else if (!isChildTypeAllowed(newParent, newChild))
-        return HIERARCHY_REQUEST_ERR;
+            return HierarchyRequestError;
+    } else if (!isChildTypeAllowed(newParent, newChild)) {
+        return HierarchyRequestError;
+    }
 
     return 0;
 }
@@ -184,7 +185,7 @@
     ASSERT(!newParent->isDocumentTypeNode());
     ASSERT(isChildTypeAllowed(newParent, newChild));
     if (newChild->contains(newParent)) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return false;
     }
 
@@ -209,7 +210,7 @@
     return true;
 }
 
-bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -220,34 +221,36 @@
     ec = 0;
 
     // insertBefore(node, 0) is equivalent to appendChild(node)
-    if (!refChild)
-        return appendChild(newChild, ec, attachBehavior);
+    if (!refChild) {
+        appendChild(newChild, ec, attachBehavior);
+        return;
+    }
 
     // Make sure adding the new child is OK.
     if (!checkAddChild(this, newChild.get(), ec))
-        return false;
+        return;
 
-    // NOT_FOUND_ERR: Raised if refChild is not a child of this node
+    // NotFoundError: Raised if refChild is not a child of this node
     if (refChild->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
-        return true;
+        return;
 
     RefPtr<Node> next = refChild;
 
     NodeVector targets;
     collectChildrenAndRemoveFromOldParent(newChild.get(), targets, ec);
     if (ec)
-        return false;
+        return;
     if (targets.isEmpty())
-        return true;
+        return;
 
     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
-        return false;
+        return;
 
     InspectorInstrumentation::willInsertDOMNode(document(), this);
 
@@ -272,7 +275,6 @@
     }
 
     dispatchSubtreeModifiedEvent();
-    return true;
 }
 
 void ContainerNode::insertBeforeCommon(Node* nextChild, Node* newChild)
@@ -325,7 +327,7 @@
     ChildNodeInsertionNotifier(this).notify(newChild.get());
 }
 
-bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -336,21 +338,21 @@
     ec = 0;
 
     if (oldChild == newChild) // nothing to do
-        return true;
+        return;
 
     if (!oldChild) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     // Make sure replacing the old child with the new is ok
     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
-        return false;
+        return;
 
-    // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
+    // NotFoundError: Raised if oldChild is not a child of this node.
     if (oldChild->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     ChildListMutationScope mutation(this);
@@ -361,23 +363,23 @@
     RefPtr<Node> removedChild = oldChild;
     removeChild(oldChild, ec);
     if (ec)
-        return false;
+        return;
 
     if (next && (next->previousSibling() == newChild || next == newChild)) // nothing to do
-        return true;
+        return;
 
     // Does this one more time because removeChild() fires a MutationEvent.
     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
-        return false;
+        return;
 
     NodeVector targets;
     collectChildrenAndRemoveFromOldParent(newChild.get(), targets, ec);
     if (ec)
-        return false;
+        return;
 
     // Does this yet another check because collectChildrenAndRemoveFromOldParent() fires a MutationEvent.
     if (!checkReplaceChild(this, newChild.get(), oldChild, ec))
-        return false;
+        return;
 
     InspectorInstrumentation::willInsertDOMNode(document(), this);
 
@@ -409,7 +411,6 @@
     }
 
     dispatchSubtreeModifiedEvent();
-    return true;
 }
 
 static void willRemoveChild(Node* child)
@@ -447,7 +448,7 @@
     ChildFrameDisconnector(this).disconnect();
 }
 
-bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
+void ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
 {
     // Check that this node is not "floating".
     // If it is, it can be deleted as a side effect of sending mutation events.
@@ -457,10 +458,10 @@
 
     ec = 0;
 
-    // NOT_FOUND_ERR: Raised if oldChild is not a child of this node.
+    // NotFoundError: Raised if oldChild is not a child of this node.
     if (!oldChild || oldChild->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     RefPtr<Node> child = oldChild;
@@ -473,16 +474,16 @@
     // Events fired when blurring currently focused node might have moved this
     // child into a different parent.
     if (child->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     willRemoveChild(child.get());
 
     // Mutation events might have moved this child into a different parent.
     if (child->parentNode() != this) {
-        ec = NOT_FOUND_ERR;
-        return false;
+        ec = NotFoundError;
+        return;
     }
 
     {
@@ -495,8 +496,6 @@
         ChildNodeRemovalNotifier(this).notify(child.get());
     }
     dispatchSubtreeModifiedEvent();
-
-    return child;
 }
 
 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node* oldChild)
@@ -590,7 +589,7 @@
     dispatchSubtreeModifiedEvent();
 }
 
-bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
     RefPtr<ContainerNode> protect(this);
 
@@ -602,22 +601,22 @@
 
     // Make sure adding the new child is ok
     if (!checkAddChild(this, newChild.get(), ec))
-        return false;
+        return;
 
     if (newChild == m_lastChild) // nothing to do
-        return newChild;
+        return;
 
     NodeVector targets;
     collectChildrenAndRemoveFromOldParent(newChild.get(), targets, ec);
     if (ec)
-        return false;
+        return;
 
     if (targets.isEmpty())
-        return true;
+        return;
 
     // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
     if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), ec))
-        return false;
+        return;
 
     InspectorInstrumentation::willInsertDOMNode(document(), this);
 
@@ -644,7 +643,6 @@
     }
 
     dispatchSubtreeModifiedEvent();
-    return true;
 }
 
 void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 28dea40..377cff5 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -26,9 +26,8 @@
 
 #include "core/dom/ExceptionCodePlaceholder.h"
 #include "core/dom/Node.h"
-
-#include <wtf/OwnPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
@@ -96,10 +95,10 @@
     unsigned childNodeCount() const;
     Node* childNode(unsigned index) const;
 
-    bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
-    bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
-    bool removeChild(Node* child, ExceptionCode& = ASSERT_NO_EXCEPTION);
-    bool appendChild(PassRefPtr<Node> newChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
+    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
+    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
+    void removeChild(Node* child, ExceptionCode& = ASSERT_NO_EXCEPTION);
+    void appendChild(PassRefPtr<Node> newChild, ExceptionCode& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachNow);
 
     // These methods are only used during parsing.
     // They don't send DOM mutation events or handle reparenting.
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h
index 0ab979d..3418b31 100644
--- a/Source/core/dom/CrossThreadTask.h
+++ b/Source/core/dom/CrossThreadTask.h
@@ -34,9 +34,9 @@
 #include <memory>
 #include "core/dom/ScriptExecutionContext.h"
 #include "core/platform/CrossThreadCopier.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/TypeTraits.h>
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/TypeTraits.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/CustomElementCallbackDispatcher.cpp b/Source/core/dom/CustomElementCallbackDispatcher.cpp
index 667c6c2..10db728 100644
--- a/Source/core/dom/CustomElementCallbackDispatcher.cpp
+++ b/Source/core/dom/CustomElementCallbackDispatcher.cpp
@@ -29,46 +29,155 @@
  */
 
 #include "config.h"
-#include "CustomElementCallbackDispatcher.h"
+#include "core/dom/CustomElementCallbackDispatcher.h"
 
-#include "CustomElementCallback.h"
+#include "core/dom/CustomElementCallbackInvocation.h"
+#include "wtf/MainThread.h"
 
 namespace WebCore {
 
+size_t CustomElementCallbackDispatcher::s_elementQueueStart = 0;
+
+// The base of the stack has a null sentinel value.
+size_t CustomElementCallbackDispatcher::s_elementQueueEnd = 1;
+
 CustomElementCallbackDispatcher& CustomElementCallbackDispatcher::instance()
 {
     DEFINE_STATIC_LOCAL(CustomElementCallbackDispatcher, instance, ());
     return instance;
 }
 
-CustomElementCallbackDispatcher::ReadyInvocation::ReadyInvocation(PassRefPtr<CustomElementCallback> callback, PassRefPtr<Element> element)
-    : m_callback(callback)
-    , m_element(element)
+void CustomElementCallbackDispatcher::enqueueAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
 {
-}
-
-bool CustomElementCallbackDispatcher::dispatch()
-{
-    if (m_invocations.isEmpty())
-        return false;
-
-    do  {
-        Vector<ReadyInvocation> invocations;
-        m_invocations.swap(invocations);
-
-        for (Vector<ReadyInvocation>::iterator it = invocations.begin(); it != invocations.end(); ++it)
-            it->invoke();
-    } while (!m_invocations.isEmpty());
-
-    return true;
-}
-
-void CustomElementCallbackDispatcher::enqueueReadyCallback(CustomElementCallback* callback, Element* element)
-{
-    if (!callback->hasReady())
+    if (!callbacks->hasAttributeChangedCallback())
         return;
 
-    m_invocations.append(ReadyInvocation(callback, element));
+    CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
+    queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
+}
+
+void CustomElementCallbackDispatcher::enqueueCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
+{
+    if (!callbacks->hasCreatedCallback())
+        return;
+
+    CustomElementCallbackQueue* queue = createCallbackQueue(element);
+    queue->setOwner(currentElementQueue());
+
+    // The created callback is unique in being prepended to the front
+    // of the element queue
+    m_flattenedProcessingStack.insert(inCallbackDeliveryScope() ? s_elementQueueStart : /* skip null sentinel */ 1, queue);
+    ++s_elementQueueEnd;
+
+    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Created));
+}
+
+void CustomElementCallbackDispatcher::enqueueEnteredDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
+{
+    if (!callbacks->hasEnteredDocumentCallback())
+        return;
+
+    CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
+    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::EnteredDocument));
+}
+
+void CustomElementCallbackDispatcher::enqueueLeftDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
+{
+    if (!callbacks->hasLeftDocumentCallback())
+        return;
+
+    CustomElementCallbackQueue* queue = scheduleInCurrentElementQueue(element);
+    queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::LeftDocument));
+}
+
+// Dispatches callbacks at microtask checkpoint.
+bool CustomElementCallbackDispatcher::dispatch()
+{
+    ASSERT(isMainThread());
+    if (inCallbackDeliveryScope())
+        return false;
+
+    size_t start = 1; // skip null sentinel
+    size_t end = s_elementQueueEnd;
+
+    for (size_t i = start; i < end; i++) {
+        m_flattenedProcessingStack[i]->processInElementQueue(currentElementQueue());
+
+        // new callbacks as a result of recursion must be scheduled in
+        // a CallbackDeliveryScope which restore this queue on completion
+        ASSERT(!s_elementQueueStart);
+        ASSERT(s_elementQueueEnd == end);
+    }
+
+    s_elementQueueEnd = 1;
+    m_flattenedProcessingStack.resize(s_elementQueueEnd);
+    m_elementCallbackQueueMap.clear();
+
+    bool didWork = start < end;
+    return didWork;
+}
+
+// Dispatches callbacks when popping the processing stack.
+void CustomElementCallbackDispatcher::processElementQueueAndPop()
+{
+    instance().processElementQueueAndPop(s_elementQueueStart, s_elementQueueEnd);
+}
+
+void CustomElementCallbackDispatcher::processElementQueueAndPop(size_t start, size_t end)
+{
+    ASSERT(isMainThread());
+
+    for (size_t i = start; i < end; i++) {
+        m_flattenedProcessingStack[i]->processInElementQueue(currentElementQueue());
+
+        // process() may run script which grows and shrinks the
+        // processing stack above this entry, but the processing stack
+        // should always drop back to having this entry at the
+        // top-of-stack on exit
+        ASSERT(start == s_elementQueueStart);
+        ASSERT(end == s_elementQueueEnd);
+    }
+
+    // Pop the element queue from the processing stack
+    m_flattenedProcessingStack.resize(start);
+    s_elementQueueEnd = start;
+
+    if (start == /* allow sentinel */ 1)
+        m_elementCallbackQueueMap.clear();
+}
+
+CustomElementCallbackQueue* CustomElementCallbackDispatcher::createCallbackQueue(PassRefPtr<Element> element)
+{
+    Element* key = element.get();
+    ElementCallbackQueueMap::AddResult result = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::create(element));
+    ASSERT(result.isNewEntry);
+    return result.iterator->value.get();
+}
+
+CustomElementCallbackQueue* CustomElementCallbackDispatcher::ensureCallbackQueue(PassRefPtr<Element> element)
+{
+    Element* key = element.get();
+    ElementCallbackQueueMap::iterator it = m_elementCallbackQueueMap.find(key);
+    if (it == m_elementCallbackQueueMap.end())
+        it = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::create(element)).iterator;
+    return it->value.get();
+}
+
+// Finds or creates the callback queue for element. If the element's
+// callback queue is scheduled in an earlier processing stack frame,
+// its owner is set to the element queue on the top of the processing
+// stack. Because callback queues are processed exhaustively, this
+// effectively moves the callback queue to the top of the stack.
+CustomElementCallbackQueue* CustomElementCallbackDispatcher::scheduleInCurrentElementQueue(PassRefPtr<Element> element)
+{
+    CustomElementCallbackQueue* queue = ensureCallbackQueue(element);
+    bool isInCurrentQueue = queue->owner() == currentElementQueue();
+    if (!isInCurrentQueue) {
+        queue->setOwner(currentElementQueue());
+        m_flattenedProcessingStack.append(queue);
+        ++s_elementQueueEnd;
+    }
+    return queue;
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/CustomElementCallbackDispatcher.h b/Source/core/dom/CustomElementCallbackDispatcher.h
index 46a4f76..9b6f10d 100644
--- a/Source/core/dom/CustomElementCallbackDispatcher.h
+++ b/Source/core/dom/CustomElementCallbackDispatcher.h
@@ -31,10 +31,12 @@
 #ifndef CustomElementCallbackDispatcher_h
 #define CustomElementCallbackDispatcher_h
 
-#include "core/dom/CustomElementCallback.h"
+#include "core/dom/CustomElementCallbackQueue.h"
+#include "core/dom/CustomElementLifecycleCallbacks.h"
 #include "core/dom/Element.h"
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
 #include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
@@ -44,18 +46,30 @@
 public:
     static CustomElementCallbackDispatcher& instance();
 
+    // This is stack allocated in many DOM callbacks. Make it cheap.
     class CallbackDeliveryScope {
     public:
-        CallbackDeliveryScope() { }
+        CallbackDeliveryScope()
+            : m_savedElementQueueStart(s_elementQueueStart)
+        {
+            s_elementQueueStart = s_elementQueueEnd;
+        }
+
         ~CallbackDeliveryScope()
         {
-            CustomElementCallbackDispatcher& dispatcher = CustomElementCallbackDispatcher::instance();
-            if (dispatcher.hasQueuedCallbacks())
-                dispatcher.dispatch();
+            if (s_elementQueueStart != s_elementQueueEnd)
+                processElementQueueAndPop();
+            s_elementQueueStart = m_savedElementQueueStart;
         }
+
+    private:
+        size_t m_savedElementQueueStart;
     };
 
-    void enqueueReadyCallback(CustomElementCallback*, Element*);
+    void enqueueAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+    void enqueueCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
+    void enqueueEnteredDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
+    void enqueueLeftDocumentCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
 
     // Returns true if more work may have to be performed at the
     // checkpoint by this or other workers (for example, this work
@@ -63,22 +77,45 @@
     bool dispatch();
 
 private:
-    explicit CustomElementCallbackDispatcher() { }
+    CustomElementCallbackDispatcher()
+    {
+        // Add a null element as a sentinel. This makes it possible to
+        // identify elements queued when there is no
+        // CallbackDeliveryScope active. Also, if the processing stack
+        // is popped when empty, this sentinel will cause a null deref
+        // crash.
+        CustomElementCallbackQueue* sentinel = 0;
+        m_flattenedProcessingStack.append(sentinel);
+        ASSERT(s_elementQueueEnd == m_flattenedProcessingStack.size());
+    }
 
-    bool hasQueuedCallbacks() { return !m_invocations.isEmpty(); }
+    // The start of the element queue on the top of the processing
+    // stack. An offset into instance().m_flattenedProcessingStack.
+    static size_t s_elementQueueStart;
 
-    class ReadyInvocation {
-    public:
-        ReadyInvocation(PassRefPtr<CustomElementCallback>, PassRefPtr<Element>);
-        virtual ~ReadyInvocation() { }
-        void invoke() { m_callback->ready(m_element.get()); }
+    // The end of the element queue on the top of the processing
+    // stack. A cache of instance().m_flattenedProcessingStack.size().
+    static size_t s_elementQueueEnd;
 
-    private:
-        RefPtr<CustomElementCallback> m_callback;
-        RefPtr<Element> m_element;
-    };
+    static bool inCallbackDeliveryScope() { return s_elementQueueStart; }
 
-    Vector<ReadyInvocation> m_invocations;
+    typedef int ElementQueue;
+    static ElementQueue currentElementQueue() { return ElementQueue(s_elementQueueStart); }
+
+    static void processElementQueueAndPop();
+    void processElementQueueAndPop(size_t start, size_t end);
+
+    CustomElementCallbackQueue* createCallbackQueue(PassRefPtr<Element>);
+    CustomElementCallbackQueue* ensureCallbackQueue(PassRefPtr<Element>);
+    CustomElementCallbackQueue* scheduleInCurrentElementQueue(PassRefPtr<Element>);
+
+    // The processing stack, flattened. Element queues lower in the
+    // stack appear toward the head of the vector. The first element
+    // is a null sentinel value.
+    Vector<CustomElementCallbackQueue*> m_flattenedProcessingStack;
+
+    typedef HashMap<Element*, OwnPtr<CustomElementCallbackQueue> > ElementCallbackQueueMap;
+    ElementCallbackQueueMap m_elementCallbackQueueMap;
 };
 
 }
diff --git a/Source/core/dom/CustomElementCallbackInvocation.cpp b/Source/core/dom/CustomElementCallbackInvocation.cpp
new file mode 100644
index 0000000..2d81c89
--- /dev/null
+++ b/Source/core/dom/CustomElementCallbackInvocation.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/CustomElementCallbackInvocation.h"
+
+#include "core/dom/CustomElementCallbackDispatcher.h"
+
+namespace WebCore {
+
+class CreatedInvocation : public CustomElementCallbackInvocation {
+public:
+    CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
+        : CustomElementCallbackInvocation(callbacks)
+    {
+    }
+
+private:
+    virtual void dispatch(Element*) OVERRIDE;
+};
+
+void CreatedInvocation::dispatch(Element* element)
+{
+    if (element->inDocument())
+        CustomElementCallbackDispatcher::instance().enqueueEnteredDocumentCallback(callbacks(), element);
+    callbacks()->created(element);
+}
+
+class EnteredLeftDocumentInvocation : public CustomElementCallbackInvocation {
+public:
+    EnteredLeftDocumentInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
+
+private:
+    virtual void dispatch(Element*) OVERRIDE;
+
+    CustomElementLifecycleCallbacks::CallbackType m_which;
+};
+
+EnteredLeftDocumentInvocation::EnteredLeftDocumentInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
+    : CustomElementCallbackInvocation(callbacks)
+    , m_which(which)
+{
+    ASSERT(m_which == CustomElementLifecycleCallbacks::EnteredDocument || m_which == CustomElementLifecycleCallbacks::LeftDocument);
+}
+
+void EnteredLeftDocumentInvocation::dispatch(Element* element)
+{
+    switch (m_which) {
+    case CustomElementLifecycleCallbacks::EnteredDocument:
+        callbacks()->enteredDocument(element);
+        break;
+    case CustomElementLifecycleCallbacks::LeftDocument:
+        callbacks()->leftDocument(element);
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
+class AttributeChangedInvocation : public CustomElementCallbackInvocation {
+public:
+    AttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+
+private:
+    virtual void dispatch(Element*) OVERRIDE;
+
+    AtomicString m_name;
+    AtomicString m_oldValue;
+    AtomicString m_newValue;
+};
+
+AttributeChangedInvocation::AttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+    : CustomElementCallbackInvocation(callbacks)
+    , m_name(name)
+    , m_oldValue(oldValue)
+    , m_newValue(newValue)
+{
+}
+
+void AttributeChangedInvocation::dispatch(Element* element)
+{
+    callbacks()->attributeChanged(element, m_name, m_oldValue, m_newValue);
+}
+
+PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
+{
+    switch (which) {
+    case CustomElementLifecycleCallbacks::Created:
+        return adoptPtr(new CreatedInvocation(callbacks));
+
+    case CustomElementLifecycleCallbacks::EnteredDocument:
+    case CustomElementLifecycleCallbacks::LeftDocument:
+        return adoptPtr(new EnteredLeftDocumentInvocation(callbacks, which));
+
+    default:
+        ASSERT_NOT_REACHED();
+        return PassOwnPtr<CustomElementCallbackInvocation>();
+    }
+}
+
+PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+    return adoptPtr(new AttributeChangedInvocation(callbacks, name, oldValue, newValue));
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/CustomElementCallbackInvocation.h b/Source/core/dom/CustomElementCallbackInvocation.h
new file mode 100644
index 0000000..c6f0818
--- /dev/null
+++ b/Source/core/dom/CustomElementCallbackInvocation.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementCallbackInvocation_h
+#define CustomElementCallbackInvocation_h
+
+#include "core/dom/CustomElementLifecycleCallbacks.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class Element;
+
+class CustomElementCallbackInvocation {
+    WTF_MAKE_NONCOPYABLE(CustomElementCallbackInvocation);
+public:
+    static PassOwnPtr<CustomElementCallbackInvocation> createInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType);
+    static PassOwnPtr<CustomElementCallbackInvocation> createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+
+    virtual ~CustomElementCallbackInvocation() { }
+    virtual void dispatch(Element*) = 0;
+
+protected:
+    CustomElementCallbackInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
+        : m_callbacks(callbacks)
+    {
+    }
+
+    CustomElementLifecycleCallbacks* callbacks() { return m_callbacks.get(); }
+
+private:
+    RefPtr<CustomElementLifecycleCallbacks> m_callbacks;
+};
+
+}
+
+#endif // CustomElementCallbackInvocation_h
diff --git a/Source/core/dom/CustomElementCallbackQueue.cpp b/Source/core/dom/CustomElementCallbackQueue.cpp
new file mode 100644
index 0000000..d5641bd
--- /dev/null
+++ b/Source/core/dom/CustomElementCallbackQueue.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/CustomElementCallbackQueue.h"
+
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+PassOwnPtr<CustomElementCallbackQueue> CustomElementCallbackQueue::create(PassRefPtr<Element> element)
+{
+    return adoptPtr(new CustomElementCallbackQueue(element));
+}
+
+CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtr<Element> element)
+    : m_element(element)
+    , m_owner(-1)
+    , m_index(0)
+{
+}
+
+void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
+{
+    while (m_index < m_queue.size() && owner() == caller) {
+        // dispatch() may cause recursion which steals this callback
+        // queue and reenters processInQueue. owner() == caller
+        // detects this recursion and cedes processing.
+        m_queue[m_index++]->dispatch(m_element.get());
+    }
+
+    if (owner() == caller && m_index == m_queue.size()) {
+        // This processInQueue exhausted the queue; shrink it.
+        m_index = 0;
+        m_queue.resize(0);
+        m_owner = -1;
+    }
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/CustomElementCallbackQueue.h b/Source/core/dom/CustomElementCallbackQueue.h
new file mode 100644
index 0000000..7e39486
--- /dev/null
+++ b/Source/core/dom/CustomElementCallbackQueue.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementCallbackQueue_h
+#define CustomElementCallbackQueue_h
+
+#include "core/dom/CustomElementCallbackInvocation.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementCallbackQueue {
+    WTF_MAKE_NONCOPYABLE(CustomElementCallbackQueue);
+public:
+    static PassOwnPtr<CustomElementCallbackQueue> create(PassRefPtr<Element>);
+
+    typedef int ElementQueue;
+    ElementQueue owner() { return m_owner; }
+    void setOwner(ElementQueue newOwner)
+    {
+        // ElementCallbackQueues only migrate towards the top of the
+        // processing stack.
+        ASSERT(newOwner >= m_owner);
+        m_owner = newOwner;
+    }
+
+    void append(PassOwnPtr<CustomElementCallbackInvocation> invocation) { m_queue.append(invocation); }
+    void processInElementQueue(ElementQueue);
+
+private:
+    CustomElementCallbackQueue(PassRefPtr<Element>);
+
+    RefPtr<Element> m_element;
+    Vector<OwnPtr<CustomElementCallbackInvocation> > m_queue;
+    ElementQueue m_owner;
+    size_t m_index;
+};
+
+}
+
+#endif // CustomElementCallbackQueue_h
diff --git a/Source/core/dom/CustomElementDefinition.cpp b/Source/core/dom/CustomElementDefinition.cpp
index 827383b..5f29910 100644
--- a/Source/core/dom/CustomElementDefinition.cpp
+++ b/Source/core/dom/CustomElementDefinition.cpp
@@ -29,20 +29,18 @@
  */
 
 #include "config.h"
-
 #include "core/dom/CustomElementDefinition.h"
 
 namespace WebCore {
 
-PassRefPtr<CustomElementDefinition> CustomElementDefinition::create(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, PassRefPtr<CustomElementCallback> callback)
+PassRefPtr<CustomElementDefinition> CustomElementDefinition::create(const CustomElementDescriptor& descriptor, PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
 {
-    return adoptRef(new CustomElementDefinition(type, name, namespaceURI, callback));
+    return adoptRef(new CustomElementDefinition(descriptor, callbacks));
 }
 
-CustomElementDefinition::CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, PassRefPtr<CustomElementCallback> callback)
-    : m_type(type)
-    , m_tag(QualifiedName(nullAtom, name, namespaceURI))
-    , m_callback(callback)
+CustomElementDefinition::CustomElementDefinition(const CustomElementDescriptor& descriptor, PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
+    : m_descriptor(descriptor)
+    , m_callbacks(callbacks)
 {
 }
 
diff --git a/Source/core/dom/CustomElementDefinition.h b/Source/core/dom/CustomElementDefinition.h
index a3a7134..96aa3dc 100644
--- a/Source/core/dom/CustomElementDefinition.h
+++ b/Source/core/dom/CustomElementDefinition.h
@@ -31,8 +31,8 @@
 #ifndef CustomElementDefinition_h
 #define CustomElementDefinition_h
 
-#include "core/dom/CustomElementCallback.h"
-#include "core/dom/QualifiedName.h"
+#include "core/dom/CustomElementDescriptor.h"
+#include "core/dom/CustomElementLifecycleCallbacks.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -41,43 +41,18 @@
 
 class CustomElementDefinition : public RefCounted<CustomElementDefinition> {
 public:
-    static PassRefPtr<CustomElementDefinition> create(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, PassRefPtr<CustomElementCallback>);
+    static PassRefPtr<CustomElementDefinition> create(const CustomElementDescriptor&, PassRefPtr<CustomElementLifecycleCallbacks>);
 
     virtual ~CustomElementDefinition() {}
 
-    enum CustomElementKind {
-        CustomTag,
-        TypeExtension
-    };
-
-    // This specifies whether the custom element is in the HTML or SVG
-    // namespace.
-    const AtomicString& namespaceURI() const { return m_tag.namespaceURI(); }
-
-    // This uniquely identifies the Custom Element. For custom tags, this
-    // is the tag name and the same as "name". For type extensions, this
-    // is the value of the "is" attribute.
-    const AtomicString& type() const { return m_type; }
-
-    // This is the tag name of the Custom Element.
-    const AtomicString& name() const { return m_tag.localName(); }
-
-    // This is a convenience property derived from "namespaceURI" and
-    // "name". Custom Elements of this kind will have this tag
-    // name. This does not have a prefix.
-    const QualifiedName& tagQName() const { return m_tag; }
-
-    CustomElementKind kind() const { return isTypeExtension() ? TypeExtension : CustomTag; }
-    bool isTypeExtension() const { return type() != name(); }
-
-    CustomElementCallback* callback() const { return m_callback.get(); }
+    const CustomElementDescriptor& descriptor() const { return m_descriptor; }
+    CustomElementLifecycleCallbacks* callbacks() const { return m_callbacks.get(); }
 
 private:
-    CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, PassRefPtr<CustomElementCallback>);
+    CustomElementDefinition(const CustomElementDescriptor&, PassRefPtr<CustomElementLifecycleCallbacks>);
 
-    AtomicString m_type;
-    QualifiedName m_tag;
-    RefPtr<CustomElementCallback> m_callback;
+    CustomElementDescriptor m_descriptor;
+    RefPtr<CustomElementLifecycleCallbacks> m_callbacks;
 };
 
 }
diff --git a/Source/core/dom/CustomElementDescriptor.h b/Source/core/dom/CustomElementDescriptor.h
new file mode 100644
index 0000000..307cb43
--- /dev/null
+++ b/Source/core/dom/CustomElementDescriptor.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementDescriptor_h
+#define CustomElementDescriptor_h
+
+#include "wtf/RefPtr.h" // for HashTableDeletedValueType
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+struct CustomElementDescriptorHash;
+
+// A Custom Element descriptor is everything necessary to match a
+// Custom Element instance to a definition.
+class CustomElementDescriptor {
+public:
+    CustomElementDescriptor(const AtomicString& type, const AtomicString& namespaceURI, const AtomicString& localName)
+        : m_type(type)
+        , m_namespaceURI(namespaceURI)
+        , m_localName(localName)
+    {
+    }
+
+    ~CustomElementDescriptor() { }
+
+    // Specifies whether the custom element is in the HTML or SVG
+    // namespace.
+    const AtomicString& namespaceURI() const { return m_namespaceURI; }
+
+    // The tag name.
+    const AtomicString& localName() const { return m_localName; }
+
+    // The name of the definition. For custom tags, this is the tag
+    // name and the same as "localName". For type extensions, this is
+    // the value of the "is" attribute.
+    const AtomicString& type() const { return m_type; }
+
+    bool isTypeExtension() const { return m_type != m_localName; }
+
+    // Stuff for hashing.
+
+    CustomElementDescriptor() { }
+    explicit CustomElementDescriptor(WTF::HashTableDeletedValueType value)
+        : m_type(value) { }
+    bool isHashTableDeletedValue() const { return m_type.isHashTableDeletedValue(); }
+
+    bool operator==(const CustomElementDescriptor& other) const
+    {
+        return m_type == other.m_type
+            && m_localName == other.m_localName
+            && m_namespaceURI == other.m_namespaceURI;
+    }
+
+private:
+    AtomicString m_type;
+    AtomicString m_namespaceURI;
+    AtomicString m_localName;
+};
+
+} // namespace WebCore
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<WebCore::CustomElementDescriptor> {
+    typedef WebCore::CustomElementDescriptorHash Hash;
+};
+
+} // namespace WTF
+
+#endif // CustomElementDescriptor_h
diff --git a/Source/core/dom/CustomElementCallback.h b/Source/core/dom/CustomElementDescriptorHash.h
similarity index 60%
rename from Source/core/dom/CustomElementCallback.h
rename to Source/core/dom/CustomElementDescriptorHash.h
index d71e35a..81c51de 100644
--- a/Source/core/dom/CustomElementCallback.h
+++ b/Source/core/dom/CustomElementDescriptorHash.h
@@ -28,34 +28,39 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef CustomElementCallback_h
-#define CustomElementCallback_h
+#ifndef CustomElementDescriptorHash_h
+#define CustomElementDescriptorHash_h
 
-#include "wtf/RefCounted.h"
+#include "core/dom/CustomElementDescriptor.h"
+#include "wtf/HashFunctions.h"
+#include "wtf/HashTraits.h"
+#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
-class Element;
+struct CustomElementDescriptorHash {
+    static unsigned hash(const CustomElementDescriptor& descriptor)
+    {
+        return WTF::pairIntHash(AtomicStringHash::hash(descriptor.type()), WTF::pairIntHash(AtomicStringHash::hash(descriptor.namespaceURI()), AtomicStringHash::hash(descriptor.localName())));
+    }
 
-class CustomElementCallback : public RefCounted<CustomElementCallback> {
-public:
-    virtual ~CustomElementCallback() { }
+    static bool equal(const CustomElementDescriptor& a, const CustomElementDescriptor& b)
+    {
+        return a == b;
+    }
 
-    bool hasReady() const { return m_which == Ready; }
-    virtual void ready(Element*) = 0;
-
-protected:
-    enum CallbackType {
-        None,
-        Ready
-    };
-
-    CustomElementCallback(CallbackType which) : m_which(which) { }
-
-private:
-    CallbackType m_which;
+    static const bool safeToCompareToEmptyOrDeleted = true;
 };
 
-}
+} // namespace WebCore
 
-#endif // CustomElementCallback_h
+namespace WTF {
+
+template<>
+struct HashTraits<WebCore::CustomElementDescriptor> : SimpleClassHashTraits<WebCore::CustomElementDescriptor> {
+    static const bool emptyValueIsZero = HashTraits<AtomicString>::emptyValueIsZero;
+};
+
+} // namespace WTF
+
+#endif // CustomElementDescriptorHash
diff --git a/Source/core/dom/CustomElementCallback.h b/Source/core/dom/CustomElementLifecycleCallbacks.h
similarity index 60%
copy from Source/core/dom/CustomElementCallback.h
copy to Source/core/dom/CustomElementLifecycleCallbacks.h
index d71e35a..e48628d 100644
--- a/Source/core/dom/CustomElementCallback.h
+++ b/Source/core/dom/CustomElementLifecycleCallbacks.h
@@ -28,29 +28,42 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef CustomElementCallback_h
-#define CustomElementCallback_h
+#ifndef CustomElementLifecycleCallbacks_h
+#define CustomElementLifecycleCallbacks_h
 
 #include "wtf/RefCounted.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
 class Element;
 
-class CustomElementCallback : public RefCounted<CustomElementCallback> {
+class CustomElementLifecycleCallbacks : public RefCounted<CustomElementLifecycleCallbacks> {
 public:
-    virtual ~CustomElementCallback() { }
+    virtual ~CustomElementLifecycleCallbacks() { }
 
-    bool hasReady() const { return m_which == Ready; }
-    virtual void ready(Element*) = 0;
+    bool hasCreatedCallback() const { return m_which & Created; }
+    virtual void created(Element*) = 0;
 
-protected:
+    bool hasEnteredDocumentCallback() const { return m_which & EnteredDocument; }
+    virtual void enteredDocument(Element*) = 0;
+
+    bool hasLeftDocumentCallback() const { return m_which & LeftDocument; }
+    virtual void leftDocument(Element*) = 0;
+
+    bool hasAttributeChangedCallback() const { return m_which & AttributeChanged; }
+    virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
+
     enum CallbackType {
-        None,
-        Ready
+        None             = 0,
+        Created          = 1 << 0,
+        EnteredDocument  = 1 << 1,
+        LeftDocument     = 1 << 2,
+        AttributeChanged = 1 << 3
     };
 
-    CustomElementCallback(CallbackType which) : m_which(which) { }
+protected:
+    CustomElementLifecycleCallbacks(CallbackType which) : m_which(which) { }
 
 private:
     CallbackType m_which;
@@ -58,4 +71,4 @@
 
 }
 
-#endif // CustomElementCallback_h
+#endif // CustomElementLifecycleCallbacks_h
diff --git a/Source/core/dom/CustomElementRegistrationContext.cpp b/Source/core/dom/CustomElementRegistrationContext.cpp
new file mode 100644
index 0000000..75844c3
--- /dev/null
+++ b/Source/core/dom/CustomElementRegistrationContext.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/CustomElementRegistrationContext.h"
+
+#include "HTMLNames.h"
+#include "SVGNames.h"
+#include "core/dom/CustomElementCallbackDispatcher.h"
+#include "core/dom/CustomElementDefinition.h"
+#include "core/dom/CustomElementRegistry.h"
+#include "core/dom/CustomElementUpgradeCandidateMap.h"
+#include "core/dom/Element.h"
+#include "core/html/HTMLElement.h"
+#include "core/html/HTMLUnknownElement.h"
+#include "core/svg/SVGElement.h"
+
+namespace WebCore {
+
+// The null registration context is used by documents that do not
+// process custom elements. All of its operations are no-ops.
+class NullRegistrationContext : public CustomElementRegistrationContext {
+public:
+    NullRegistrationContext() { }
+    virtual ~NullRegistrationContext() { }
+
+    virtual CustomElementDescriptor describe(Element*) const OVERRIDE { return CustomElementDescriptor(); }
+
+    virtual void registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString&, ExceptionCode& ec) OVERRIDE { ec = NotSupportedError; }
+
+    virtual PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&) OVERRIDE;
+    virtual void didGiveTypeExtension(Element*, const AtomicString&) OVERRIDE { }
+
+    virtual void customElementAttributeDidChange(Element*, const AtomicString&, const AtomicString&, const AtomicString&) OVERRIDE { }
+    virtual void customElementDidEnterDocument(Element*) OVERRIDE { }
+    virtual void customElementDidLeaveDocument(Element*) OVERRIDE { }
+    virtual void customElementIsBeingDestroyed(Element*) OVERRIDE { }
+};
+
+PassRefPtr<Element> NullRegistrationContext::createCustomTagElement(Document* document, const QualifiedName& tagName)
+{
+    ASSERT(isCustomTagName(tagName.localName()));
+
+    if (!document)
+        return 0;
+
+    if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI())
+        return HTMLUnknownElement::create(tagName, document);
+    if (SVGNames::svgNamespaceURI == tagName.namespaceURI())
+        return SVGElement::create(tagName, document);
+    return Element::create(tagName, document);
+}
+
+PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::nullRegistrationContext()
+{
+    DEFINE_STATIC_LOCAL(RefPtr<NullRegistrationContext>, instance, ());
+    if (!instance)
+        instance = adoptRef(new NullRegistrationContext());
+    return instance.get();
+}
+
+// An active registration context is used by documents that are
+// processing custom elements.
+class ActiveRegistrationContext : public CustomElementRegistrationContext {
+public:
+    ActiveRegistrationContext() { }
+    virtual ~ActiveRegistrationContext() { }
+
+    virtual CustomElementDescriptor describe(Element*) const OVERRIDE;
+
+    virtual void registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& type, ExceptionCode&) OVERRIDE;
+
+    virtual PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&) OVERRIDE;
+    virtual void didGiveTypeExtension(Element*, const AtomicString&) OVERRIDE;
+
+    virtual void customElementAttributeDidChange(Element*, const AtomicString&, const AtomicString&, const AtomicString&) OVERRIDE;
+    virtual void customElementDidEnterDocument(Element*) OVERRIDE;
+    virtual void customElementDidLeaveDocument(Element*) OVERRIDE;
+    virtual void customElementIsBeingDestroyed(Element*) OVERRIDE;
+
+private:
+    CustomElementDefinition* definitionFor(Element*) const;
+
+    void didCreateUnresolvedElement(const CustomElementDescriptor&, Element*);
+    void didResolveElement(CustomElementDefinition*, Element*) const;
+
+    CustomElementRegistry m_registry;
+
+    // Element creation
+    typedef HashMap<Element*, AtomicString> ElementTypeMap;
+    ElementTypeMap m_elementTypeMap; // Creation-time "is" attribute value.
+    CustomElementUpgradeCandidateMap m_candidates;
+};
+
+CustomElementDescriptor ActiveRegistrationContext::describe(Element* element) const
+{
+    ASSERT(element->isCustomElement());
+
+    // If an element has a custom tag name it takes precedence over
+    // the "is" attribute (if any).
+    const AtomicString& type = isCustomTagName(element->localName())
+        ? element->localName()
+        : m_elementTypeMap.get(element);
+
+    ASSERT(!type.isNull()); // Element must be in this registry
+    return CustomElementDescriptor(type, element->namespaceURI(), element->localName());
+}
+
+void ActiveRegistrationContext::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& type, ExceptionCode& ec)
+{
+    CustomElementDefinition* definition = m_registry.registerElement(document, constructorBuilder, type, ec);
+
+    if (!definition)
+        return;
+
+    // Upgrade elements that were waiting for this definition.
+    const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor());
+    for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it)
+        didResolveElement(definition, *it);
+}
+
+CustomElementDefinition* ActiveRegistrationContext::definitionFor(Element* element) const
+{
+    ASSERT(element->document()->registrationContext() == this);
+    const CustomElementDescriptor& descriptor = describe(element);
+    return m_registry.find(descriptor);
+}
+
+PassRefPtr<Element> ActiveRegistrationContext::createCustomTagElement(Document* document, const QualifiedName& tagName)
+{
+    ASSERT(isCustomTagName(tagName.localName()));
+
+    if (!document)
+        return 0;
+
+    RefPtr<Element> element;
+
+    if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) {
+        element = HTMLElement::create(tagName, document);
+    } else if (SVGNames::svgNamespaceURI == tagName.namespaceURI()) {
+        element = SVGElement::create(tagName, document);
+    } else {
+        // XML elements are not custom elements, so return early.
+        return Element::create(tagName, document);
+    }
+
+    element->setIsCustomElement();
+
+    const CustomElementDescriptor& descriptor = describe(element.get());
+    CustomElementDefinition* definition = m_registry.find(descriptor);
+    if (definition)
+        didResolveElement(definition, element.get());
+    else
+        didCreateUnresolvedElement(descriptor, element.get());
+
+    return element.release();
+}
+
+void ActiveRegistrationContext::didCreateUnresolvedElement(const CustomElementDescriptor& descriptor, Element* element)
+{
+    m_candidates.add(descriptor, element);
+}
+
+void ActiveRegistrationContext::didResolveElement(CustomElementDefinition* definition, Element* element) const
+{
+    CustomElementCallbackDispatcher::instance().enqueueCreatedCallback(definition->callbacks(), element);
+}
+
+void ActiveRegistrationContext::didGiveTypeExtension(Element* element, const AtomicString& type)
+{
+    if (!element->isHTMLElement() && !element->isSVGElement())
+        return;
+    if (element->isCustomElement())
+        return; // A custom tag, which takes precedence over type extensions
+    element->setIsCustomElement();
+    m_elementTypeMap.add(element, type);
+    const CustomElementDescriptor& descriptor = describe(element);
+    CustomElementDefinition* definition = m_registry.find(descriptor);
+    if (definition)
+        didResolveElement(definition, element);
+    else
+        didCreateUnresolvedElement(descriptor, element);
+}
+
+void ActiveRegistrationContext::customElementAttributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+    ASSERT(element->isUpgradedCustomElement());
+    CustomElementDefinition* definition = definitionFor(element);
+    CustomElementCallbackDispatcher::instance().enqueueAttributeChangedCallback(definition->callbacks(), element, name, oldValue, newValue);
+}
+
+void ActiveRegistrationContext::customElementDidEnterDocument(Element* element)
+{
+    ASSERT(element->isUpgradedCustomElement());
+    CustomElementDefinition* definition = definitionFor(element);
+    CustomElementCallbackDispatcher::instance().enqueueEnteredDocumentCallback(definition->callbacks(), element);
+}
+
+void ActiveRegistrationContext::customElementDidLeaveDocument(Element* element)
+{
+    ASSERT(element->isUpgradedCustomElement());
+    CustomElementDefinition* definition = definitionFor(element);
+    CustomElementCallbackDispatcher::instance().enqueueLeftDocumentCallback(definition->callbacks(), element);
+}
+
+void ActiveRegistrationContext::customElementIsBeingDestroyed(Element* element)
+{
+    ASSERT(element->isCustomElement());
+    m_candidates.remove(element);
+    m_elementTypeMap.remove(element);
+}
+
+PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create()
+{
+    return adoptRef(new ActiveRegistrationContext());
+}
+
+bool CustomElementRegistrationContext::isValidTypeName(const AtomicString& name)
+{
+    if (notFound == name.find('-'))
+        return false;
+
+    // FIXME: Add annotation-xml.
+    DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
+    if (reservedNames.isEmpty()) {
+        reservedNames.append(SVGNames::color_profileTag.localName());
+        reservedNames.append(SVGNames::font_faceTag.localName());
+        reservedNames.append(SVGNames::font_face_srcTag.localName());
+        reservedNames.append(SVGNames::font_face_uriTag.localName());
+        reservedNames.append(SVGNames::font_face_formatTag.localName());
+        reservedNames.append(SVGNames::font_face_nameTag.localName());
+        reservedNames.append(SVGNames::missing_glyphTag.localName());
+    }
+
+    if (notFound != reservedNames.find(name))
+        return false;
+
+    return Document::isValidName(name.string());
+}
+
+bool CustomElementRegistrationContext::isCustomTagName(const AtomicString& localName)
+{
+    return isValidTypeName(localName);
+}
+
+void CustomElementRegistrationContext::setTypeExtension(Element* element, const AtomicString& type)
+{
+    ASSERT(element);
+    if (!type.isEmpty())
+        element->setAttribute(HTMLNames::isAttr, type);
+
+    didGiveTypeExtension(element, type);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/CustomElementRegistrationContext.h b/Source/core/dom/CustomElementRegistrationContext.h
new file mode 100644
index 0000000..b675300
--- /dev/null
+++ b/Source/core/dom/CustomElementRegistrationContext.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ *    may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementRegistrationContext_h
+#define CustomElementRegistrationContext_h
+
+#include "core/dom/CustomElementDescriptor.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/dom/QualifiedName.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class CustomElementConstructorBuilder;
+class Document;
+class Element;
+
+class CustomElementRegistrationContext : public RefCounted<CustomElementRegistrationContext> {
+public:
+    static PassRefPtr<CustomElementRegistrationContext> nullRegistrationContext();
+    static PassRefPtr<CustomElementRegistrationContext> create();
+
+    virtual ~CustomElementRegistrationContext() { }
+
+    // Model
+    static bool isValidTypeName(const AtomicString& type);
+    static bool isCustomTagName(const AtomicString& localName);
+    virtual CustomElementDescriptor describe(Element*) const = 0;
+
+    // Definitions
+    virtual void registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& type, ExceptionCode&) = 0;
+
+    // Instance creation
+    virtual PassRefPtr<Element> createCustomTagElement(Document*, const QualifiedName&) = 0;
+    void setTypeExtension(Element*, const AtomicString& type);
+    virtual void didGiveTypeExtension(Element*, const AtomicString& type) = 0;
+
+    // Instance lifecycle
+    virtual void customElementAttributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
+    virtual void customElementDidEnterDocument(Element*) = 0;
+    virtual void customElementDidLeaveDocument(Element*) = 0;
+    virtual void customElementIsBeingDestroyed(Element*) = 0;
+
+protected:
+    CustomElementRegistrationContext() { }
+};
+
+}
+
+#endif // CustomElementRegistrationContext_h
+
diff --git a/Source/core/dom/CustomElementRegistry.cpp b/Source/core/dom/CustomElementRegistry.cpp
index 3eeb0df..3bbd23f 100644
--- a/Source/core/dom/CustomElementRegistry.cpp
+++ b/Source/core/dom/CustomElementRegistry.cpp
@@ -34,221 +34,95 @@
 #include "HTMLNames.h"
 #include "SVGNames.h"
 #include "bindings/v8/CustomElementConstructorBuilder.h"
-#include "core/dom/CustomElementCallbackDispatcher.h"
 #include "core/dom/CustomElementDefinition.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/html/HTMLElement.h"
-#include "core/svg/SVGElement.h"
+#include "core/dom/CustomElementRegistrationContext.h"
+#include "core/dom/DocumentLifecycleObserver.h"
 
 namespace WebCore {
 
-void setTypeExtension(Element* element, const AtomicString& typeExtension)
-{
-    ASSERT(element);
-    if (!typeExtension.isEmpty())
-        element->setAttribute(HTMLNames::isAttr, typeExtension);
-}
-
-CustomElementRegistry::CustomElementRegistry(Document* document)
-    : ContextLifecycleObserver(document)
-{
-}
-
-static inline bool nameIncludesHyphen(const AtomicString& name)
-{
-    size_t hyphenPosition = name.find('-');
-    return (hyphenPosition != notFound);
-}
-
-bool CustomElementRegistry::isValidName(const AtomicString& name)
-{
-    if (!nameIncludesHyphen(name))
-        return false;
-
-    DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
-    if (reservedNames.isEmpty()) {
-        reservedNames.append(SVGNames::color_profileTag.localName());
-        reservedNames.append(SVGNames::font_faceTag.localName());
-        reservedNames.append(SVGNames::font_face_srcTag.localName());
-        reservedNames.append(SVGNames::font_face_uriTag.localName());
-        reservedNames.append(SVGNames::font_face_formatTag.localName());
-        reservedNames.append(SVGNames::font_face_nameTag.localName());
-        reservedNames.append(SVGNames::missing_glyphTag.localName());
+class RegistrationContextObserver : public DocumentLifecycleObserver {
+public:
+    explicit RegistrationContextObserver(Document* document)
+        : DocumentLifecycleObserver(document)
+        , m_wentAway(!document)
+    {
     }
 
-    if (notFound != reservedNames.find(name))
-        return false;
+    bool registrationContextWentAway() { return m_wentAway; }
 
-    return Document::isValidName(name.string());
-}
+private:
+    virtual void documentWasDisposed() OVERRIDE { m_wentAway = true; }
 
-void CustomElementRegistry::registerElement(CustomElementConstructorBuilder* constructorBuilder, const AtomicString& userSuppliedName, ExceptionCode& ec)
+    bool m_wentAway;
+};
+
+CustomElementDefinition* CustomElementRegistry::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& userSuppliedName, ExceptionCode& ec)
 {
-    RefPtr<CustomElementRegistry> protect(this);
+    // FIXME: In every instance except one it is the
+    // CustomElementConstructorBuilder that observes document
+    // destruction during registration. This responsibility should be
+    // consolidated in one place.
+    RegistrationContextObserver observer(document);
 
     if (!constructorBuilder->isFeatureAllowed())
-        return;
+        return 0;
 
     AtomicString type = userSuppliedName.lower();
-    if (!isValidName(type)) {
-        ec = INVALID_CHARACTER_ERR;
-        return;
+    if (!CustomElementRegistrationContext::isValidTypeName(type)) {
+        ec = InvalidCharacterError;
+        return 0;
     }
 
     if (!constructorBuilder->validateOptions()) {
-        ec = INVALID_STATE_ERR;
-        return;
+        ec = InvalidStateError;
+        return 0;
     }
 
     QualifiedName tagName = nullQName();
     if (!constructorBuilder->findTagName(type, tagName)) {
-        ec = NAMESPACE_ERR;
-        return;
+        ec = NamespaceError;
+        return 0;
     }
     ASSERT(tagName.namespaceURI() == HTMLNames::xhtmlNamespaceURI || tagName.namespaceURI() == SVGNames::svgNamespaceURI);
 
-    if (m_definitions.contains(type)) {
-        ec = INVALID_STATE_ERR;
-        return;
+    if (m_registeredTypeNames.contains(type)) {
+        ec = InvalidStateError;
+        return 0;
     }
 
-    RefPtr<CustomElementCallback> lifecycleCallbacks = constructorBuilder->createCallback(document());
+    ASSERT(!observer.registrationContextWentAway());
+
+    RefPtr<CustomElementLifecycleCallbacks> lifecycleCallbacks = constructorBuilder->createCallbacks(document);
 
     // Consulting the constructor builder could execute script and
     // kill the document.
-    if (!document()) {
-        ec = INVALID_STATE_ERR;
-        return;
-    }
-
-    RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create(type, tagName.localName(), tagName.namespaceURI(), lifecycleCallbacks);
-
-    if (!constructorBuilder->createConstructor(document(), definition.get())) {
-        ec = NOT_SUPPORTED_ERR;
-        return;
-    }
-
-    m_definitions.add(definition->type(), definition);
-
-    // Upgrade elements that were waiting for this definition.
-    CustomElementUpgradeCandidateMap::ElementSet upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition.get());
-    if (!constructorBuilder->didRegisterDefinition(definition.get(), upgradeCandidates)) {
-        ec = NOT_SUPPORTED_ERR;
-        return;
-    }
-
-    for (CustomElementUpgradeCandidateMap::ElementSet::iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it) {
-        (*it)->setNeedsStyleRecalc(); // :unresolved has changed
-
-        CustomElementCallbackDispatcher::instance().enqueueReadyCallback(lifecycleCallbacks.get(), *it);
-    }
-}
-
-bool CustomElementRegistry::isUnresolved(Element* element) const
-{
-    return m_candidates.contains(element);
-}
-
-PassRefPtr<CustomElementDefinition> CustomElementRegistry::findFor(Element* element) const
-{
-    ASSERT(element->document()->registry() == this);
-
-    if (!element->isCustomElement())
+    if (observer.registrationContextWentAway()) {
+        ec = InvalidStateError;
         return 0;
-
-    // When a custom tag and a type extension are provided as element
-    // names at the same time, the custom tag takes precedence.
-    if (isCustomTagName(element->localName())) {
-        if (RefPtr<CustomElementDefinition> definition = findAndCheckNamespace(element->localName(), element->namespaceURI()))
-            return definition->isTypeExtension() ? 0 : definition.release();
     }
 
-    // FIXME: Casually consulting the "is" attribute is dangerous if
-    // it could have changed since element creation.
-    const AtomicString& isValue = element->getAttribute(HTMLNames::isAttr);
-    if (RefPtr<CustomElementDefinition> definition = findAndCheckNamespace(isValue, element->namespaceURI()))
-        return definition->isTypeExtension() && definition->name() == element->localName() ? definition.release() : 0;
+    const CustomElementDescriptor descriptor(type, tagName.namespaceURI(), tagName.localName());
+    RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create(descriptor, lifecycleCallbacks);
 
-    return 0;
-}
-
-PassRefPtr<CustomElementDefinition> CustomElementRegistry::findAndCheckNamespace(const AtomicString& type, const AtomicString& namespaceURI) const
-{
-    if (type.isNull())
+    if (!constructorBuilder->createConstructor(document, definition.get())) {
+        ec = NotSupportedError;
         return 0;
-    DefinitionMap::const_iterator it = m_definitions.find(type);
-    if (it == m_definitions.end())
-        return 0;
-    if (it->value->namespaceURI() != namespaceURI)
-        return 0;
-    return it->value;
-}
-
-PassRefPtr<Element> CustomElementRegistry::createCustomTagElement(const QualifiedName& tagName)
-{
-    if (!document())
-        return 0;
-
-    ASSERT(isCustomTagName(tagName.localName()));
-
-    RefPtr<Element> element;
-
-    if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI())
-        element = HTMLElement::create(tagName, document());
-    else if (SVGNames::svgNamespaceURI == tagName.namespaceURI())
-        element = SVGElement::create(tagName, document());
-    else
-        return Element::create(tagName, document());
-
-    element->setIsCustomElement();
-
-    RefPtr<CustomElementDefinition> definition = findAndCheckNamespace(tagName.localName(), tagName.namespaceURI());
-    if (!definition || definition->isTypeExtension()) {
-        // If a definition for a type extension was available, this
-        // custom tag element will be unresolved in perpetuity.
-        didCreateUnresolvedElement(CustomElementDefinition::CustomTag, tagName.localName(), element.get());
-    } else {
-        didCreateCustomTagElement(definition.get(), element.get());
     }
 
-    return element.release();
-}
+    m_definitions.add(descriptor, definition);
+    m_registeredTypeNames.add(descriptor.type());
 
-void CustomElementRegistry::didGiveTypeExtension(Element* element, const AtomicString& type)
-{
-    if (!element->isHTMLElement() && !element->isSVGElement())
-        return;
-    element->setIsCustomElement();
-    RefPtr<CustomElementDefinition> definition = findFor(element);
-    if (!definition || !definition->isTypeExtension()) {
-        // If a definition for a custom tag was available, this type
-        // extension element will be unresolved in perpetuity.
-        didCreateUnresolvedElement(CustomElementDefinition::TypeExtension, type, element);
-    } else {
-        CustomElementCallbackDispatcher::instance().enqueueReadyCallback(definition->callback(), element);
+    if (!constructorBuilder->didRegisterDefinition(definition.get())) {
+        ec = NotSupportedError;
+        return 0;
     }
+
+    return definition.get();
 }
 
-void CustomElementRegistry::didCreateCustomTagElement(CustomElementDefinition* definition, Element* element)
+CustomElementDefinition* CustomElementRegistry::find(const CustomElementDescriptor& descriptor) const
 {
-    CustomElementCallbackDispatcher::instance().enqueueReadyCallback(definition->callback(), element);
+    return m_definitions.get(descriptor);
 }
 
-void CustomElementRegistry::didCreateUnresolvedElement(CustomElementDefinition::CustomElementKind kind, const AtomicString& type, Element* element)
-{
-    m_candidates.add(kind, type, element);
-}
-
-void CustomElementRegistry::customElementWasDestroyed(Element* element)
-{
-    ASSERT(element->isCustomElement());
-    m_candidates.remove(element);
-}
-
-inline Document* CustomElementRegistry::document() const
-{
-    return toDocument(m_scriptExecutionContext);
-}
-
-}
+} // namespace WebCore
diff --git a/Source/core/dom/CustomElementRegistry.h b/Source/core/dom/CustomElementRegistry.h
index 525618a..f4195a7 100644
--- a/Source/core/dom/CustomElementRegistry.h
+++ b/Source/core/dom/CustomElementRegistry.h
@@ -31,12 +31,12 @@
 #ifndef CustomElementRegistry_h
 #define CustomElementRegistry_h
 
-#include "core/dom/ContextLifecycleObserver.h"
-#include "core/dom/CustomElementUpgradeCandidateMap.h"
+#include "core/dom/CustomElementDefinition.h"
+#include "core/dom/CustomElementDescriptor.h"
+#include "core/dom/CustomElementDescriptorHash.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/dom/QualifiedName.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
+#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
 #include "wtf/RefPtr.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/AtomicStringHash.h"
@@ -44,43 +44,23 @@
 namespace WebCore {
 
 class CustomElementConstructorBuilder;
-class CustomElementDefinition;
 class Document;
-class Element;
 
-void setTypeExtension(Element*, const AtomicString& typeExtension);
+class CustomElementRegistry {
+    WTF_MAKE_NONCOPYABLE(CustomElementRegistry);
+protected:
+    friend class ActiveRegistrationContext;
 
-class CustomElementRegistry : public RefCounted<CustomElementRegistry>, public ContextLifecycleObserver {
-    WTF_MAKE_NONCOPYABLE(CustomElementRegistry); WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit CustomElementRegistry(Document*);
+    CustomElementRegistry() { }
     virtual ~CustomElementRegistry() { }
 
-    void registerElement(CustomElementConstructorBuilder*, const AtomicString& name, ExceptionCode&);
-
-    bool isUnresolved(Element*) const;
-    PassRefPtr<CustomElementDefinition> findFor(Element*) const;
-
-    PassRefPtr<Element> createCustomTagElement(const QualifiedName& localName);
-
-    Document* document() const;
-
-    void didGiveTypeExtension(Element*, const AtomicString&);
-    void customElementWasDestroyed(Element*);
-
-    static bool isCustomTagName(const AtomicString& name) { return isValidName(name); }
+    CustomElementDefinition* registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& name, ExceptionCode&);
+    CustomElementDefinition* find(const CustomElementDescriptor&) const;
 
 private:
-    typedef HashMap<AtomicString, RefPtr<CustomElementDefinition> > DefinitionMap;
-    static bool isValidName(const AtomicString&);
-
-    PassRefPtr<CustomElementDefinition> findAndCheckNamespace(const AtomicString& type, const AtomicString& namespaceURI) const;
-
-    void didCreateCustomTagElement(CustomElementDefinition*, Element*);
-    void didCreateUnresolvedElement(CustomElementDefinition::CustomElementKind, const AtomicString& type, Element*);
-
+    typedef HashMap<CustomElementDescriptor, RefPtr<CustomElementDefinition> > DefinitionMap;
     DefinitionMap m_definitions;
-    CustomElementUpgradeCandidateMap m_candidates;
+    HashSet<AtomicString> m_registeredTypeNames;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/CustomElementUpgradeCandidateMap.cpp b/Source/core/dom/CustomElementUpgradeCandidateMap.cpp
index 6b9c543..0c3049a 100644
--- a/Source/core/dom/CustomElementUpgradeCandidateMap.cpp
+++ b/Source/core/dom/CustomElementUpgradeCandidateMap.cpp
@@ -29,63 +29,39 @@
  */
 
 #include "config.h"
-
 #include "core/dom/CustomElementUpgradeCandidateMap.h"
 
 namespace WebCore {
 
-void CustomElementUpgradeCandidateMap::add(CustomElementDefinition::CustomElementKind kind, const AtomicString& type, Element* element)
+void CustomElementUpgradeCandidateMap::add(const CustomElementDescriptor& descriptor, Element* element)
 {
-    m_unresolvedElements.add(element, RequiredDefinition(kind, type));
+    m_upgradeCandidates.add(element, descriptor);
 
-    UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(type);
+    UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(descriptor);
     if (it == m_unresolvedDefinitions.end())
-        it = m_unresolvedDefinitions.add(type, ElementSet()).iterator;
+        it = m_unresolvedDefinitions.add(descriptor, ElementSet()).iterator;
     it->value.add(element);
 }
 
-bool CustomElementUpgradeCandidateMap::contains(Element* element) const
-{
-    return m_unresolvedElements.contains(element);
-}
-
 void CustomElementUpgradeCandidateMap::remove(Element* element)
 {
-    UnresolvedElementMap::iterator it = m_unresolvedElements.find(element);
-    if (it == m_unresolvedElements.end())
+    UpgradeCandidateMap::iterator it = m_upgradeCandidates.find(element);
+    if (it == m_upgradeCandidates.end())
         return;
 
-    const AtomicString& type = it->value.second;
-    m_unresolvedDefinitions.get(type).remove(element);
-    m_unresolvedElements.remove(it);
+    const CustomElementDescriptor& descriptor = it->value;
+    m_unresolvedDefinitions.get(descriptor).remove(element);
+    m_upgradeCandidates.remove(it);
 }
 
-CustomElementUpgradeCandidateMap::ElementSet CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(CustomElementDefinition* definition)
+ListHashSet<Element*> CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(const CustomElementDescriptor& descriptor)
 {
-    UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(definition->type());
-    if (it == m_unresolvedDefinitions.end())
-        return ElementSet();
+    const ListHashSet<Element*>& candidates = m_unresolvedDefinitions.take(descriptor);
 
-    const ElementSet& candidatesForThisType = it->value;
-    ElementSet matchingCandidates;
+    for (ElementSet::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate)
+        m_upgradeCandidates.remove(*candidate);
 
-    // Filter the set based on whether the definition matches
-    for (ElementSet::const_iterator candidate = candidatesForThisType.begin(); candidate != candidatesForThisType.end(); ++candidate) {
-        if (matches(definition, *candidate)) {
-            matchingCandidates.add(*candidate);
-            m_unresolvedElements.remove(*candidate);
-        }
-    }
-
-    m_unresolvedDefinitions.remove(it);
-    return matchingCandidates;
-}
-
-bool CustomElementUpgradeCandidateMap::matches(CustomElementDefinition* definition, Element* element)
-{
-    ASSERT(m_unresolvedElements.contains(element));
-    const RequiredDefinition& requirement = m_unresolvedElements.get(element);
-    return definition->kind() == requirement.first && definition->type() == requirement.second && definition->namespaceURI() == element->namespaceURI() && definition->name() == element->localName();
+    return candidates;
 }
 
 }
diff --git a/Source/core/dom/CustomElementUpgradeCandidateMap.h b/Source/core/dom/CustomElementUpgradeCandidateMap.h
index 84d3d91..bf22e7d 100644
--- a/Source/core/dom/CustomElementUpgradeCandidateMap.h
+++ b/Source/core/dom/CustomElementUpgradeCandidateMap.h
@@ -31,40 +31,35 @@
 #ifndef CustomElementUpgradeCandidateMap_h
 #define CustomElementUpgradeCandidateMap_h
 
-#include "core/dom/CustomElementDefinition.h"
-#include "core/dom/Element.h"
+#include "core/dom/CustomElementDescriptor.h"
+#include "core/dom/CustomElementDescriptorHash.h"
 #include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
+#include "wtf/ListHashSet.h"
 #include "wtf/Noncopyable.h"
-#include "wtf/text/AtomicString.h"
-#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
+class Element;
+
 class CustomElementUpgradeCandidateMap {
     WTF_MAKE_NONCOPYABLE(CustomElementUpgradeCandidateMap);
 public:
     CustomElementUpgradeCandidateMap() { }
 
-    typedef HashSet<Element*> ElementSet;
-
-    void add(CustomElementDefinition::CustomElementKind, const AtomicString& type, Element*);
-    bool contains(Element*) const;
+    void add(const CustomElementDescriptor&, Element*);
     void remove(Element*);
-    ElementSet takeUpgradeCandidatesFor(CustomElementDefinition*);
+
+    typedef ListHashSet<Element*> ElementSet;
+    ElementSet takeUpgradeCandidatesFor(const CustomElementDescriptor&);
 
 private:
-    typedef std::pair<CustomElementDefinition::CustomElementKind, AtomicString> RequiredDefinition;
-    typedef HashMap<Element*, RequiredDefinition> UnresolvedElementMap;
-    typedef HashMap<AtomicString, ElementSet> UnresolvedDefinitionMap;
+    typedef HashMap<Element*, CustomElementDescriptor> UpgradeCandidateMap;
+    UpgradeCandidateMap m_upgradeCandidates;
 
-    bool matches(CustomElementDefinition*, Element*);
-
-    UnresolvedElementMap m_unresolvedElements;
+    typedef HashMap<CustomElementDescriptor, ElementSet> UnresolvedDefinitionMap;
     UnresolvedDefinitionMap m_unresolvedDefinitions;
 };
 
 }
 
 #endif // CustomElementUpgradeCandidateMap_h
-
diff --git a/Source/core/dom/CustomEvent.cpp b/Source/core/dom/CustomEvent.cpp
index c7e67b3..bad25d2 100644
--- a/Source/core/dom/CustomEvent.cpp
+++ b/Source/core/dom/CustomEvent.cpp
@@ -30,10 +30,6 @@
 
 namespace WebCore {
 
-CustomEventInit::CustomEventInit()
-{
-}
-
 CustomEvent::CustomEvent()
 {
     ScriptWrappable::init(this);
@@ -41,7 +37,6 @@
 
 CustomEvent::CustomEvent(const AtomicString& type, const CustomEventInit& initializer)
     : Event(type, initializer)
-    , m_detail(initializer.detail)
 {
     ScriptWrappable::init(this);
 }
@@ -50,20 +45,8 @@
 {
 }
 
-void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& detail)
-{
-    ASSERT(!m_serializedScriptValue.get());
-    if (dispatched())
-        return;
-
-    initEvent(type, canBubble, cancelable);
-
-    m_detail = detail;
-}
-
 void CustomEvent::initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> serializedScriptValue)
 {
-    ASSERT(m_detail.hasNoValue());
     if (dispatched())
         return;
 
diff --git a/Source/core/dom/CustomEvent.h b/Source/core/dom/CustomEvent.h
index 6afc0ae..22466bf 100644
--- a/Source/core/dom/CustomEvent.h
+++ b/Source/core/dom/CustomEvent.h
@@ -32,11 +32,7 @@
 
 namespace WebCore {
 
-struct CustomEventInit : public EventInit {
-    CustomEventInit();
-
-    ScriptValue detail;
-};
+typedef EventInit CustomEventInit;
 
 class CustomEvent : public Event {
 public:
@@ -52,19 +48,16 @@
         return adoptRef(new CustomEvent(type, initializer));
     }
 
-    void initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& detail);
     void initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue>);
 
     virtual const AtomicString& interfaceName() const;
 
-    const ScriptValue& detail() const { return m_detail; }
-    PassRefPtr<SerializedScriptValue> serializedScriptValue() { return m_serializedScriptValue; }
+    SerializedScriptValue* serializedScriptValue() { return m_serializedScriptValue.get(); }
 
 private:
     CustomEvent();
     CustomEvent(const AtomicString& type, const CustomEventInit& initializer);
 
-    ScriptValue m_detail;
     RefPtr<SerializedScriptValue> m_serializedScriptValue;
 };
 
diff --git a/Source/core/dom/CustomEvent.idl b/Source/core/dom/CustomEvent.idl
index f4a67e4..ed86fda 100644
--- a/Source/core/dom/CustomEvent.idl
+++ b/Source/core/dom/CustomEvent.idl
@@ -28,8 +28,8 @@
 ] interface CustomEvent : Event {
     [InitializedByEventConstructor, Custom] readonly attribute any detail;
 
-    void initCustomEvent([Default=Undefined] optional DOMString typeArg, 
-                         [Default=Undefined] optional boolean canBubbleArg, 
-                         [Default=Undefined] optional boolean cancelableArg, 
-                         [Default=Undefined] optional any detailArg);
+    [Custom] void initCustomEvent([Default=Undefined] optional DOMString typeArg,
+                                  [Default=Undefined] optional boolean canBubbleArg,
+                                  [Default=Undefined] optional boolean cancelableArg,
+                                  [Default=Undefined] optional any detailArg);
 };
diff --git a/Source/core/dom/DOMError.cpp b/Source/core/dom/DOMError.cpp
index a8f316c..e77d271 100644
--- a/Source/core/dom/DOMError.cpp
+++ b/Source/core/dom/DOMError.cpp
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "core/dom/DOMError.h"
 
-#include <wtf/text/WTFString.h>
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DOMException.cpp b/Source/core/dom/DOMException.cpp
index ff41cd3..b1dc214 100644
--- a/Source/core/dom/DOMException.cpp
+++ b/Source/core/dom/DOMException.cpp
@@ -48,7 +48,7 @@
     { "InUseAttributeError", "An attempt was made to add an attribute that is already in use elsewhere.", 10 },
     { "InvalidStateError", "An attempt was made to use an object that is not, or is no longer, usable.", 11 },
     { "SyntaxError", "An invalid or illegal string was specified.", 12 },
-    { "InvalidModificationError", "An attempt was made to modify the type of the underlying object.", 13 },
+    { "InvalidModificationError", "The object can not be modified in this way.", 13 },
     { "NamespaceError", "An attempt was made to create or change an object in a way which is incorrect with regard to namespaces.", 14 },
     { "InvalidAccessError", "A parameter or an operation was not supported by the underlying object.", 15 },
     { "TypeMismatchError", "The type of an object was incompatible with the expected type of the parameter associated to the object.", 17 },
@@ -61,12 +61,7 @@
     { "InvalidNodeTypeError", "The supplied node is invalid or has an invalid ancestor for this operation.", 24 },
     { "DataCloneError", "An object could not be cloned.", 25 },
 
-    // These are IDB-specific errors.
-    // FIXME: NotFoundError is duplicated to have a more specific error message.
-    // https://code.google.com/p/chromium/issues/detail?id=252233
-    { "NotFoundError", "An operation failed because the requested database object could not be found.", 8 },
-
-    // More IDB-specific errors.
+    // Indexed DB
     { "UnknownError", "An unknown error occurred within Indexed Database.", 0 },
     { "ConstraintError", "A mutation operation in the transaction failed because a constraint was not satisfied.", 0 },
     { "DataError", "The data provided does not meet requirements.", 0 },
@@ -83,53 +78,36 @@
     { "NoModificationAllowedError", "An attempt was made to write to a file or directory which could not be modified due to the state of the underlying filesystem.", 7 },
     { "InvalidStateError", "An operation that depends on state cached in an interface object was made but the state had changed since it was read from disk.", 11 },
     { "SyntaxError", "An invalid or unsupported argument was given, like an invalid line ending specifier.", 12 },
-    { "InvalidModificationError", "The modification request was illegal.", 13 },
     { "QuotaExceededError", "The operation failed because it would cause the application to exceed its storage quota.", 22 },
     { "TypeMismatchError", "The path supplied exists, but was not an entry of requested type.", 17 },
     { "PathExistsError", "An attempt was made to create a file or directory where an element already exists.", 0 },
 
     // SQL
-    { "UnknownError", "The operation failed for reasons unrelated to the database.", 0 },
     { "DatabaseError", "The operation failed for some reason related to the database.", 0 },
-    { "VersionError", "The actual database version did not match the expected version.", 0 },
-    { "TooLargeError", "Data returned from the database is too large.", 0 },
-    { "QuotaExceededError", "Quota was exceeded.", 22 },
-    { "SyntaxError", "Invalid or unauthorized statement; or the number of arguments did not match the number of ? placeholders.", 12 },
-    { "ConstraintError", "A constraint was violated.", 0 },
-    { "TimeoutError", "A transaction lock could not be acquired in a reasonable time.", 23 },
 };
 
 static const CoreException* getErrorEntry(ExceptionCode ec)
 {
     size_t tableSize = WTF_ARRAY_LENGTH(coreExceptions);
-    size_t tableIndex = ec - INDEX_SIZE_ERR;
+    size_t tableIndex = ec - IndexSizeError;
 
     return tableIndex < tableSize ? &coreExceptions[tableIndex] : 0;
 }
 
-DOMException::DOMException(ExceptionCode ec)
+DOMException::DOMException(unsigned short code, const char* name, const char * message)
 {
-    const CoreException* entry = getErrorEntry(ec);
-    ASSERT(entry);
-    if (!entry) {
-        m_code = 0;
-        m_name = "UnknownError";
-        m_message = "Unknown Error";
-    } else {
-        m_code = entry->code;
-        if (entry->name)
-            m_name = entry->name;
-        else
-            m_name = "Error";
-        m_message = entry->message;
-    }
-
+    ASSERT(name);
+    m_code = code;
+    m_name = name;
+    m_message = message;
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<DOMException> DOMException::create(ExceptionCode ec)
+PassRefPtr<DOMException> DOMException::create(ExceptionCode ec, const char* message)
 {
-    return adoptRef(new DOMException(ec));
+    const CoreException* entry = getErrorEntry(ec);
+    ASSERT(entry);
+    return adoptRef(new DOMException(entry->code, entry->name ? entry->name : "Error", message ? message : entry->message));
 }
 
 String DOMException::toString() const
diff --git a/Source/core/dom/DOMException.h b/Source/core/dom/DOMException.h
index 88fbebb..06e4cbd 100644
--- a/Source/core/dom/DOMException.h
+++ b/Source/core/dom/DOMException.h
@@ -39,7 +39,7 @@
 
 class DOMException : public RefCounted<DOMException>, public ScriptWrappable {
 public:
-    static PassRefPtr<DOMException> create(ExceptionCode);
+    static PassRefPtr<DOMException> create(ExceptionCode, const char* message = 0);
 
     unsigned short code() const { return m_code; }
     String name() const { return m_name; }
@@ -52,7 +52,7 @@
     static unsigned short getLegacyErrorCode(ExceptionCode);
 
 private:
-    explicit DOMException(ExceptionCode);
+    DOMException(unsigned short m_code, const char* name, const char* message);
 
     unsigned short m_code;
     String m_name;
diff --git a/Source/core/dom/DOMImplementation.cpp b/Source/core/dom/DOMImplementation.cpp
index d9e8989..9edaf7a 100644
--- a/Source/core/dom/DOMImplementation.cpp
+++ b/Source/core/dom/DOMImplementation.cpp
@@ -255,11 +255,11 @@
 {
     RefPtr<Document> doc;
     if (namespaceURI == SVGNames::svgNamespaceURI)
-        doc = SVGDocument::create(0, KURL());
+        doc = SVGDocument::create();
     else if (namespaceURI == HTMLNames::xhtmlNamespaceURI)
-        doc = Document::createXHTML(0, KURL());
+        doc = Document::createXHTML();
     else
-        doc = Document::create(0, KURL());
+        doc = Document::create();
 
     doc->setSecurityOrigin(m_document->securityOrigin());
     doc->setContextFeatures(m_document->contextFeatures());
@@ -271,13 +271,13 @@
             return 0;
     }
 
-    // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
+    // WrongDocumentError: Raised if doctype has already been used with a different document or was
     // created from a different implementation.
     // Hixie's interpretation of the DOM Core spec suggests we should prefer
-    // other exceptions to WRONG_DOCUMENT_ERR (based on order mentioned in spec),
+    // other exceptions to WrongDocumentError (based on order mentioned in spec),
     // but this matches the new DOM Core spec (http://www.w3.org/TR/domcore/).
     if (doctype && doctype->document()) {
-        ec = WRONG_DOCUMENT_ERR;
+        ec = WrongDocumentError;
         return 0;
     }
 
@@ -372,7 +372,7 @@
 
 PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
 {
-    RefPtr<HTMLDocument> d = HTMLDocument::create(0, KURL());
+    RefPtr<HTMLDocument> d = HTMLDocument::create();
     d->open();
     d->write("<!doctype html><html><body></body></html>");
     if (!title.isNull())
@@ -385,13 +385,13 @@
 PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const KURL& url, bool inViewSourceMode)
 {
     if (inViewSourceMode)
-        return HTMLViewSourceDocument::create(frame, url, type);
+        return HTMLViewSourceDocument::create(DocumentInit(url, frame), type);
 
     // Plugins cannot take HTML and XHTML from us, and we don't even need to initialize the plugin database for those.
     if (type == "text/html")
-        return HTMLDocument::create(frame, url);
+        return HTMLDocument::create(DocumentInit(url, frame));
     if (type == "application/xhtml+xml")
-        return Document::createXHTML(frame, url);
+        return Document::createXHTML(DocumentInit(url, frame));
 
     PluginData* pluginData = 0;
     if (frame && frame->page() && frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
@@ -400,27 +400,27 @@
     // PDF is one image type for which a plugin can override built-in support.
     // We do not want QuickTime to take over all image types, obviously.
     if ((type == "application/pdf" || type == "text/pdf") && pluginData && pluginData->supportsMimeType(type))
-        return PluginDocument::create(frame, url);
+        return PluginDocument::create(DocumentInit(url, frame));
     if (Image::supportsType(type))
-        return ImageDocument::create(frame, url);
+        return ImageDocument::create(DocumentInit(url, frame));
 
     // Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument
     if (HTMLMediaElement::supportsType(ContentType(type)))
-        return MediaDocument::create(frame, url);
+        return MediaDocument::create(DocumentInit(url, frame));
 
     // Everything else except text/plain can be overridden by plugins. In particular, Adobe SVG Viewer should be used for SVG, if installed.
     // Disallowing plug-ins to use text/plain prevents plug-ins from hijacking a fundamental type that the browser is expected to handle,
     // and also serves as an optimization to prevent loading the plug-in database in the common case.
     if (type != "text/plain" && pluginData && pluginData->supportsMimeType(type)) 
-        return PluginDocument::create(frame, url);
+        return PluginDocument::create(DocumentInit(url, frame));
     if (isTextMIMEType(type))
-        return TextDocument::create(frame, url);
+        return TextDocument::create(DocumentInit(url, frame));
     if (type == "image/svg+xml")
-        return SVGDocument::create(frame, url);
+        return SVGDocument::create(DocumentInit(url, frame));
     if (isXMLMIMEType(type))
-        return Document::create(frame, url);
+        return Document::create(DocumentInit(url, frame));
 
-    return HTMLDocument::create(frame, url);
+    return HTMLDocument::create(DocumentInit(url, frame));
 }
 
 }
diff --git a/Source/core/dom/DOMNamedFlowCollection.h b/Source/core/dom/DOMNamedFlowCollection.h
index 0a87b2b..c7e6a6c 100644
--- a/Source/core/dom/DOMNamedFlowCollection.h
+++ b/Source/core/dom/DOMNamedFlowCollection.h
@@ -31,10 +31,10 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/NamedFlowCollection.h"
-#include <wtf/ListHashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
+#include "wtf/ListHashSet.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DOMStringList.h b/Source/core/dom/DOMStringList.h
index f4dddd3..44de344 100644
--- a/Source/core/dom/DOMStringList.h
+++ b/Source/core/dom/DOMStringList.h
@@ -27,10 +27,10 @@
 #define DOMStringList_h
 
 #include "bindings/v8/ScriptWrappable.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DOMStringMap.h b/Source/core/dom/DOMStringMap.h
index 90a6019..3408945 100644
--- a/Source/core/dom/DOMStringMap.h
+++ b/Source/core/dom/DOMStringMap.h
@@ -27,9 +27,9 @@
 #define DOMStringMap_h
 
 #include "bindings/v8/ScriptWrappable.h"
-#include <wtf/Noncopyable.h>
-#include <wtf/text/WTFString.h>
-#include <wtf/Vector.h>
+#include "wtf/Noncopyable.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DatasetDOMStringMap.cpp b/Source/core/dom/DatasetDOMStringMap.cpp
index d1db9f1..b959ec0 100644
--- a/Source/core/dom/DatasetDOMStringMap.cpp
+++ b/Source/core/dom/DatasetDOMStringMap.cpp
@@ -29,8 +29,8 @@
 #include "core/dom/Attribute.h"
 #include "core/dom/Element.h"
 #include "core/dom/ExceptionCode.h"
-#include <wtf/ASCIICType.h>
-#include <wtf/text/StringBuilder.h>
+#include "wtf/ASCIICType.h"
+#include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
@@ -179,7 +179,7 @@
 void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionCode& ec)
 {
     if (!isValidPropertyName(name)) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return;
     }
 
@@ -189,7 +189,7 @@
 void DatasetDOMStringMap::deleteItem(const String& name, ExceptionCode& ec)
 {
     if (!isValidPropertyName(name)) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return;
     }
 
diff --git a/Source/core/dom/DatasetDOMStringMap.h b/Source/core/dom/DatasetDOMStringMap.h
index 8788b6e..c716181 100644
--- a/Source/core/dom/DatasetDOMStringMap.h
+++ b/Source/core/dom/DatasetDOMStringMap.h
@@ -27,7 +27,7 @@
 #define DatasetDOMStringMap_h
 
 #include "core/dom/DOMStringMap.h"
-#include <wtf/PassOwnPtr.h>
+#include "wtf/PassOwnPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DeviceOrientationData.h b/Source/core/dom/DeviceOrientationData.h
index 1df9b65..2c37a13 100644
--- a/Source/core/dom/DeviceOrientationData.h
+++ b/Source/core/dom/DeviceOrientationData.h
@@ -26,8 +26,8 @@
 #ifndef DeviceOrientationData_h
 #define DeviceOrientationData_h
 
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index b296bc1..7b3cad2 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -52,7 +52,7 @@
 #include "core/dom/CDATASection.h"
 #include "core/dom/Comment.h"
 #include "core/dom/ContextFeatures.h"
-#include "core/dom/CustomElementRegistry.h"
+#include "core/dom/CustomElementRegistrationContext.h"
 #include "core/dom/DOMImplementation.h"
 #include "core/dom/DOMNamedFlowCollection.h"
 #include "core/dom/DocumentEventQueue.h"
@@ -104,8 +104,9 @@
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLHtmlElement.h"
 #include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImportsController.h"
+#include "core/html/HTMLImport.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/HTMLNameCollection.h"
 #include "core/html/HTMLScriptElement.h"
@@ -160,10 +161,6 @@
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGStyleElement.h"
 #include "core/workers/SharedWorkerRepository.h"
-#include "core/xml/XPathEvaluator.h"
-#include "core/xml/XPathExpression.h"
-#include "core/xml/XPathNSResolver.h"
-#include "core/xml/XPathResult.h"
 #include "core/xml/XSLTProcessor.h"
 #include "core/xml/parser/XMLDocumentParser.h"
 #include "weborigin/SchemeRegistry.h"
@@ -188,8 +185,6 @@
 
 using namespace HTMLNames;
 
-// #define INSTRUMENT_LAYOUT_SCHEDULING 1
-
 static const double cDefaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
 
 static const unsigned cMaxWriteRecursionDepth = 21;
@@ -369,11 +364,11 @@
         if (document->focusedNode()->renderer() && document->focusedNode()->renderer()->needsLayout())
             return;
         if (!document->focusedNode()->isFocusable())
-            document->setFocusedNode(0);
+            document->setFocusedElement(0);
     }
 };
 
-Document::Document(Frame* frame, const KURL& url, DocumentClassFlags documentClasses)
+Document::Document(const DocumentInit& initializer, DocumentClassFlags documentClasses)
     : ContainerNode(0, CreateDocument)
     , TreeScope(this)
     , m_styleResolverThrowawayTimer(this, &Document::styleResolverThrowawayTimerFired)
@@ -383,8 +378,9 @@
     , m_needsNotifyRemoveAllPendingStylesheet(false)
     , m_hasNodesWithPlaceholderStyle(false)
     , m_pendingSheetLayout(NoLayoutWithPendingSheets)
-    , m_frame(frame)
+    , m_frame(initializer.frame())
     , m_domWindow(0)
+    , m_import(initializer.import())
     , m_activeParserCount(0)
     , m_contextFeatures(ContextFeatures::defaultSwitch())
     , m_wellFormed(false)
@@ -393,7 +389,6 @@
     , m_ignoreAutofocus(false)
     , m_compatibilityMode(NoQuirksMode)
     , m_compatibilityModeLocked(false)
-    , m_textColor(Color::black)
     , m_didPostCheckFocusedNodeTask(false)
     , m_domTreeVersion(++s_globalTreeVersion)
     , m_listenerTypes(0)
@@ -426,7 +421,6 @@
     , m_designMode(inherit)
     , m_hasAnnotatedRegions(false)
     , m_annotatedRegionsDirty(false)
-    , m_accessKeyMapValid(false)
     , m_useSecureKeyboardEntryWhenActive(false)
     , m_documentClasses(documentClasses)
     , m_isViewSource(false)
@@ -476,20 +470,23 @@
     // See fast/dom/early-frame-url.html
     // and fast/dom/location-new-window-no-crash.html, respectively.
     // FIXME: Can/should we unify this behavior?
-    if ((m_frame && m_frame->ownerElement()) || !url.isEmpty())
-        setURL(url);
+    if (initializer.shouldSetURL())
+        setURL(initializer.url());
 
-    resetLinkColor();
-    resetVisitedLinkColor();
-    resetActiveLinkColor();
-
-    initSecurityContext();
+    initSecurityContext(initializer);
     initDNSPrefetch();
 
     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
         m_nodeListCounts[i] = 0;
 
     InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
+
+    bool shouldProcessCustomElements =
+        (isHTMLDocument() || isXHTMLDocument())
+        && RuntimeEnabledFeatures::customDOMElementsEnabled();
+    m_registrationContext = shouldProcessCustomElements
+        ? CustomElementRegistrationContext::create()
+        : CustomElementRegistrationContext::nullRegistrationContext();
 }
 
 static void histogramMutationEventUsage(const unsigned short& listenerTypes)
@@ -552,6 +549,11 @@
     if (m_styleSheetList)
         m_styleSheetList->detachFromDocument();
 
+    if (m_import) {
+        m_import->wasDetachedFromDocument();
+        m_import = 0;
+    }
+
     m_styleSheetCollection.clear();
 
     if (m_elemSheet)
@@ -596,8 +598,12 @@
 
     detachParser();
 
-    m_registry.clear();
-    m_imports.clear();
+    m_registrationContext.clear();
+
+    if (m_import) {
+        m_import->wasDetachedFromDocument();
+        m_import = 0;
+    }
 
     // removeDetachedChildren() doesn't always unregister IDs,
     // so tear down scope information upfront to avoid having stale references in the map.
@@ -623,37 +629,6 @@
     return TreeScope::getElementById(id);
 }
 
-Element* Document::getElementByAccessKey(const String& key)
-{
-    if (key.isEmpty())
-        return 0;
-    if (!m_accessKeyMapValid) {
-        buildAccessKeyMap(this);
-        m_accessKeyMapValid = true;
-    }
-    return m_elementsByAccessKey.get(key.impl());
-}
-
-void Document::buildAccessKeyMap(TreeScope* scope)
-{
-    ASSERT(scope);
-    Node* rootNode = scope->rootNode();
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
-        const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
-        if (!accessKey.isEmpty())
-            m_elementsByAccessKey.set(accessKey.impl(), element);
-
-        for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->olderShadowRoot())
-            buildAccessKeyMap(root);
-    }
-}
-
-void Document::invalidateAccessKeyMap()
-{
-    m_accessKeyMapValid = false;
-    m_elementsByAccessKey.clear();
-}
-
 SelectorQueryCache* Document::selectorQueryCache()
 {
     if (!m_selectorQueryCache)
@@ -687,21 +662,6 @@
     return inQuirksMode() ? "BackCompat" : "CSS1Compat";
 }
 
-void Document::resetLinkColor()
-{
-    m_linkColor = Color(0, 0, 238);
-}
-
-void Document::resetVisitedLinkColor()
-{
-    m_visitedLinkColor = Color(85, 26, 139);
-}
-
-void Document::resetActiveLinkColor()
-{
-    m_activeLinkColor.setNamedColor("red");
-}
-
 void Document::setDocType(PassRefPtr<DocumentType> docType)
 {
     // This should never be called more than once.
@@ -725,7 +685,7 @@
 
 bool Document::hasManifest() const
 {
-    return documentElement() && documentElement()->hasTagName(htmlTag) && documentElement()->hasAttribute(manifestAttr);
+    return documentElement() && isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
 }
 
 void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -743,7 +703,7 @@
 PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
 {
     if (!isValidName(name)) {
-        ec = INVALID_CHARACTER_ERR;
+        ec = InvalidCharacterError;
         return 0;
     }
 
@@ -756,21 +716,19 @@
 PassRefPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionCode& ec)
 {
     if (!isValidName(localName)) {
-        ec = INVALID_CHARACTER_ERR;
+        ec = InvalidCharacterError;
         return 0;
     }
 
     RefPtr<Element> element;
 
-    if (CustomElementRegistry::isCustomTagName(localName))
-        element = ensureCustomElementRegistry()->createCustomTagElement(QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
+    if (CustomElementRegistrationContext::isCustomTagName(localName))
+        element = registrationContext()->createCustomTagElement(this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
     else
         element = createElement(localName, ec);
 
-    if (!typeExtension.isNull()) {
-        setTypeExtension(element.get(), typeExtension);
-        ensureCustomElementRegistry()->didGiveTypeExtension(element.get(), typeExtension);
-    }
+    if (!typeExtension.isNull())
+        registrationContext()->setTypeExtension(element.get(), typeExtension);
 
     return element;
 }
@@ -783,20 +741,18 @@
 
     QualifiedName qName(prefix, localName, namespaceURI);
     if (!hasValidNamespaceForElements(qName)) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return 0;
     }
 
     RefPtr<Element> element;
-    if (CustomElementRegistry::isCustomTagName(qName.localName()))
-        element = ensureCustomElementRegistry()->createCustomTagElement(qName);
+    if (CustomElementRegistrationContext::isCustomTagName(qName.localName()))
+        element = registrationContext()->createCustomTagElement(this, qName);
     else
         element = createElementNS(namespaceURI, qualifiedName, ec);
 
-    if (!typeExtension.isNull()) {
-        setTypeExtension(element.get(), typeExtension);
-        ensureCustomElementRegistry()->didGiveTypeExtension(element.get(), typeExtension);
-    }
+    if (!typeExtension.isNull())
+        registrationContext()->setTypeExtension(element.get(), typeExtension);
 
     return element;
 }
@@ -808,29 +764,15 @@
 
 ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionCode& ec)
 {
-    if (!isHTMLDocument() && !isXHTMLDocument()) {
-        ec = NOT_SUPPORTED_ERR;
-        return ScriptValue();
-    }
-
     CustomElementConstructorBuilder constructorBuilder(state, &options);
-    ensureCustomElementRegistry()->registerElement(&constructorBuilder, name, ec);
+    registrationContext()->registerElement(this, &constructorBuilder, name, ec);
     return constructorBuilder.bindingsReturnValue();
 }
 
-CustomElementRegistry* Document::ensureCustomElementRegistry()
+void Document::setImport(HTMLImport* import)
 {
-    if (!m_registry) {
-        ASSERT(isHTMLDocument() || isXHTMLDocument());
-        m_registry = adoptRef(new CustomElementRegistry(this));
-    }
-    return m_registry.get();
-}
-
-void Document::setImports(PassRefPtr<HTMLImportsController> imports)
-{
-    ASSERT(!m_imports);
-    m_imports = imports;
+    ASSERT(!m_import || !import);
+    m_import = import;
 }
 
 void Document::didLoadAllImports()
@@ -840,7 +782,7 @@
 
 bool Document::haveImportsLoaded() const
 {
-    return !m_imports || m_imports->haveLoaded();
+    return !m_import || m_import->haveChildrenLoaded();
 }
 
 PassRefPtr<DocumentFragment> Document::createDocumentFragment()
@@ -861,7 +803,7 @@
 PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
 {
     if (isHTMLDocument()) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return CDATASection::create(this, data);
@@ -870,11 +812,11 @@
 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
 {
     if (!isValidName(target)) {
-        ec = INVALID_CHARACTER_ERR;
+        ec = InvalidCharacterError;
         return 0;
     }
     if (isHTMLDocument()) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return ProcessingInstruction::create(this, target, data);
@@ -895,7 +837,7 @@
     ec = 0;
 
     if (!importedNode) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
 
@@ -913,7 +855,7 @@
         // FIXME: The following check might be unnecessary. Is it possible that
         // oldElement has mismatched prefix/namespace?
         if (!hasValidNamespaceForElements(oldElement->tagQName())) {
-            ec = NAMESPACE_ERR;
+            ec = NamespaceError;
             return 0;
         }
         RefPtr<Element> newElement = createElement(oldElement->tagQName(), false);
@@ -965,15 +907,14 @@
     case XPATH_NAMESPACE_NODE:
         break;
     }
-    ec = NOT_SUPPORTED_ERR;
+    ec = NotSupportedError;
     return 0;
 }
 
-
 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
 {
     if (!source) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
 
@@ -985,7 +926,7 @@
     case DOCUMENT_NODE:
     case DOCUMENT_TYPE_NODE:
     case XPATH_NAMESPACE_NODE:
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     case ATTRIBUTE_NODE: {
         Attr* attr = toAttr(source.get());
@@ -997,14 +938,14 @@
     default:
         if (source->isShadowRoot()) {
             // ShadowRoot cannot disconnect itself from the host node.
-            ec = HIERARCHY_REQUEST_ERR;
+            ec = HierarchyRequestError;
             return 0;
         }
 
         if (source->isFrameOwnerElement()) {
             HTMLFrameOwnerElement* frameOwnerElement = toFrameOwnerElement(source.get());
             if (frame() && frame()->tree()->isDescendantOf(frameOwnerElement->contentFrame())) {
-                ec = HIERARCHY_REQUEST_ERR;
+                ec = HierarchyRequestError;
                 return 0;
             }
         }
@@ -1112,7 +1053,7 @@
 
     QualifiedName qName(prefix, localName, namespaceURI);
     if (!hasValidNamespaceForElements(qName)) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return 0;
     }
 
@@ -1189,19 +1130,19 @@
         return;
     m_contentLanguage = language;
 
-    // Recalculate style so language is used when selecting the initial font.
-    styleResolverChanged(DeferRecalcStyle);
+    // Document's style depends on the content language.
+    scheduleForcedStyleRecalc();
 }
 
 void Document::setXMLVersion(const String& version, ExceptionCode& ec)
 {
     if (!implementation()->hasFeature("XML", String())) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return;
     }
 
     if (!XMLDocumentParser::supportsXMLVersion(version)) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return;
     }
 
@@ -1211,7 +1152,7 @@
 void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
 {
     if (!implementation()->hasFeature("XML", String())) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return;
     }
 
@@ -1382,9 +1323,9 @@
     updateTitle(StringWithDirection(title, LTR));
 
     if (m_titleElement) {
-        ASSERT(m_titleElement->hasTagName(titleTag));
-        if (m_titleElement->hasTagName(titleTag))
-            static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(title);
+        ASSERT(isHTMLTitleElement(m_titleElement.get()));
+        if (isHTMLTitleElement(m_titleElement.get()))
+            toHTMLTitleElement(m_titleElement.get())->setText(title);
     }
 }
 
@@ -1410,12 +1351,13 @@
 
     // Update title based on first title element in the head, if one exists.
     if (HTMLElement* headElement = head()) {
-        for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
-            if (e->hasTagName(titleTag)) {
-                HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
+        for (Node* e = headElement->firstChild(); e; e = e->nextSibling()) {
+            if (isHTMLTitleElement(e)) {
+                HTMLTitleElement* titleElement = toHTMLTitleElement(e);
                 setTitleElement(titleElement->textWithDirection(), titleElement);
                 break;
             }
+        }
     }
 
     if (!m_titleElement)
@@ -1510,7 +1452,7 @@
 {
     // FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
@@ -1519,7 +1461,7 @@
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     // FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
@@ -1530,7 +1472,7 @@
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     // FIXME: Ditto.
@@ -1540,7 +1482,7 @@
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     // FIXME: Warn if |expandEntityReferences| is specified. This optional argument is deprecated in DOM4.
@@ -1551,7 +1493,7 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
@@ -1560,7 +1502,7 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
@@ -1569,7 +1511,7 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionCode& ec)
 {
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return TreeWalker::create(root, whatToShow, filter);
@@ -1579,7 +1521,7 @@
 {
     UNUSED_PARAM(expandEntityReferences);
     if (!root) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
     return TreeWalker::create(root, whatToShow, filter);
@@ -1605,9 +1547,6 @@
 
     ASSERT(childNeedsStyleRecalc() || m_pendingStyleRecalcShouldForce);
 
-    // FIXME: Why on earth is this here? This is clearly misplaced.
-    invalidateAccessKeyMap();
-
     m_styleRecalcTimer.startOneShot(0);
 
     InspectorInstrumentation::didScheduleStyleRecalculation(this);
@@ -1652,7 +1591,7 @@
         return; // Guard against re-entrancy. -dwh
 
     TRACE_EVENT0("webkit", "Document::recalcStyle");
-    TraceEvent::SamplingState0Scope("Blink\0Blink-RecalcStyle");
+    TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
 
     // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
     // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
@@ -1759,8 +1698,8 @@
         return;
 
     bool needsStyleRecalc = hasPendingForcedStyleRecalc();
-    for (Node* n = node; n && !needsStyleRecalc; n = n->parentNode())
-        needsStyleRecalc = n->needsStyleRecalc();
+    for (Node* ancestor = node; ancestor && !needsStyleRecalc; ancestor = ancestor->parentOrShadowHostNode())
+        needsStyleRecalc = ancestor->needsStyleRecalc();
     if (needsStyleRecalc)
         updateStyleIfNeeded();
 }
@@ -1831,24 +1770,18 @@
 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
 {
     ASSERT_ARG(element, element->document() == this);
-
-    bool oldIgnore = m_ignorePendingStylesheets;
-    m_ignorePendingStylesheets = true;
-    RefPtr<RenderStyle> style = styleResolver()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
-    m_ignorePendingStylesheets = oldIgnore;
-    return style.release();
+    TemporaryChange<bool> ignoreStyleSheets(m_ignorePendingStylesheets, true);
+    return styleResolver()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
 }
 
 PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
 {
-    RefPtr<RenderStyle> style = styleResolver()->styleForPage(pageIndex);
-    return style.release();
+    return styleResolver()->styleForPage(pageIndex);
 }
 
 bool Document::isPageBoxVisible(int pageIndex)
 {
-    RefPtr<RenderStyle> style = styleForPage(pageIndex);
-    return style->visibility() != HIDDEN; // display property doesn't apply to @page.
+    return styleForPage(pageIndex)->visibility() != HIDDEN; // display property doesn't apply to @page.
 }
 
 void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
@@ -2176,45 +2109,39 @@
 
 HTMLElement* Document::body() const
 {
-    Node* de = documentElement();
-    if (!de)
+    if (!documentElement())
         return 0;
 
-    // try to prefer a FRAMESET element over BODY
-    Node* body = 0;
-    for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
-        if (i->hasTagName(framesetTag))
-            return toHTMLElement(i);
-
-        if (i->hasTagName(bodyTag) && !body)
-            body = i;
+    for (Node* child = documentElement()->firstChild(); child; child = child->nextSibling()) {
+        if (child->hasTagName(framesetTag) || child->hasTagName(bodyTag))
+            return toHTMLElement(child);
     }
-    return toHTMLElement(body);
+
+    return 0;
 }
 
 void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionCode& ec)
 {
     RefPtr<HTMLElement> newBody = prpNewBody;
 
-    if (!newBody || !documentElement() || !newBody->hasTagName(bodyTag)) {
-        ec = HIERARCHY_REQUEST_ERR;
+    if (!newBody || !documentElement()) {
+        ec = HierarchyRequestError;
         return;
     }
 
-    if (newBody->document() && newBody->document() != this) {
-        ec = 0;
-        RefPtr<Node> node = importNode(newBody.get(), true, ec);
-        if (ec)
-            return;
-
-        newBody = toHTMLElement(node.get());
+    if (!newBody->hasTagName(bodyTag) && !newBody->hasTagName(framesetTag)) {
+        ec = HierarchyRequestError;
+        return;
     }
 
-    HTMLElement* b = body();
-    if (!b)
-        documentElement()->appendChild(newBody.release(), ec);
+    HTMLElement* oldBody = body();
+    if (oldBody == newBody)
+        return;
+
+    if (oldBody)
+        documentElement()->replaceChild(newBody.release(), oldBody, ec, AttachLazily);
     else
-        documentElement()->replaceChild(newBody.release(), b, ec);
+        documentElement()->appendChild(newBody.release(), ec, AttachLazily);
 }
 
 HTMLHeadElement* Document::head()
@@ -2285,7 +2212,7 @@
     detachParser();
 
     Frame* f = frame();
-    if (f)
+    if (f && !RuntimeEnabledFeatures::webAnimationsCSSEnabled())
         f->animation()->resumeAnimationsForDocument(this);
 
     if (f && f->script()->canExecuteScripts(NotAboutToExecuteScript)) {
@@ -2309,10 +2236,6 @@
 
     if (f)
         f->loader()->handledOnloadEvents();
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("onload fired at %d\n", elapsedTime());
-#endif
 
     // An event handler may have removed the frame
     if (!frame()) {
@@ -2379,11 +2302,6 @@
 
     if (!m_bParsing && view())
         view()->scheduleRelayout();
-
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement() && !m_bParsing)
-        printf("Parsing finished at %d\n", elapsedTime());
-#endif
 }
 
 bool Document::shouldScheduleLayout()
@@ -2395,7 +2313,7 @@
     //    (b) Only schedule layout once we have a body element.
 
     return (haveStylesheetsLoaded() && body())
-        || (documentElement() && !documentElement()->hasTagName(htmlTag));
+        || (documentElement() && !isHTMLHtmlElement(documentElement()));
 }
 
 bool Document::isLayoutTimerActive()
@@ -2430,11 +2348,6 @@
     if (m_writeRecursionIsTooDeep)
        return;
 
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("Beginning a document.write at %d\n", elapsedTime());
-#endif
-
     bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
     if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
         return;
@@ -2444,11 +2357,6 @@
 
     ASSERT(m_parser);
     m_parser->insert(text);
-
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("Ending a document.write at %d\n", elapsedTime());
-#endif
 }
 
 void Document::write(const String& text, Document* ownerDocument)
@@ -2537,8 +2445,8 @@
         // Base URL change changes any relative visited links.
         // FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
         for (Element* element = ElementTraversal::firstWithin(this); element; element = ElementTraversal::next(element)) {
-            if (element->hasTagName(aTag))
-                static_cast<HTMLAnchorElement*>(element)->invalidateCachedVisitedLinkHash();
+            if (isHTMLAnchorElement(element))
+                toHTMLAnchorElement(element)->invalidateCachedVisitedLinkHash();
         }
     }
 }
@@ -2706,75 +2614,23 @@
     return m_elemSheet.get();
 }
 
-int Document::nodeAbsIndex(Node *node)
-{
-    ASSERT(node->document() == this);
-
-    int absIndex = 0;
-    for (Node* n = node; n && n != this; n = NodeTraversal::previous(n))
-        absIndex++;
-    return absIndex;
-}
-
-Node* Document::nodeWithAbsIndex(int absIndex)
-{
-    Node* n = this;
-    for (int i = 0; n && (i < absIndex); i++)
-        n = NodeTraversal::next(n);
-    return n;
-}
-
 void Document::processHttpEquiv(const String& equiv, const String& content)
 {
     ASSERT(!equiv.isNull() && !content.isNull());
 
-    Frame* frame = this->frame();
-
-    if (equalIgnoringCase(equiv, "default-style")) {
-        // The preferred style set has been overridden as per section
-        // 14.3.2 of the HTML4.0 specification.  We need to update the
-        // sheet used variable and then update our style selector.
-        // For more info, see the test at:
-        // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
-        // -dwh
-        m_styleSheetCollection->setSelectedStylesheetSetName(content);
-        m_styleSheetCollection->setPreferredStylesheetSetName(content);
-        styleResolverChanged(DeferRecalcStyle);
-    } else if (equalIgnoringCase(equiv, "refresh")) {
-        double delay;
-        String url;
-        if (frame && parseHTTPRefresh(content, true, delay, url)) {
-            if (url.isEmpty())
-                url = m_url.string();
-            else
-                url = completeURL(url).string();
-            frame->navigationScheduler()->scheduleRedirect(delay, url);
-        }
-    } else if (equalIgnoringCase(equiv, "set-cookie")) {
-        // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
-        if (isHTMLDocument()) {
-            // Exception (for sandboxed documents) ignored.
-            toHTMLDocument(this)->setCookie(content, IGNORE_EXCEPTION);
-        }
-    } else if (equalIgnoringCase(equiv, "content-language"))
+    if (equalIgnoringCase(equiv, "default-style"))
+        processHttpEquivDefaultStyle(content);
+    else if (equalIgnoringCase(equiv, "refresh"))
+        processHttpEquivRefresh(content);
+    else if (equalIgnoringCase(equiv, "set-cookie"))
+        processHttpEquivSetCookie(content);
+    else if (equalIgnoringCase(equiv, "content-language"))
         setContentLanguage(content);
     else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
         parseDNSPrefetchControlHeader(content);
-    else if (equalIgnoringCase(equiv, "x-frame-options")) {
-        if (frame) {
-            FrameLoader* frameLoader = frame->loader();
-            unsigned long requestIdentifier = loader()->mainResourceIdentifier();
-            if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url(), requestIdentifier)) {
-                String message = "Refused to display '" + url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
-                frameLoader->stopAllLoaders();
-                // Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
-                // intent, we must navigate away from the possibly partially-rendered document to a location that
-                // doesn't inherit the parent's SecurityOrigin.
-                frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
-                addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
-            }
-        }
-    } else if (equalIgnoringCase(equiv, "content-security-policy"))
+    else if (equalIgnoringCase(equiv, "x-frame-options"))
+        processHttpEquivXFrameOptions(content);
+    else if (equalIgnoringCase(equiv, "content-security-policy"))
         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
     else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
@@ -2784,6 +2640,70 @@
         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedReport);
 }
 
+void Document::processHttpEquivDefaultStyle(const String& content)
+{
+    // The preferred style set has been overridden as per section
+    // 14.3.2 of the HTML4.0 specification. We need to update the
+    // sheet used variable and then update our style selector.
+    // For more info, see the test at:
+    // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
+    // -dwh
+    m_styleSheetCollection->setSelectedStylesheetSetName(content);
+    m_styleSheetCollection->setPreferredStylesheetSetName(content);
+    styleResolverChanged(DeferRecalcStyle);
+}
+
+void Document::processHttpEquivRefresh(const String& content)
+{
+    Frame* frame = this->frame();
+    if (!frame)
+        return;
+
+    double delay;
+    String refreshUrl;
+    if (parseHTTPRefresh(content, true, delay, refreshUrl)) {
+        if (refreshUrl.isEmpty())
+            refreshUrl = m_url.string();
+        else
+            refreshUrl = completeURL(refreshUrl).string();
+        if (!protocolIsJavaScript(refreshUrl)) {
+            frame->navigationScheduler()->scheduleRedirect(delay, refreshUrl);
+        } else {
+            String message = "Refused to refresh " + m_url.elidedString() + " to a javascript: URL";
+            addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+        }
+    }
+}
+
+void Document::processHttpEquivSetCookie(const String& content)
+{
+    // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
+    if (!isHTMLDocument())
+        return;
+
+    // Exception (for sandboxed documents) ignored.
+    toHTMLDocument(this)->setCookie(content, IGNORE_EXCEPTION);
+}
+
+void Document::processHttpEquivXFrameOptions(const String& content)
+{
+    Frame* frame = this->frame();
+    if (!frame)
+        return;
+
+    FrameLoader* frameLoader = frame->loader();
+    unsigned long requestIdentifier = loader()->mainResourceIdentifier();
+    if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url(), requestIdentifier)) {
+        String message = "Refused to display '" + url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
+        frameLoader->stopAllLoaders();
+        // Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
+        // intent, we must navigate away from the possibly partially-rendered document to a location that
+        // doesn't inherit the parent's SecurityOrigin.
+        frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+        addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
+    }
+}
+
 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
 static bool isSeparator(UChar c)
 {
@@ -2895,7 +2815,7 @@
     renderView()->hitTest(request, result);
 
     if (!request.readOnly())
-        updateHoverActiveState(request, result.innerElement());
+        updateHoverActiveState(request, result.innerElement(), &event);
 
     return MouseEventWithHitTestResults(event, result);
 }
@@ -2931,7 +2851,7 @@
 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
 {
     if (!oldChild)
-        // ContainerNode::replaceChild will raise a NOT_FOUND_ERR.
+        // ContainerNode::replaceChild will raise a NotFoundError.
         return true;
 
     if (oldChild->nodeType() == newChild->nodeType())
@@ -3057,11 +2977,6 @@
     }
     m_didCalculateStyleResolver = true;
 
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("Beginning update of style selector at time %d.\n", elapsedTime());
-#endif
-
     bool needsRecalc = m_styleSheetCollection->updateActiveStyleSheets(updateMode);
 
     if (updateType >= DeferRecalcStyle) {
@@ -3085,11 +3000,6 @@
         recalcStyle(Force);
     }
 
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("Finished update of style selector at time %d\n", elapsedTime());
-#endif
-
     if (renderer()) {
         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
         if (view())
@@ -3135,18 +3045,18 @@
     if (!m_focusedNode)
         return;
 
-    Node* focusedNode = node->treeScope()->focusedNode();
-    if (!focusedNode)
+    Element* focusedElement = node->treeScope()->adjustedFocusedElement();
+    if (!focusedElement)
         return;
 
     bool nodeInSubtree = false;
     if (amongChildrenOnly)
-        nodeInSubtree = focusedNode->isDescendantOf(node);
+        nodeInSubtree = focusedElement->isDescendantOf(node);
     else
-        nodeInSubtree = (focusedNode == node) || focusedNode->isDescendantOf(node);
+        nodeInSubtree = (focusedElement == node) || focusedElement->isDescendantOf(node);
 
     if (nodeInSubtree)
-        setFocusedNode(0);
+        setFocusedElement(0);
 }
 
 void Document::hoveredNodeDetached(Node* node)
@@ -3196,7 +3106,7 @@
     setAnnotatedRegionsDirty(false);
 }
 
-bool Document::setFocusedNode(PassRefPtr<Node> prpNewFocusedNode, FocusDirection direction)
+bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedNode, FocusDirection direction)
 {
     RefPtr<Node> newFocusedNode = prpNewFocusedNode;
 
@@ -3336,16 +3246,6 @@
     return !focusChangeBlocked;
 }
 
-void Document::getFocusableNodes(Vector<RefPtr<Node> >& nodes)
-{
-    updateLayout();
-
-    for (Node* node = firstChild(); node; node = NodeTraversal::next(node)) {
-        if (node->isFocusable())
-            nodes.append(node);
-    }
-}
-
 void Document::setCSSTarget(Element* n)
 {
     if (m_cssTarget)
@@ -3541,7 +3441,7 @@
     if (event)
         return event.release();
 
-    ec = NOT_SUPPORTED_ERR;
+    ec = NotSupportedError;
     return 0;
 }
 
@@ -3609,11 +3509,11 @@
         return String();
 
     // FIXME: The HTML5 DOM spec states that this attribute can raise an
-    // INVALID_STATE_ERR exception on getting if the Document has no
+    // InvalidStateError exception on getting if the Document has no
     // browsing context.
 
     if (!securityOrigin()->canAccessCookies()) {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return String();
     }
 
@@ -3630,11 +3530,11 @@
         return;
 
     // FIXME: The HTML5 DOM spec states that this attribute can raise an
-    // INVALID_STATE_ERR exception on setting if the Document has no
+    // InvalidStateError exception on setting if the Document has no
     // browsing context.
 
     if (!securityOrigin()->canAccessCookies()) {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return;
     }
 
@@ -3660,7 +3560,7 @@
 void Document::setDomain(const String& newDomain, ExceptionCode& ec)
 {
     if (SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(securityOrigin()->protocol())) {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return;
     }
 
@@ -3686,14 +3586,14 @@
     int newLength = newDomain.length();
     // e.g. newDomain = webkit.org (10) and domain() = www.webkit.org (14)
     if (newLength >= oldLength) {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return;
     }
 
     String test = domain();
     // Check that it's a subdomain, not e.g. "ebkit.org"
     if (test[oldLength - newLength - 1] != '.') {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return;
     }
 
@@ -3701,7 +3601,7 @@
     // and we check that it's the same thing as newDomain
     test.remove(0, oldLength - newLength);
     if (test != newDomain) {
-        ec = SECURITY_ERR;
+        ec = SecurityError;
         return;
     }
 
@@ -3802,26 +3702,19 @@
     return isValidNameNonASCII(characters, length);
 }
 
-bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionCode& ec)
+template<typename CharType>
+static bool parseQualifiedNameInternal(const String& qualifiedName, const CharType* characters, unsigned length, String& prefix, String& localName, ExceptionCode& ec)
 {
-    unsigned length = qualifiedName.length();
-
-    if (!length) {
-        ec = INVALID_CHARACTER_ERR;
-        return false;
-    }
-
     bool nameStart = true;
     bool sawColon = false;
     int colonPos = 0;
 
-    const UChar* s = qualifiedName.bloatedCharacters();
     for (unsigned i = 0; i < length;) {
         UChar32 c;
-        U16_NEXT(s, i, length, c)
+        U16_NEXT(characters, i, length, c)
         if (c == ':') {
             if (sawColon) {
-                ec = NAMESPACE_ERR;
+                ec = NamespaceError;
                 return false; // multiple colons: not allowed
             }
             nameStart = true;
@@ -3829,13 +3722,13 @@
             colonPos = i - 1;
         } else if (nameStart) {
             if (!isValidNameStart(c)) {
-                ec = INVALID_CHARACTER_ERR;
+                ec = InvalidCharacterError;
                 return false;
             }
             nameStart = false;
         } else {
             if (!isValidNamePart(c)) {
-                ec = INVALID_CHARACTER_ERR;
+                ec = InvalidCharacterError;
                 return false;
             }
         }
@@ -3847,20 +3740,34 @@
     } else {
         prefix = qualifiedName.substring(0, colonPos);
         if (prefix.isEmpty()) {
-            ec = NAMESPACE_ERR;
+            ec = NamespaceError;
             return false;
         }
         localName = qualifiedName.substring(colonPos + 1);
     }
 
     if (localName.isEmpty()) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return false;
     }
 
     return true;
 }
 
+bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionCode& ec)
+{
+    unsigned length = qualifiedName.length();
+
+    if (!length) {
+        ec = InvalidCharacterError;
+        return false;
+    }
+
+    if (qualifiedName.is8Bit())
+        return parseQualifiedNameInternal(qualifiedName, qualifiedName.characters8(), length, prefix, localName, ec);
+    return parseQualifiedNameInternal(qualifiedName, qualifiedName.characters16(), length, prefix, localName, ec);
+}
+
 void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
 {
     m_decoder = decoder;
@@ -3954,7 +3861,7 @@
     for (unsigned i = 0; Node* child = children->item(i); i++) {
         if (!child->hasTagName(linkTag))
             continue;
-        HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(child);
+        HTMLLinkElement* linkElement = toHTMLLinkElement(child);
         if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
             continue;
         if (linkElement->href().isEmpty())
@@ -4053,7 +3960,7 @@
     QualifiedName qName(prefix, localName, namespaceURI);
 
     if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return 0;
     }
 
@@ -4205,34 +4112,6 @@
     clearStyleResolver();
 }
 
-PassRefPtr<XPathExpression> Document::createExpression(const String& expression,
-                                                       XPathNSResolver* resolver,
-                                                       ExceptionCode& ec)
-{
-    if (!m_xpathEvaluator)
-        m_xpathEvaluator = XPathEvaluator::create();
-    return m_xpathEvaluator->createExpression(expression, resolver, ec);
-}
-
-PassRefPtr<XPathNSResolver> Document::createNSResolver(Node* nodeResolver)
-{
-    if (!m_xpathEvaluator)
-        m_xpathEvaluator = XPathEvaluator::create();
-    return m_xpathEvaluator->createNSResolver(nodeResolver);
-}
-
-PassRefPtr<XPathResult> Document::evaluate(const String& expression,
-                                           Node* contextNode,
-                                           XPathNSResolver* resolver,
-                                           unsigned short type,
-                                           XPathResult* result,
-                                           ExceptionCode& ec)
-{
-    if (!m_xpathEvaluator)
-        m_xpathEvaluator = XPathEvaluator::create();
-    return m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, ec);
-}
-
 const Vector<IconURL>& Document::shortcutIconURLs()
 {
     // Include any icons where type = link, rel = "shortcut icon".
@@ -4252,7 +4131,7 @@
         Node* child = children->item(i);
         if (!child->hasTagName(linkTag))
             continue;
-        HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(child);
+        HTMLLinkElement* linkElement = toHTMLLinkElement(child);
         if (!(linkElement->iconType() & iconTypesMask))
             continue;
         if (linkElement->href().isEmpty())
@@ -4296,12 +4175,17 @@
 
 void Document::initSecurityContext()
 {
+    initSecurityContext(DocumentInit(m_url, m_frame, m_import));
+}
+
+void Document::initSecurityContext(const DocumentInit& initializer)
+{
     if (haveInitializedSecurityOrigin()) {
         ASSERT(securityOrigin());
         return;
     }
 
-    if (!m_frame) {
+    if (!initializer.frame()) {
         // No source for a security context.
         // This can occur via document.implementation.createDocument().
         m_cookieURL = KURL(ParsedURLString, emptyString());
@@ -4313,11 +4197,11 @@
     // In the common case, create the security context from the currently
     // loading URL with a fresh content security policy.
     m_cookieURL = m_url;
-    enforceSandboxFlags(m_frame->loader()->effectiveSandboxFlags());
+    enforceSandboxFlags(initializer.sandboxFlags());
     setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
     setContentSecurityPolicy(ContentSecurityPolicy::create(this));
 
-    if (Settings* settings = this->settings()) {
+    if (Settings* settings = initializer.settings()) {
         if (!settings->webSecurityEnabled()) {
             // Web security is turned off. We should let this document access every other document. This is used primary by testing
             // harnesses for web sites.
@@ -4336,7 +4220,7 @@
     }
 
     Document* parentDocument = ownerElement() ? ownerElement()->document() : 0;
-    if (parentDocument && m_frame->loader()->shouldTreatURLAsSrcdocDocument(url())) {
+    if (parentDocument && initializer.shouldTreatURLAsSrcdocDocument()) {
         m_isSrcdocDocument = true;
         setBaseURLOverride(parentDocument->baseURL());
     }
@@ -4351,10 +4235,7 @@
     // If we do not obtain a meaningful origin from the URL, then we try to
     // find one via the frame hierarchy.
 
-    Frame* ownerFrame = m_frame->tree()->parent();
-    if (!ownerFrame)
-        ownerFrame = m_frame->loader()->opener();
-
+    Frame* ownerFrame = initializer.ownerFrame();
     if (!ownerFrame) {
         didFailToInitializeSecurityOrigin();
         return;
@@ -4666,12 +4547,19 @@
     dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
 }
 
-void Document::addToTopLayer(Element* element)
+void Document::addToTopLayer(Element* element, const Element* before)
 {
     if (element->isInTopLayer())
         return;
+
     ASSERT(!m_topLayerElements.contains(element));
-    m_topLayerElements.append(element);
+    ASSERT(!before || m_topLayerElements.contains(before));
+    if (before) {
+        size_t beforePosition = m_topLayerElements.find(before);
+        m_topLayerElements.insert(beforePosition, element);
+    } else {
+        m_topLayerElements.append(element);
+    }
     element->setIsInTopLayer(true);
 }
 
@@ -4857,9 +4745,7 @@
     if (!shouldDisplaySeamlesslyWithParent())
         return 0;
 
-    HTMLFrameOwnerElement* ownerElement = this->ownerElement();
-    ASSERT(ownerElement->hasTagName(iframeTag));
-    return static_cast<HTMLIFrameElement*>(ownerElement);
+    return toHTMLIFrameElement(this->ownerElement());
 }
 
 bool Document::shouldDisplaySeamlesslyWithParent() const
@@ -4976,13 +4862,13 @@
     return 0;
 }
 
-void Document::updateHoverActiveState(const HitTestRequest& request, Element* innerElement)
+void Document::updateHoverActiveState(const HitTestRequest& request, Element* innerElement, const PlatformMouseEvent* event)
 {
     ASSERT(!request.readOnly());
 
     Element* innerElementInDocument = innerElement;
     while (innerElementInDocument && innerElementInDocument->document() != this) {
-        innerElementInDocument->document()->updateHoverActiveState(request, innerElementInDocument);
+        innerElementInDocument->document()->updateHoverActiveState(request, innerElementInDocument, event);
         innerElementInDocument = innerElementInDocument->document()->ownerElement();
     }
 
@@ -5070,15 +4956,52 @@
             nodesToAddToChain.append(curr->node());
     }
 
-    size_t removeCount = nodesToRemoveFromChain.size();
-    for (size_t i = 0; i < removeCount; ++i)
-        nodesToRemoveFromChain[i]->setHovered(false);
+    // mouseenter and mouseleave events do not bubble, so they are dispatched iff there is a capturing
+    // event handler on an ancestor or a normal event handler on the element itself. This special
+    // handling is necessary to avoid O(n^2) capturing event handler checks. We'll check the previously
+    // hovered node's ancestor tree for 'mouseleave' handlers here, then check the newly hovered node's
+    // ancestor tree for 'mouseenter' handlers after dispatching the 'mouseleave' events (as the handler
+    // for 'mouseleave' might set a capturing 'mouseenter' handler, odd as that might be).
+    bool ancestorHasCapturingMouseleaveListener = false;
+    if (event && newHoverNode != oldHoverNode.get()) {
+        for (Node* node = oldHoverNode.get(); node; node = node->parentOrShadowHostNode()) {
+            if (node->hasCapturingEventListeners(eventNames().mouseleaveEvent)) {
+                ancestorHasCapturingMouseleaveListener = true;
+                break;
+            }
+        }
+    }
 
+    size_t removeCount = nodesToRemoveFromChain.size();
+    for (size_t i = 0; i < removeCount; ++i) {
+        nodesToRemoveFromChain[i]->setHovered(false);
+        if (event && (ancestorHasCapturingMouseleaveListener || nodesToRemoveFromChain[i]->hasEventListeners(eventNames().mouseleaveEvent)))
+            nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, eventNames().mouseleaveEvent, 0, newHoverNode);
+    }
+
+    bool ancestorHasCapturingMouseenterListener = false;
+    if (event && newHoverNode != oldHoverNode.get()) {
+        for (Node* node = newHoverNode; node; node = node->parentOrShadowHostNode()) {
+            if (node->hasCapturingEventListeners(eventNames().mouseenterEvent)) {
+                ancestorHasCapturingMouseenterListener = true;
+                break;
+            }
+        }
+    }
+
+    bool sawCommonAncestor = false;
     size_t addCount = nodesToAddToChain.size();
     for (size_t i = 0; i < addCount; ++i) {
+        // Elements past the common ancestor do not change hover state, but might change active state.
+        if (ancestor && nodesToAddToChain[i] == ancestor->node())
+            sawCommonAncestor = true;
         if (allowActiveChanges)
             nodesToAddToChain[i]->setActive(true);
-        nodesToAddToChain[i]->setHovered(true);
+        if (!sawCommonAncestor) {
+            nodesToAddToChain[i]->setHovered(true);
+            if (event && (ancestorHasCapturingMouseenterListener || nodesToAddToChain[i]->hasEventListeners(eventNames().mouseenterEvent)))
+                nodesToAddToChain[i]->dispatchMouseEvent(*event, eventNames().mouseenterEvent, 0, oldHoverNode.get());
+        }
     }
 
     updateStyleIfNeeded();
@@ -5117,7 +5040,6 @@
     info.addMember(m_annotatedRegions, "annotatedRegions");
     info.addMember(m_cssCanvasElements, "cssCanvasElements");
     info.addMember(m_iconURLs, "iconURLs");
-    info.addMember(m_elementsByAccessKey, "elementsByAccessKey");
     info.addMember(m_eventQueue, "eventQueue");
     info.addMember(m_pendingTasks, "pendingTasks");
     info.addMember(m_prerenderer, "prerenderer");
@@ -5141,7 +5063,6 @@
     info.addMember(m_transformSource, "transformSource");
     info.addMember(m_transformSourceDocument, "transformSourceDocument");
     info.addMember(m_decoder, "decoder");
-    info.addMember(m_xpathEvaluator, "xpathEvaluator");
     info.addMember(m_svgExtensions, "svgExtensions");
     info.addMember(m_selectorQueryCache, "selectorQueryCache");
     info.addMember(m_renderer, "renderer");
@@ -5188,9 +5109,9 @@
         return const_cast<Document*>(document);
 
     if (isHTMLDocument())
-        m_templateDocument = HTMLDocument::create(0, blankURL());
+        m_templateDocument = HTMLDocument::create(DocumentInit(blankURL()));
     else
-        m_templateDocument = Document::create(0, blankURL());
+        m_templateDocument = Document::create(DocumentInit(blankURL()));
 
     m_templateDocument->setTemplateDocumentHost(this); // balanced in dtor.
 
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index e77c623..3299ae2 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -32,11 +32,13 @@
 #include "core/dom/ContainerNode.h"
 #include "core/dom/DOMTimeStamp.h"
 #include "core/dom/DocumentEventQueue.h"
+#include "core/dom/DocumentInit.h"
 #include "core/dom/DocumentTiming.h"
 #include "core/dom/IconURL.h"
 #include "core/dom/MutationObserver.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/ScriptExecutionContext.h"
+#include "core/dom/TextLinkColors.h"
 #include "core/dom/TreeScope.h"
 #include "core/dom/UserActionElementSet.h"
 #include "core/dom/ViewportArguments.h"
@@ -45,7 +47,6 @@
 #include "core/page/PageVisibilityState.h"
 #include "weborigin/ReferrerPolicy.h"
 #include "core/platform/Timer.h"
-#include "core/platform/graphics/Color.h"
 #include "core/platform/text/StringWithDirection.h"
 #include "core/rendering/HitTestRequest.h"
 #include "wtf/Deque.h"
@@ -69,7 +70,7 @@
 class CharacterData;
 class Comment;
 class ContextFeatures;
-class CustomElementRegistry;
+class CustomElementRegistrationContext;
 class DOMImplementation;
 class DOMNamedFlowCollection;
 class DOMSecurityPolicy;
@@ -102,7 +103,7 @@
 class HTMLElement;
 class HTMLFrameOwnerElement;
 class HTMLHeadElement;
-class HTMLImportsController;
+class HTMLImport;
 class HTMLIFrameElement;
 class HTMLMapElement;
 class HTMLNameCollection;
@@ -154,10 +155,6 @@
 class TreeWalker;
 class VisitedLinkState;
 class XMLHttpRequest;
-class XPathEvaluator;
-class XPathExpression;
-class XPathNSResolver;
-class XPathResult;
 
 struct AnnotatedRegionValue;
 
@@ -210,13 +207,13 @@
 
 class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext {
 public:
-    static PassRefPtr<Document> create(Frame* frame, const KURL& url)
+    static PassRefPtr<Document> create(const DocumentInit& initializer = DocumentInit())
     {
-        return adoptRef(new Document(frame, url));
+        return adoptRef(new Document(initializer));
     }
-    static PassRefPtr<Document> createXHTML(Frame* frame, const KURL& url)
+    static PassRefPtr<Document> createXHTML(const DocumentInit& initializer = DocumentInit())
     {
-        return adoptRef(new Document(frame, url, XHTMLDocumentClass));
+        return adoptRef(new Document(initializer, XHTMLDocumentClass));
     }
     virtual ~Document();
 
@@ -229,9 +226,6 @@
 
     virtual bool canContainRangeEndPoint() const { return true; }
 
-    Element* getElementByAccessKey(const String& key);
-    void invalidateAccessKeyMap();
-
     SelectorQueryCache* selectorQueryCache();
 
     // DOM methods & attributes for Document
@@ -254,6 +248,8 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
@@ -449,6 +445,12 @@
     // Called when one or more stylesheets in the document may have been added, removed, or changed.
     void styleResolverChanged(StyleResolverUpdateType, StyleResolverUpdateMode = FullStyleUpdate);
 
+    // FIXME: Switch all callers of styleResolverChanged to these or better ones and then make them
+    // do something smarter.
+    void removedStyleSheet(StyleSheet*, StyleResolverUpdateType type = DeferRecalcStyle) { styleResolverChanged(type); }
+    void addedStyleSheet(StyleSheet*, StyleResolverUpdateType type = DeferRecalcStyle) { styleResolverChanged(type); }
+    void modifiedStyleSheet(StyleSheet*, StyleResolverUpdateType type = DeferRecalcStyle) { styleResolverChanged(type); }
+
     void didAccessStyleResolver();
 
     void evaluateMediaQueryList();
@@ -612,19 +614,8 @@
     bool shouldScheduleLayout();
     bool isLayoutTimerActive();
     int elapsedTime() const;
-    
-    void setTextColor(const Color& color) { m_textColor = color; }
-    Color textColor() const { return m_textColor; }
 
-    const Color& linkColor() const { return m_linkColor; }
-    const Color& visitedLinkColor() const { return m_visitedLinkColor; }
-    const Color& activeLinkColor() const { return m_activeLinkColor; }
-    void setLinkColor(const Color& c) { m_linkColor = c; }
-    void setVisitedLinkColor(const Color& c) { m_visitedLinkColor = c; }
-    void setActiveLinkColor(const Color& c) { m_activeLinkColor = c; }
-    void resetLinkColor();
-    void resetVisitedLinkColor();
-    void resetActiveLinkColor();
+    TextLinkColors& textLinkColors() { return m_textLinkColors; }
     VisitedLinkState* visitedLinkState() const { return m_visitedLinkState.get(); }
 
     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const LayoutPoint&, const PlatformMouseEvent&);
@@ -637,13 +628,12 @@
     String selectedStylesheetSet() const;
     void setSelectedStylesheetSet(const String&);
 
-    bool setFocusedNode(PassRefPtr<Node>, FocusDirection = FocusDirectionNone);
+    bool setFocusedElement(PassRefPtr<Element>, FocusDirection = FocusDirectionNone);
     Node* focusedNode() const { return m_focusedNode.get(); }
     UserActionElementSet& userActionElements()  { return m_userActionElements; }
     const UserActionElementSet& userActionElements() const { return m_userActionElements; }
     void didRunCheckFocusedNodeTask() { m_didPostCheckFocusedNodeTask = false; }
-    void getFocusableNodes(Vector<RefPtr<Node> >&);
-    
+
     // The m_ignoreAutofocus flag specifies whether or not the document has been changed by the user enough 
     // for WebCore to ignore the autofocus attribute on any form controls
     bool ignoreAutofocus() const { return m_ignoreAutofocus; };
@@ -659,7 +649,7 @@
     void hoveredNodeDetached(Node*);
     void activeChainNodeDetached(Node*);
 
-    void updateHoverActiveState(const HitTestRequest&, Element*);
+    void updateHoverActiveState(const HitTestRequest&, Element*, const PlatformMouseEvent* = 0);
 
     // Updates for :target (CSS3 selector).
     void setCSSTarget(Element*);
@@ -739,9 +729,6 @@
 
     CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
 
-    int nodeAbsIndex(Node*);
-    Node* nodeWithAbsIndex(int absIndex);
-
     /**
      * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
      * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
@@ -868,18 +855,6 @@
 
     void setDocType(PassRefPtr<DocumentType>);
 
-    // XPathEvaluator methods
-    PassRefPtr<XPathExpression> createExpression(const String& expression,
-                                                 XPathNSResolver* resolver,
-                                                 ExceptionCode& ec);
-    PassRefPtr<XPathNSResolver> createNSResolver(Node *nodeResolver);
-    PassRefPtr<XPathResult> evaluate(const String& expression,
-                                     Node* contextNode,
-                                     XPathNSResolver* resolver,
-                                     unsigned short type,
-                                     XPathResult* result,
-                                     ExceptionCode& ec);
-
     enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
 
     bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
@@ -939,6 +914,7 @@
     SVGDocumentExtensions* accessSVGExtensions();
 
     void initSecurityContext();
+    void initSecurityContext(const DocumentInit&);
     void initContentSecurityPolicy();
 
     void updateURLForPushOrReplaceState(const KURL&);
@@ -1018,11 +994,10 @@
     PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionCode&);
     ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionCode&);
     ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&);
-    CustomElementRegistry* registry() const { return m_registry.get(); }
-    CustomElementRegistry* ensureCustomElementRegistry();
+    CustomElementRegistrationContext* registrationContext() { return m_registrationContext.get(); }
 
-    void setImports(PassRefPtr<HTMLImportsController>);
-    HTMLImportsController* imports() const { return m_imports.get(); }
+    void setImport(HTMLImport*);
+    HTMLImport* import() const { return m_import; }
     bool haveImportsLoaded() const;
     void didLoadAllImports();
 
@@ -1053,7 +1028,7 @@
 
     DocumentTimeline* timeline() { return m_timeline.get(); }
 
-    void addToTopLayer(Element*);
+    void addToTopLayer(Element*, const Element* before = 0);
     void removeFromTopLayer(Element*);
     const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
     Element* activeModalDialog() const { return !m_topLayerElements.isEmpty() ? m_topLayerElements.last().get() : 0; }
@@ -1073,18 +1048,18 @@
     DocumentLifecycleNotifier* lifecycleNotifier();
 
 protected:
-    Document(Frame*, const KURL&, DocumentClassFlags = DefaultDocumentClass);
+    Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
 
     virtual void didUpdateSecurityOrigin() OVERRIDE;
 
     void clearXMLVersion() { m_xmlVersion = String(); }
 
+    virtual void dispose() OVERRIDE;
+
 private:
     friend class Node;
     friend class IgnoreDestructiveWriteCountIncrementer;
 
-    virtual void dispose() OVERRIDE;
-
     void detachParser();
 
     typedef void (*ArgumentsCallback)(const String& keyString, const String& valueString, Document*, void* data);
@@ -1097,7 +1072,7 @@
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
     virtual bool childTypeAllowed(NodeType) const;
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
 
     virtual void refScriptExecutionContext() { ref(); }
     virtual void derefScriptExecutionContext() { deref(); }
@@ -1114,8 +1089,6 @@
     void updateFocusAppearanceTimerFired(Timer<Document>*);
     void updateBaseURL();
 
-    void buildAccessKeyMap(TreeScope* root);
-
     void createStyleResolver();
 
     void executeScriptsWaitingForResourcesIfNeeded();
@@ -1129,7 +1102,7 @@
     void pendingTasksTimerFired(Timer<Document>*);
 
     static void didReceiveTask(void*);
-    
+
     template <typename CharacterType>
     void displayBufferModifiedByEncodingInternal(CharacterType*, unsigned) const;
 
@@ -1146,8 +1119,13 @@
     void addMutationEventListenerTypeIfEnabled(ListenerType);
 
     void didAssociateFormControlsTimerFired(Timer<Document>*);
-
     void styleResolverThrowawayTimerFired(Timer<Document>*);
+
+    void processHttpEquivDefaultStyle(const String& content);
+    void processHttpEquivRefresh(const String& content);
+    void processHttpEquivSetCookie(const String& content);
+    void processHttpEquivXFrameOptions(const String& content);
+
     Timer<Document> m_styleResolverThrowawayTimer;
     double m_lastStyleResolverAccessTime;
 
@@ -1166,6 +1144,7 @@
 
     Frame* m_frame;
     DOMWindow* m_domWindow;
+    HTMLImport* m_import;
 
     RefPtr<CachedResourceLoader> m_cachedResourceLoader;
     RefPtr<DocumentParser> m_parser;
@@ -1204,8 +1183,6 @@
     CompatibilityMode m_compatibilityMode;
     bool m_compatibilityModeLocked; // This is cheaper than making setCompatibilityMode virtual.
 
-    Color m_textColor;
-
     bool m_didPostCheckFocusedNodeTask;
     RefPtr<Node> m_focusedNode;
     RefPtr<Node> m_hoverNode;
@@ -1228,9 +1205,7 @@
 
     OwnPtr<FormController> m_formController;
 
-    Color m_linkColor;
-    Color m_visitedLinkColor;
-    Color m_activeLinkColor;
+    TextLinkColors m_textLinkColors;
     OwnPtr<VisitedLinkState> m_visitedLinkState;
 
     bool m_loadingSheet;
@@ -1298,8 +1273,6 @@
     HashSet<LiveNodeListBase*> m_listsInvalidatedAtDocument;
     unsigned m_nodeListCounts[numNodeListInvalidationTypes];
 
-    RefPtr<XPathEvaluator> m_xpathEvaluator;
-
     OwnPtr<SVGDocumentExtensions> m_svgExtensions;
 
     Vector<AnnotatedRegionValue> m_annotatedRegions;
@@ -1310,9 +1283,6 @@
 
     Vector<IconURL> m_iconURLs;
 
-    HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
-    bool m_accessKeyMapValid;
-
     OwnPtr<SelectorQueryCache> m_selectorQueryCache;
 
     bool m_useSecureKeyboardEntryWhenActive;
@@ -1363,8 +1333,7 @@
 
     OwnPtr<TextAutosizer> m_textAutosizer;
 
-    RefPtr<CustomElementRegistry> m_registry;
-    RefPtr<HTMLImportsController> m_imports;
+    RefPtr<CustomElementRegistrationContext> m_registrationContext;
 
     bool m_scheduledTasksAreSuspended;
     
diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl
index 7afd390..effc829 100644
--- a/Source/core/dom/Document.idl
+++ b/Source/core/dom/Document.idl
@@ -97,16 +97,6 @@
      CSSStyleDeclaration getOverrideStyle([Default=Undefined] optional Element element,
                                                         [Default=Undefined] optional DOMString pseudoElement);
 
-    // DOM Level 3 XPath (XPathEvaluator interface)
-     [RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
-                                                    [Default=Undefined] optional XPathNSResolver resolver);
-    XPathNSResolver    createNSResolver(Node nodeResolver);
-    [Custom, RaisesException] XPathResult evaluate([Default=Undefined] optional DOMString expression,
-                                                  [Default=Undefined] optional Node contextNode,
-                                                  [Default=Undefined] optional XPathNSResolver resolver,
-                                                  [Default=Undefined] optional unsigned short type,
-                                                  [Default=Undefined] optional XPathResult inResult);
-
     // Common extensions
     [DeliverCustomElementCallbacks]
     boolean            execCommand([Default=Undefined] optional DOMString command,
@@ -203,6 +193,8 @@
     [NotEnumerable] attribute EventListener onkeyup;
     [NotEnumerable] attribute EventListener onload;
     [NotEnumerable] attribute EventListener onmousedown;
+    [NotEnumerable] attribute EventListener onmouseenter;
+    [NotEnumerable] attribute EventListener onmouseleave;
     [NotEnumerable] attribute EventListener onmousemove;
     [NotEnumerable] attribute EventListener onmouseout;
     [NotEnumerable] attribute EventListener onmouseover;
diff --git a/Source/core/dom/DocumentFragment.h b/Source/core/dom/DocumentFragment.h
index 08ede54..1b763a1 100644
--- a/Source/core/dom/DocumentFragment.h
+++ b/Source/core/dom/DocumentFragment.h
@@ -48,7 +48,7 @@
 
 private:
     virtual NodeType nodeType() const;
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
     virtual bool childTypeAllowed(NodeType) const;
 };
 
diff --git a/Source/core/dom/DocumentInit.cpp b/Source/core/dom/DocumentInit.cpp
new file mode 100644
index 0000000..adf48c2
--- /dev/null
+++ b/Source/core/dom/DocumentInit.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/DocumentInit.h"
+
+#include "core/html/HTMLImportsController.h"
+#include "core/page/Frame.h"
+
+namespace WebCore {
+
+bool DocumentInit::shouldSetURL() const
+{
+    return (m_frame && m_frame->ownerElement()) || !m_url.isEmpty();
+}
+
+bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
+{
+    return m_frame->loader()->shouldTreatURLAsSrcdocDocument(m_url);
+}
+
+SandboxFlags DocumentInit::sandboxFlags() const
+{
+    return m_frame->loader()->effectiveSandboxFlags();
+}
+
+Settings* DocumentInit::settings() const
+{
+    return m_frame->settings();
+}
+
+Frame* DocumentInit::ownerFrame() const
+{
+    Frame* ownerFrame = m_frame->tree()->parent();
+    if (!ownerFrame)
+        ownerFrame = m_frame->loader()->opener();
+    return ownerFrame;
+}
+
+} // namespace WebCore
+
diff --git a/Source/core/dom/DocumentInit.h b/Source/core/dom/DocumentInit.h
new file mode 100644
index 0000000..893662f
--- /dev/null
+++ b/Source/core/dom/DocumentInit.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DocumentInit_h
+#define DocumentInit_h
+
+#include "core/dom/SecurityContext.h"
+#include "weborigin/KURL.h"
+
+namespace WebCore {
+
+class Frame;
+class HTMLImport;
+class Settings;
+
+class DocumentInit {
+public:
+    explicit DocumentInit(const KURL& url = KURL(), Frame* frame = 0, HTMLImport* import = 0)
+        : m_url(url)
+        , m_frame(frame)
+        , m_import(import)
+    { }
+
+    const KURL& url() const { return m_url; }
+    Frame* frame() const { return m_frame; }
+    HTMLImport* import() const { return m_import; }
+
+    bool shouldTreatURLAsSrcdocDocument() const;
+    bool shouldSetURL() const;
+    SandboxFlags sandboxFlags() const;
+
+    Frame* ownerFrame() const;
+    Settings* settings() const;
+
+private:
+    KURL m_url;
+    Frame* m_frame;
+    HTMLImport* m_import;
+};
+
+} // namespace WebCore
+
+#endif // DocumentInit_h
diff --git a/Source/core/dom/DocumentMarker.h b/Source/core/dom/DocumentMarker.h
index e8e6d9f..b6072b9 100644
--- a/Source/core/dom/DocumentMarker.h
+++ b/Source/core/dom/DocumentMarker.h
@@ -23,10 +23,10 @@
 #ifndef DocumentMarker_h
 #define DocumentMarker_h
 
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentMarkerController.h b/Source/core/dom/DocumentMarkerController.h
index b73bcd1..59fca3e 100644
--- a/Source/core/dom/DocumentMarkerController.h
+++ b/Source/core/dom/DocumentMarkerController.h
@@ -29,8 +29,8 @@
 
 #include "core/dom/DocumentMarker.h"
 #include "core/platform/graphics/IntRect.h"
-#include <wtf/HashMap.h>
-#include <wtf/Vector.h>
+#include "wtf/HashMap.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentOrderedMap.cpp b/Source/core/dom/DocumentOrderedMap.cpp
index 5c41c8d..980917f 100644
--- a/Source/core/dom/DocumentOrderedMap.cpp
+++ b/Source/core/dom/DocumentOrderedMap.cpp
@@ -36,9 +36,10 @@
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/TreeScope.h"
 #include "core/dom/WebCoreMemoryInstrumentation.h"
+#include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLMapElement.h"
-#include <wtf/MemoryInstrumentationHashCountedSet.h>
-#include <wtf/MemoryInstrumentationHashMap.h>
+#include "wtf/MemoryInstrumentationHashCountedSet.h"
+#include "wtf/MemoryInstrumentationHashMap.h"
 
 namespace WebCore {
 
@@ -51,17 +52,17 @@
 
 inline bool keyMatchesMapName(AtomicStringImpl* key, Element* element)
 {
-    return element->hasTagName(mapTag) && static_cast<HTMLMapElement*>(element)->getName().impl() == key;
+    return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().impl() == key;
 }
 
 inline bool keyMatchesLowercasedMapName(AtomicStringImpl* key, Element* element)
 {
-    return element->hasTagName(mapTag) && static_cast<HTMLMapElement*>(element)->getName().lower().impl() == key;
+    return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().lower().impl() == key;
 }
 
 inline bool keyMatchesLabelForAttribute(AtomicStringImpl* key, Element* element)
 {
-    return element->hasTagName(labelTag) && element->getAttribute(forAttr).impl() == key;
+    return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl() == key;
 }
 
 void DocumentOrderedMap::clear()
diff --git a/Source/core/dom/DocumentOrderedMap.h b/Source/core/dom/DocumentOrderedMap.h
index f7deb3b..78ccd90 100644
--- a/Source/core/dom/DocumentOrderedMap.h
+++ b/Source/core/dom/DocumentOrderedMap.h
@@ -31,9 +31,9 @@
 #ifndef DocumentOrderedMap_h
 #define DocumentOrderedMap_h
 
-#include <wtf/HashCountedSet.h>
-#include <wtf/HashMap.h>
-#include <wtf/text/AtomicStringImpl.h>
+#include "wtf/HashCountedSet.h"
+#include "wtf/HashMap.h"
+#include "wtf/text/AtomicStringImpl.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentParser.cpp b/Source/core/dom/DocumentParser.cpp
index 9a834eb..dcafb09 100644
--- a/Source/core/dom/DocumentParser.cpp
+++ b/Source/core/dom/DocumentParser.cpp
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "core/dom/DocumentParser.h"
 
-#include <wtf/Assertions.h>
+#include "wtf/Assertions.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentParser.h b/Source/core/dom/DocumentParser.h
index 98a473b..587fa2f 100644
--- a/Source/core/dom/DocumentParser.h
+++ b/Source/core/dom/DocumentParser.h
@@ -24,8 +24,8 @@
 #ifndef DocumentParser_h
 #define DocumentParser_h
 
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentSharedObjectPool.h b/Source/core/dom/DocumentSharedObjectPool.h
index a3b24d7..2f827db 100644
--- a/Source/core/dom/DocumentSharedObjectPool.h
+++ b/Source/core/dom/DocumentSharedObjectPool.h
@@ -27,9 +27,9 @@
 #ifndef DocumentSharedObjectPool_h
 #define DocumentSharedObjectPool_h
 
-#include <wtf/HashMap.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/text/StringHash.h>
+#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/StringHash.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index 35b41b4..8bb4caf 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -46,8 +46,8 @@
 #include "core/page/Settings.h"
 #include "core/page/UserContentURLPattern.h"
 #include "core/svg/SVGStyleElement.h"
-#include <wtf/MemoryInstrumentationListHashSet.h>
-#include <wtf/MemoryInstrumentationVector.h>
+#include "wtf/MemoryInstrumentationListHashSet.h"
+#include "wtf/MemoryInstrumentationVector.h"
 
 namespace WebCore {
 
@@ -57,7 +57,6 @@
     : m_document(document)
     , m_pendingStylesheets(0)
     , m_injectedStyleSheetCacheValid(false)
-    , m_hadActiveLoadingStylesheet(false)
     , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
     , m_usesSiblingRules(false)
     , m_usesSiblingRulesOverride(false)
@@ -66,6 +65,7 @@
     , m_usesBeforeAfterRules(false)
     , m_usesBeforeAfterRulesOverride(false)
     , m_usesRemUnits(false)
+    , m_collectionForDocument(document)
 {
 }
 
@@ -83,6 +83,16 @@
         m_authorStyleSheets[i]->clearOwnerNode();
 }
 
+const Vector<RefPtr<StyleSheet> >& DocumentStyleSheetCollection::styleSheetsForStyleSheetList()
+{
+    return m_collectionForDocument.styleSheetsForStyleSheetList();
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::activeAuthorStyleSheets() const
+{
+    return m_collectionForDocument.activeAuthorStyleSheets();
+}
+
 void DocumentStyleSheetCollection::combineCSSFeatureFlags()
 {
     // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
@@ -123,16 +133,18 @@
 void DocumentStyleSheetCollection::clearPageUserSheet()
 {
     if (m_pageUserSheet) {
+        RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
         m_pageUserSheet = 0;
-        m_document->styleResolverChanged(DeferRecalcStyle);
+        m_document->removedStyleSheet(removedSheet.get());
     }
 }
 
 void DocumentStyleSheetCollection::updatePageUserSheet()
 {
     clearPageUserSheet();
-    if (pageUserSheet())
-        m_document->styleResolverChanged(RecalcStyleImmediately);
+    // FIXME: Why is this immediately and not defer?
+    if (StyleSheet* addedSheet = pageUserSheet())
+        m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
 }
 
 const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::injectedUserStyleSheets() const
@@ -181,6 +193,8 @@
 void DocumentStyleSheetCollection::invalidateInjectedStyleSheetCache()
 {
     m_injectedStyleSheetCacheValid = false;
+    // FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
+    // and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
     m_document->styleResolverChanged(DeferRecalcStyle);
 }
 
@@ -188,14 +202,14 @@
 {
     ASSERT(!authorSheet->isUserStyleSheet());
     m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
-    m_document->styleResolverChanged(RecalcStyleImmediately);
+    m_document->addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
 }
 
 void DocumentStyleSheetCollection::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
 {
     ASSERT(userSheet->isUserStyleSheet());
     m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
-    m_document->styleResolverChanged(RecalcStyleImmediately);
+    m_document->addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
 }
 
 // This method is called whenever a top-level stylesheet has finished loading.
@@ -205,11 +219,6 @@
     ASSERT(m_pendingStylesheets > 0);
 
     m_pendingStylesheets--;
-    
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
-    if (!ownerElement())
-        printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
-#endif
 
     if (m_pendingStylesheets)
         return;
@@ -218,174 +227,20 @@
         m_document->setNeedsNotifyRemoveAllPendingStylesheet();
         return;
     }
-    
+
+    // FIXME: We can't call addedStyleSheet or removedStyleSheet here because we don't know
+    // what's new. We should track that to tell the style system what changed.
     m_document->didRemoveAllPendingStylesheet();
 }
 
 void DocumentStyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
 {
-    if (!node->inDocument())
-        return;
-
-    // Until the <body> exists, we have no choice but to compare document positions,
-    // since styles outside of the body and head continue to be shunted into the head
-    // (and thus can shift to end up before dynamically added DOM content that is also
-    // outside the body).
-    if (createdByParser && m_document->body()) {
-        m_styleSheetCandidateNodes.parserAdd(node);
-        return;
-    }
-
-    m_styleSheetCandidateNodes.add(node);
+    m_collectionForDocument.addStyleSheetCandidateNode(node, createdByParser);
 }
 
 void DocumentStyleSheetCollection::removeStyleSheetCandidateNode(Node* node)
 {
-    m_styleSheetCandidateNodes.remove(node);
-}
-
-void DocumentStyleSheetCollection::collectStyleSheets(Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
-{
-    if (m_document->settings() && !m_document->settings()->authorAndUserStylesEnabled())
-        return;
-
-    DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
-    DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
-    for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
-        Node* n = *it;
-        StyleSheet* sheet = 0;
-        CSSStyleSheet* activeSheet = 0;
-        if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
-            // Processing instruction (XML documents only).
-            // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
-            ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
-            // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
-            if (pi->isXSL() && !m_document->transformSourceDocument()) {
-                // Don't apply XSL transforms until loading is finished.
-                if (!m_document->parsing())
-                    m_document->applyXSLTransform(pi);
-                return;
-            }
-            sheet = pi->sheet();
-            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
-                activeSheet = static_cast<CSSStyleSheet*>(sheet);
-        } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
-            Element* e = toElement(n);
-            AtomicString title = e->getAttribute(titleAttr);
-            bool enabledViaScript = false;
-            if (e->hasLocalName(linkTag)) {
-                // <LINK> element
-                HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
-                enabledViaScript = linkElement->isEnabledViaScript();
-                if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
-                    // it is loading but we should still decide which style sheet set to use
-                    if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSetName.isEmpty()) {
-                        const AtomicString& rel = e->getAttribute(relAttr);
-                        if (!rel.contains("alternate")) {
-                            m_preferredStylesheetSetName = title;
-                            m_selectedStylesheetSetName = title;
-                        }
-                    }
-
-                    continue;
-                }
-                sheet = linkElement->sheet();
-                if (!sheet)
-                    title = nullAtom;
-            } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
-                sheet = static_cast<SVGStyleElement*>(n)->sheet();
-            } else {
-                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
-            }
-
-            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
-                activeSheet = static_cast<CSSStyleSheet*>(sheet);
-
-            // Check to see if this sheet belongs to a styleset
-            // (thus making it PREFERRED or ALTERNATE rather than
-            // PERSISTENT).
-            AtomicString rel = e->getAttribute(relAttr);
-            if (!enabledViaScript && sheet && !title.isEmpty()) {
-                // Yes, we have a title.
-                if (m_preferredStylesheetSetName.isEmpty()) {
-                    // No preferred set has been established. If
-                    // we are NOT an alternate sheet, then establish
-                    // us as the preferred set. Otherwise, just ignore
-                    // this sheet.
-                    if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
-                        m_preferredStylesheetSetName = m_selectedStylesheetSetName = title;
-                }
-                if (title != m_preferredStylesheetSetName)
-                    activeSheet = 0;
-            }
-
-            if (rel.contains("alternate") && title.isEmpty())
-                activeSheet = 0;
-        }
-        if (sheet)
-            styleSheets.append(sheet);
-        if (activeSheet)
-            activeSheets.append(activeSheet);
-    }
-}
-
-void DocumentStyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, StyleResolverUpdateType& styleResolverUpdateType, bool& requiresFullStyleRecalc)
-{
-    styleResolverUpdateType = Reconstruct;
-    requiresFullStyleRecalc = true;
-
-    // Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
-    bool hasActiveLoadingStylesheet = false;
-    unsigned newStylesheetCount = newStylesheets.size();
-    for (unsigned i = 0; i < newStylesheetCount; ++i) {
-        if (newStylesheets[i]->isLoading())
-            hasActiveLoadingStylesheet = true;
-    }
-    if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
-        m_hadActiveLoadingStylesheet = false;
-        return;
-    }
-    m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
-
-    if (updateMode != AnalyzedStyleUpdate)
-        return;
-    if (!m_document->styleResolverIfExists())
-        return;
-
-    // Find out which stylesheets are new.
-    unsigned oldStylesheetCount = m_activeAuthorStyleSheets.size();
-    if (newStylesheetCount < oldStylesheetCount)
-        return;
-    Vector<StyleSheetContents*> addedSheets;
-    unsigned newIndex = 0;
-    for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
-        if (newIndex >= newStylesheetCount)
-            return;
-        while (m_activeAuthorStyleSheets[oldIndex] != newStylesheets[newIndex]) {
-            addedSheets.append(newStylesheets[newIndex]->contents());
-            ++newIndex;
-            if (newIndex == newStylesheetCount)
-                return;
-        }
-        ++newIndex;
-    }
-    bool hasInsertions = !addedSheets.isEmpty();
-    while (newIndex < newStylesheetCount) {
-        addedSheets.append(newStylesheets[newIndex]->contents());
-        ++newIndex;
-    }
-    // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
-    // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
-    styleResolverUpdateType = hasInsertions ? Reset : Additive;
-
-    // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
-    if (!m_document->body() || m_document->hasNodesWithPlaceholderStyle())
-        return;
-    StyleInvalidationAnalysis invalidationAnalysis(addedSheets);
-    if (invalidationAnalysis.dirtiesAllStyle())
-        return;
-    invalidationAnalysis.invalidateStyle(m_document);
-    requiresFullStyleRecalc = false;
+    m_collectionForDocument.removeStyleSheetCandidateNode(node);
 }
 
 static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
@@ -397,14 +252,6 @@
     return false;
 }
 
-static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
-{
-    HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
-    if (!seamlessParentIFrame)
-        return;
-    sheets.append(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
-}
-
 bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
 {
     if (m_document->inStyleRecalc()) {
@@ -419,37 +266,15 @@
     if (!m_document->renderer() || !m_document->attached())
         return false;
 
-    Vector<RefPtr<StyleSheet> > styleSheets;
-    Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
-    activeCSSStyleSheets.append(injectedAuthorStyleSheets());
-    activeCSSStyleSheets.append(documentAuthorStyleSheets());
-    collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, m_document);
-    collectStyleSheets(styleSheets, activeCSSStyleSheets);
-
-    StyleResolverUpdateType styleResolverUpdateType;
-    bool requiresFullStyleRecalc;
-    analyzeStyleSheetChange(updateMode, activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
-
-    if (styleResolverUpdateType == Reconstruct)
-        m_document->clearStyleResolver();
-    else {
-        StyleResolver* styleResolver = m_document->styleResolver();
-        if (styleResolverUpdateType == Reset) {
-            styleResolver->resetAuthorStyle();
-            styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
-        } else {
-            ASSERT(styleResolverUpdateType == Additive);
-            styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
-        }
-        resetCSSFeatureFlags();
-    }
-    m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
-    InspectorInstrumentation::activeStyleSheetsUpdated(m_document, styleSheets);
-    m_styleSheetsForStyleSheetList.swap(styleSheets);
-
-    m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
+    StyleSheetCollection::StyleResolverUpdateType styleResolverUpdateType;
+    bool requiresFullStyleRecalc = m_collectionForDocument.updateActiveStyleSheets(this, updateMode, styleResolverUpdateType);
     m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
 
+    if (styleResolverUpdateType != StyleSheetCollection::Reconstruct)
+        resetCSSFeatureFlags();
+
+    InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_collectionForDocument.styleSheetsForStyleSheetList());
+    m_usesRemUnits = styleSheetsUseRemUnits(m_collectionForDocument.activeAuthorStyleSheets());
     m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
 
     return requiresFullStyleRecalc;
@@ -463,9 +288,7 @@
     info.addMember(m_injectedAuthorStyleSheets, "injectedAuthorStyleSheets");
     info.addMember(m_userStyleSheets, "userStyleSheets");
     info.addMember(m_authorStyleSheets, "authorStyleSheets");
-    info.addMember(m_activeAuthorStyleSheets, "activeAuthorStyleSheets");
-    info.addMember(m_styleSheetsForStyleSheetList, "styleSheetsForStyleSheetList");
-    info.addMember(m_styleSheetCandidateNodes, "styleSheetCandidateNodes");
+    info.addMember(m_collectionForDocument, "styleSheetCollectionForDocument");
     info.addMember(m_preferredStylesheetSetName, "preferredStylesheetSetName");
     info.addMember(m_selectedStylesheetSetName, "selectedStylesheetSetName");
     info.addMember(m_document, "document");
diff --git a/Source/core/dom/DocumentStyleSheetCollection.h b/Source/core/dom/DocumentStyleSheetCollection.h
index 1a67e28..7b4cc03 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/Source/core/dom/DocumentStyleSheetCollection.h
@@ -30,6 +30,7 @@
 
 #include "core/dom/Document.h"
 #include "core/dom/DocumentOrderedList.h"
+#include "core/dom/StyleSheetCollection.h"
 #include "wtf/FastAllocBase.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/RefPtr.h"
@@ -51,9 +52,8 @@
 
     ~DocumentStyleSheetCollection();
 
-    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
-
-    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList();
+    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
 
     CSSStyleSheet* pageUserSheet();
     const Vector<RefPtr<CSSStyleSheet> >& documentUserStyleSheets() const { return m_userStyleSheets; }
@@ -108,19 +108,8 @@
 private:
     DocumentStyleSheetCollection(Document*);
 
-    void collectStyleSheets(Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
-    enum StyleResolverUpdateType {
-        Reconstruct,
-        Reset,
-        Additive
-    };
-    void analyzeStyleSheetChange(StyleResolverUpdateMode, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, StyleResolverUpdateType&, bool& requiresFullStyleRecalc);
-
     Document* m_document;
 
-    Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
-    Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
-
     // Track the number of currently loading top-level stylesheets needed for rendering.
     // Sheets loaded using the @import directive are not included in this count.
     // We use this count of pending sheets to detect when we can begin attaching
@@ -139,7 +128,7 @@
     bool m_hadActiveLoadingStylesheet;
     bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
 
-    DocumentOrderedList m_styleSheetCandidateNodes;
+    StyleSheetCollection m_collectionForDocument;
 
     String m_preferredStylesheetSetName;
     String m_selectedStylesheetSetName;
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index ab2f94d..ab7a395 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -42,7 +42,7 @@
 #include "core/dom/Attribute.h"
 #include "core/dom/ClientRect.h"
 #include "core/dom/ClientRectList.h"
-#include "core/dom/CustomElementRegistry.h"
+#include "core/dom/CustomElementRegistrationContext.h"
 #include "core/dom/DatasetDOMStringMap.h"
 #include "core/dom/Document.h"
 #include "core/dom/DocumentSharedObjectPool.h"
@@ -205,12 +205,12 @@
         ElementRareData* data = elementRareData();
         data->setPseudoElement(BEFORE, 0);
         data->setPseudoElement(AFTER, 0);
+        data->setPseudoElement(BACKDROP, 0);
         data->clearShadow();
     }
 
-    if (isCustomElement() && document() && document()->registry()) {
-        document()->registry()->customElementWasDestroyed(this);
-    }
+    if (isCustomElement() && document() && document()->registrationContext())
+        document()->registrationContext()->customElementIsBeingDestroyed(this);
 
     if (hasSyntheticAttrChildNodes())
         detachAllAttrNodesFromElement();
@@ -266,7 +266,7 @@
     }
 
     // FIXME: These asserts should be in Node::isFocusable, but there are some
-    // callsites like Document::setFocusedNode that would currently fail on
+    // callsites like Document::setFocusedElement that would currently fail on
     // them. See crbug.com/251163
     if (renderer()) {
         ASSERT(!renderer()->needsLayout());
@@ -823,7 +823,7 @@
 void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionCode& ec)
 {
     if (!Document::isValidName(localName)) {
-        ec = INVALID_CHARACTER_ERR;
+        ec = InvalidCharacterError;
         return;
     }
 
@@ -907,14 +907,14 @@
     document()->incDOMTreeVersion();
 
     StyleResolver* styleResolver = document()->styleResolverIfExists();
-    bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
+    bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
     if (isStyledElement() && name == styleAttr) {
         styleAttributeChanged(newValue, reason);
     } else if (isStyledElement() && isPresentationAttribute(name)) {
         elementData()->m_presentationAttributeStyleIsDirty = true;
-        setNeedsStyleRecalc(InlineStyleChange);
+        setNeedsStyleRecalc(LocalStyleChange);
     }
 
     if (isIdAttributeName(name)) {
@@ -946,9 +946,8 @@
 
 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
 {
-    if (RuntimeEnabledFeatures::customDOMElementsEnabled() && name == isAttr) {
-        document()->ensureCustomElementRegistry()->didGiveTypeExtension(this, newValue);
-    }
+    if (name == isAttr)
+        document()->registrationContext()->didGiveTypeExtension(this, newValue);
     attributeChanged(name, newValue, reason);
 }
 
@@ -1023,7 +1022,7 @@
 void Element::classAttributeChanged(const AtomicString& newClassString)
 {
     StyleResolver* styleResolver = document()->styleResolverIfExists();
-    bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
+    bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < SubtreeStyleChange;
     bool shouldInvalidateStyle = false;
 
     if (classStringHasClassName(newClassString)) {
@@ -1266,6 +1265,9 @@
     if (scope != treeScope())
         return InsertionDone;
 
+    if (isUpgradedCustomElement())
+        document()->registrationContext()->customElementDidEnterDocument(this);
+
     const AtomicString& idValue = getIdAttribute();
     if (!idValue.isNull())
         updateId(scope, nullAtom, idValue);
@@ -1292,7 +1294,10 @@
     if (Element* after = pseudoElement(AFTER))
         after->removedFrom(insertionPoint);
 
+    if (Element* backdrop = pseudoElement(BACKDROP))
+        backdrop->removedFrom(insertionPoint);
     document()->removeFromTopLayer(this);
+
     if (containsFullScreenElement())
         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
 
@@ -1318,8 +1323,13 @@
     }
 
     ContainerNode::removedFrom(insertionPoint);
-    if (wasInDocument && hasPendingResources())
-        document()->accessSVGExtensions()->removeElementFromPendingResources(this);
+    if (wasInDocument) {
+        if (hasPendingResources())
+            document()->accessSVGExtensions()->removeElementFromPendingResources(this);
+
+        if (isUpgradedCustomElement() && document()->registrationContext())
+            document()->registrationContext()->customElementDidLeaveDocument(this);
+    }
 }
 
 void Element::createRendererIfNeeded(const AttachContext& context)
@@ -1350,6 +1360,7 @@
     ContainerNode::attach(context);
 
     createPseudoElementIfNeeded(AFTER);
+    createPseudoElementIfNeeded(BACKDROP);
 
     if (hasRareData()) {
         ElementRareData* data = elementRareData();
@@ -1382,6 +1393,7 @@
         ElementRareData* data = elementRareData();
         data->setPseudoElement(BEFORE, 0);
         data->setPseudoElement(AFTER, 0);
+        data->setPseudoElement(BACKDROP, 0);
         data->setIsInCanvasSubtree(false);
         data->resetComputedStyle();
         data->resetDynamicRestyleObservations();
@@ -1445,7 +1457,7 @@
     return document()->styleResolver()->styleForElement(this);
 }
 
-void Element::recalcStyle(StyleChange change)
+bool Element::recalcStyle(StyleChange change)
 {
     ASSERT(document()->inStyleRecalc());
 
@@ -1487,13 +1499,13 @@
 
             if (hasCustomStyleCallbacks())
                 didRecalcStyle(change);
-            return;
+            return true;
         }
 
         InspectorInstrumentation::didRecalculateStyleForElement(this);
 
         if (RenderObject* renderer = this->renderer()) {
-            if (localChange != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || needsLayerUpdate())
+            if (localChange != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles())
                 renderer->setAnimatableStyle(newStyle.get());
             else if (needsStyleRecalc()) {
                 // Although no change occurred, we use the new style so that the cousin style sharing code won't get
@@ -1510,7 +1522,7 @@
             change = Force;
         }
 
-        if (styleChangeType() == FullStyleChange)
+        if (styleChangeType() == SubtreeStyleChange)
             change = Force;
         else if (change != Force)
             change = localChange;
@@ -1533,23 +1545,35 @@
     // without doing way too much re-resolution.
     bool forceCheckOfNextElementSibling = false;
     bool forceCheckOfAnyElementSibling = false;
-    for (Node *n = firstChild(); n; n = n->nextSibling()) {
-        if (n->isTextNode()) {
-            toText(n)->recalcTextStyle(change);
-            continue;
+    bool forceReattachOfAnyWhitespaceSibling = false;
+    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+        bool didReattach = false;
+
+        if (child->renderer())
+            forceReattachOfAnyWhitespaceSibling = false;
+
+        if (child->isTextNode()) {
+            if (forceReattachOfAnyWhitespaceSibling && toText(child)->containsOnlyWhitespace())
+                child->reattach();
+            else
+                didReattach = toText(child)->recalcTextStyle(change);
+        } else if (child->isElementNode()) {
+            Element* element = toElement(child);
+
+            if (forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)
+                element->setNeedsStyleRecalc();
+
+            bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == SubtreeStyleChange;
+            forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
+            forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+
+            if (shouldRecalcStyle(change, element)) {
+                parentPusher.push();
+                didReattach = element->recalcStyle(change);
+            }
         }
-        if (!n->isElementNode())
-            continue;
-        Element* element = toElement(n);
-        bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
-        if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
-            element->setNeedsStyleRecalc();
-        if (shouldRecalcStyle(change, element)) {
-            parentPusher.push();
-            element->recalcStyle(change);
-        }
-        forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
-        forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+
+        forceReattachOfAnyWhitespaceSibling = didReattach || forceReattachOfAnyWhitespaceSibling;
     }
 
     if (shouldRecalcStyle(change, this))
@@ -1560,6 +1584,7 @@
 
     if (hasCustomStyleCallbacks())
         didRecalcStyle(change);
+    return false;
 }
 
 ElementShadow* Element::shadow() const
@@ -1591,7 +1616,7 @@
     // subtrees won't work well in that element. Until they are fixed, we disable
     // adding author shadow root for them.
     if (!areAuthorShadowsAllowed()) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return 0;
     }
     return ensureShadow()->addShadowRoot(this, ShadowRoot::AuthorShadowRoot);
@@ -1810,7 +1835,7 @@
 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
 {
     if (!attrNode) {
-        ec = TYPE_MISMATCH_ERR;
+        ec = TypeMismatchError;
         return 0;
     }
 
@@ -1818,10 +1843,10 @@
     if (oldAttrNode.get() == attrNode)
         return attrNode; // This Attr is already attached to the element.
 
-    // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
+    // InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
     if (attrNode->ownerElement()) {
-        ec = INUSE_ATTRIBUTE_ERR;
+        ec = InUseAttributeError;
         return 0;
     }
 
@@ -1853,11 +1878,11 @@
 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
 {
     if (!attr) {
-        ec = TYPE_MISMATCH_ERR;
+        ec = TypeMismatchError;
         return 0;
     }
     if (attr->ownerElement() != this) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
 
@@ -1867,7 +1892,7 @@
 
     size_t index = elementData()->getAttrIndex(attr);
     if (index == notFound) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
 
@@ -1886,7 +1911,7 @@
     QualifiedName qName(prefix, localName, namespaceURI);
 
     if (!Document::hasValidNamespaceForAttributes(qName)) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return false;
     }
 
@@ -2022,7 +2047,7 @@
         // If a focus event handler changes the focus to a different node it
         // does not make sense to continue and update appearence.
         protect = this;
-        if (!page->focusController()->setFocusedNode(this, doc->frame(), direction))
+        if (!page->focusController()->setFocusedElement(this, doc->frame(), direction))
             return;
     }
 
@@ -2063,12 +2088,12 @@
 void Element::blur()
 {
     cancelFocusAppearanceUpdate();
-    Document* doc = document();
-    if (treeScope()->focusedNode() == this) {
+    if (treeScope()->adjustedFocusedElement() == this) {
+        Document* doc = document();
         if (doc->frame())
-            doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
+            doc->frame()->page()->focusController()->setFocusedElement(0, doc->frame());
         else
-            doc->setFocusedNode(0);
+            doc->setFocusedElement(0);
     }
 }
 
@@ -2327,11 +2352,6 @@
     return hasRareData() && elementRareData()->isInCanvasSubtree();
 }
 
-bool Element::isUnresolvedCustomElement()
-{
-    return isCustomElement() && document()->registry()->isUnresolved(this);
-}
-
 void Element::setIsInsideRegion(bool value)
 {
     if (value == isInsideRegion())
@@ -2423,7 +2443,10 @@
 
 void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
 {
-    if (!document()->styleSheetCollection()->usesBeforeAfterRules())
+    if ((pseudoId == BEFORE || pseudoId == AFTER) && !document()->styleSheetCollection()->usesBeforeAfterRules())
+        return;
+
+    if (pseudoId == BACKDROP && !isInTopLayer())
         return;
 
     if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
@@ -2434,7 +2457,10 @@
 
     ASSERT(!isPseudoElement());
     RefPtr<PseudoElement> element = PseudoElement::create(this, pseudoId);
+    if (pseudoId == BACKDROP)
+        document()->addToTopLayer(element.get(), this);
     element->attach();
+
     ensureElementRareData()->setPseudoElement(pseudoId, element.release());
 }
 
@@ -2463,7 +2489,7 @@
 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
 {
     if (selector.isEmpty()) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return false;
     }
 
@@ -2568,7 +2594,7 @@
 void Element::setContainsFullScreenElement(bool flag)
 {
     ensureElementRareData()->setContainsFullScreenElement(flag);
-    setNeedsStyleRecalc(SyntheticStyleChange);
+    setNeedsStyleRecalc(SubtreeStyleChange);
 }
 
 static Element* parentCrossingFrameBoundaries(Element* element)
@@ -2770,9 +2796,9 @@
         return;
 
     if (!oldForAttributeValue.isEmpty())
-        scope->removeLabel(oldForAttributeValue, static_cast<HTMLLabelElement*>(this));
+        scope->removeLabel(oldForAttributeValue, toHTMLLabelElement(this));
     if (!newForAttributeValue.isEmpty())
-        scope->addLabel(newForAttributeValue, static_cast<HTMLLabelElement*>(this));
+        scope->addLabel(newForAttributeValue, toHTMLLabelElement(this));
 }
 
 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
@@ -2790,6 +2816,9 @@
     if (oldValue != newValue) {
         if (attached() && document()->styleResolver() && document()->styleResolver()->hasSelectorForAttribute(name.localName()))
            setNeedsStyleRecalc();
+
+        if (isUpgradedCustomElement())
+            document()->registrationContext()->customElementAttributeDidChange(this, name.localName(), oldValue, newValue);
     }
 
     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
@@ -2819,6 +2848,20 @@
     dispatchSubtreeModifiedEvent();
 }
 
+void Element::didMoveToNewDocument(Document* oldDocument)
+{
+    Node::didMoveToNewDocument(oldDocument);
+
+    // If the documents differ by quirks mode then they differ by case sensitivity
+    // for class and id names so we need to go through the attribute change logic
+    // to pick up the new casing in the ElementData.
+    if (oldDocument->inQuirksMode() != document()->inQuirksMode()) {
+        if (hasID())
+            setIdAttribute(getIdAttribute());
+        if (hasClass())
+            setAttribute(HTMLNames::classAttr, getClassAttribute());
+    }
+}
 
 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
 {
@@ -2865,7 +2908,9 @@
 
 static void scheduleLayerUpdateCallback(Node* node)
 {
-    node->setNeedsLayerUpdate();
+    // Notify the renderer even is the styles are identical since it may need to
+    // create or destroy a RenderLayer.
+    node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
 }
 
 void Element::scheduleLayerUpdate()
@@ -2873,7 +2918,7 @@
     if (postAttachCallbacksAreSuspended())
         queuePostAttachCallback(scheduleLayerUpdateCallback, this);
     else
-        setNeedsLayerUpdate();
+        scheduleLayerUpdateCallback(this);
 }
 
 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
@@ -2983,14 +3028,22 @@
     if (!oldName.isNull() || !newName.isNull())
         updateName(oldName, newName);
 
+    // Quirks mode makes class and id not case sensitive. We can't share the ElementData
+    // if the idForStyleResolution and the className need different casing.
+    bool ownerDocumentsHaveDifferentCaseSensitivity = false;
+    if (other.hasClass() || other.hasID())
+        ownerDocumentsHaveDifferentCaseSensitivity = other.document()->inQuirksMode() != document()->inQuirksMode();
+
     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
-    // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
+    // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes,
+    // and sharing the data won't result in different case sensitivity of class or id.
     if (other.m_elementData->isUnique()
+        && !ownerDocumentsHaveDifferentCaseSensitivity
         && !other.m_elementData->presentationAttributeStyle()
         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
 
-    if (!other.m_elementData->isUnique())
+    if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
         m_elementData = other.m_elementData;
     else
         m_elementData = other.m_elementData->makeUniqueCopy();
@@ -3196,14 +3249,14 @@
 
     elementData()->m_styleAttributeIsDirty = false;
 
-    setNeedsStyleRecalc(InlineStyleChange);
+    setNeedsStyleRecalc(LocalStyleChange);
     InspectorInstrumentation::didInvalidateStyleAttr(document(), this);
 }
 
 void Element::inlineStyleChanged()
 {
     ASSERT(isStyledElement());
-    setNeedsStyleRecalc(InlineStyleChange);
+    setNeedsStyleRecalc(LocalStyleChange);
     ASSERT(elementData());
     elementData()->m_styleAttributeIsDirty = true;
     InspectorInstrumentation::didInvalidateStyleAttr(document(), this);
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 2aa1745..4f71560 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -208,6 +208,8 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseenter);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseleave);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
@@ -334,6 +336,8 @@
     // Returns the absolute bounding box translated into screen coordinates:
     IntRect screenRect() const;
 
+    virtual void didMoveToNewDocument(Document*) OVERRIDE;
+
     void removeAttribute(const AtomicString& name);
     void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
 
@@ -432,7 +436,7 @@
     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
     virtual RenderObject* createRenderer(RenderStyle*);
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
-    void recalcStyle(StyleChange = NoChange);
+    bool recalcStyle(StyleChange = NoChange);
     void didAffectSelector(AffectedSelectorMask);
 
     ElementShadow* shadow() const;
@@ -479,7 +483,7 @@
     void setIsInCanvasSubtree(bool);
     bool isInCanvasSubtree() const;
 
-    bool isUnresolvedCustomElement();
+    bool isUnresolvedCustomElement() { return isCustomElement() && !isUpgradedCustomElement(); }
 
     void setIsInsideRegion(bool);
     bool isInsideRegion() const;
@@ -560,7 +564,7 @@
     virtual bool isInRange() const { return false; }
     virtual bool isOutOfRange() const { return false; }
     virtual bool isFrameElementBase() const { return false; }
-    virtual bool isTextFieldDecoration() const { return false; }
+    virtual bool isPasswordGeneratorButtonElement() const { return false; }
     virtual bool isClearButtonElement() const;
 
     virtual bool canContainRangeEndPoint() const { return true; }
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index 543a8a1..2dd8467 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -27,12 +27,12 @@
     [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString tagName;
 
     [TreatReturnedNullStringAs=Null] DOMString getAttribute([Default=Undefined] optional DOMString name);
-    [RaisesException] void setAttribute([Default=Undefined] optional DOMString name,
+    [RaisesException, DeliverCustomElementCallbacks] void setAttribute([Default=Undefined] optional DOMString name,
                                      [Default=Undefined] optional DOMString value);
-    void removeAttribute([Default=Undefined] optional DOMString name);
+    [DeliverCustomElementCallbacks] void removeAttribute([Default=Undefined] optional DOMString name);
     Attr getAttributeNode([Default=Undefined] optional DOMString name);
-    [RaisesException] Attr setAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr newAttr);
-    [RaisesException] Attr removeAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr oldAttr);
+    [RaisesException, DeliverCustomElementCallbacks] Attr setAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr newAttr);
+    [RaisesException, DeliverCustomElementCallbacks] Attr removeAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr oldAttr);
     [PerWorldBindings] NodeList getElementsByTagName([Default=Undefined] optional DOMString name);
 
     // For ObjC this is defined on Node for legacy support.
@@ -43,10 +43,10 @@
 
      DOMString getAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                                             [Default=Undefined] optional DOMString localName);
-     [RaisesException] void setAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+     [RaisesException, DeliverCustomElementCallbacks] void setAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                                        [Default=Undefined] optional DOMString qualifiedName,
                                        [Default=Undefined] optional DOMString value);
-     void removeAttributeNS([TreatNullAs=NullString] DOMString namespaceURI,
+     [DeliverCustomElementCallbacks] void removeAttributeNS([TreatNullAs=NullString] DOMString namespaceURI,
                                           DOMString localName);
      NodeList getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                                                    [Default=Undefined] optional DOMString localName);
@@ -145,6 +145,8 @@
     [NotEnumerable, PerWorldBindings] attribute EventListener onkeyup;
     [NotEnumerable, PerWorldBindings] attribute EventListener onload;
     [NotEnumerable, PerWorldBindings] attribute EventListener onmousedown;
+    [NotEnumerable, PerWorldBindings] attribute EventListener onmouseenter;
+    [NotEnumerable, PerWorldBindings] attribute EventListener onmouseleave;
     [NotEnumerable, PerWorldBindings] attribute EventListener onmousemove;
     [NotEnumerable, PerWorldBindings] attribute EventListener onmouseout;
     [NotEnumerable, PerWorldBindings] attribute EventListener onmouseover;
diff --git a/Source/core/dom/ElementRareData.cpp b/Source/core/dom/ElementRareData.cpp
index dd404bf..c6510d5 100644
--- a/Source/core/dom/ElementRareData.cpp
+++ b/Source/core/dom/ElementRareData.cpp
@@ -43,7 +43,7 @@
     RegionOversetState regionOversetState;
     LayoutSize sizeForResizing;
     IntSize scrollOffset;
-    void* pointers[9];
+    void* pointers[10];
 };
 
 COMPILE_ASSERT(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), ElementRareDataShouldStaySmall);
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index 440df8e..77244da 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -186,6 +186,7 @@
 
     RefPtr<PseudoElement> m_generatedBefore;
     RefPtr<PseudoElement> m_generatedAfter;
+    RefPtr<PseudoElement> m_backdrop;
 
     ElementRareData(RenderObject*);
     void releasePseudoElement(PseudoElement*);
@@ -226,6 +227,7 @@
     ASSERT(!m_shadow);
     ASSERT(!m_generatedBefore);
     ASSERT(!m_generatedAfter);
+    ASSERT(!m_backdrop);
 }
 
 inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
@@ -239,6 +241,10 @@
         releasePseudoElement(m_generatedAfter.get());
         m_generatedAfter = element;
         break;
+    case BACKDROP:
+        releasePseudoElement(m_backdrop.get());
+        m_backdrop = element;
+        break;
     default:
         ASSERT_NOT_REACHED();
     }
@@ -251,6 +257,8 @@
         return m_generatedBefore.get();
     case AFTER:
         return m_generatedAfter.get();
+    case BACKDROP:
+        return m_backdrop.get();
     default:
         return 0;
     }
@@ -267,6 +275,7 @@
     ASSERT(!element->nextSibling());
     ASSERT(!element->previousSibling());
 
+    element->document()->removeFromTopLayer(element);
     element->setParentOrShadowHostNode(0);
 }
 
diff --git a/Source/core/dom/ErrorEvent.h b/Source/core/dom/ErrorEvent.h
index 7992ec3..0c2a453 100644
--- a/Source/core/dom/ErrorEvent.h
+++ b/Source/core/dom/ErrorEvent.h
@@ -32,7 +32,7 @@
 #define ErrorEvent_h
 
 #include "core/dom/Event.h"
-#include <wtf/text/WTFString.h>
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Event.cpp b/Source/core/dom/Event.cpp
index 770e175..74a795f 100644
--- a/Source/core/dom/Event.cpp
+++ b/Source/core/dom/Event.cpp
@@ -27,8 +27,8 @@
 #include "core/dom/EventTarget.h"
 #include "core/dom/StaticNodeList.h"
 #include "core/dom/WebCoreMemoryInstrumentation.h"
-#include <wtf/CurrentTime.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/CurrentTime.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventContext.h b/Source/core/dom/EventContext.h
index 5e4f136..ea8961b 100644
--- a/Source/core/dom/EventContext.h
+++ b/Source/core/dom/EventContext.h
@@ -31,7 +31,7 @@
 #include "core/dom/Node.h"
 #include "core/dom/StaticNodeList.h"
 #include "core/dom/TreeScope.h"
-#include <wtf/RefPtr.h>
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventDispatchMediator.h b/Source/core/dom/EventDispatchMediator.h
index c334348..00ab327 100644
--- a/Source/core/dom/EventDispatchMediator.h
+++ b/Source/core/dom/EventDispatchMediator.h
@@ -31,9 +31,9 @@
 #ifndef EventDispatchMediator_h
 #define EventDispatchMediator_h
 
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventFactory.h b/Source/core/dom/EventFactory.h
index adfcfb5..2436e3f 100644
--- a/Source/core/dom/EventFactory.h
+++ b/Source/core/dom/EventFactory.h
@@ -26,8 +26,8 @@
 #ifndef EventFactory_h
 #define EventFactory_h
 
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventListener.h b/Source/core/dom/EventListener.h
index a1add8c..768a0c3 100644
--- a/Source/core/dom/EventListener.h
+++ b/Source/core/dom/EventListener.h
@@ -21,7 +21,7 @@
 #ifndef EventListener_h
 #define EventListener_h
 
-#include <wtf/RefCounted.h>
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventListenerMap.cpp b/Source/core/dom/EventListenerMap.cpp
index 1bc8690..ad0b72b 100644
--- a/Source/core/dom/EventListenerMap.cpp
+++ b/Source/core/dom/EventListenerMap.cpp
@@ -75,6 +75,20 @@
     return false;
 }
 
+bool EventListenerMap::containsCapturing(const AtomicString& eventType) const
+{
+    for (unsigned i = 0; i < m_entries.size(); ++i) {
+        if (m_entries[i].first == eventType) {
+            const EventListenerVector* vector = m_entries[i].second.get();
+            for (unsigned j = 0; j < vector->size(); ++j) {
+                if (vector->at(j).useCapture)
+                    return true;
+            }
+        }
+    }
+    return false;
+}
+
 void EventListenerMap::clear()
 {
     assertNoActiveIterators();
diff --git a/Source/core/dom/EventListenerMap.h b/Source/core/dom/EventListenerMap.h
index 052018a..4889d94 100644
--- a/Source/core/dom/EventListenerMap.h
+++ b/Source/core/dom/EventListenerMap.h
@@ -34,9 +34,9 @@
 #define EventListenerMap_h
 
 #include "core/dom/RegisteredEventListener.h"
-#include <wtf/Forward.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/text/AtomicStringHash.h>
+#include "wtf/Forward.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
@@ -50,6 +50,7 @@
 
     bool isEmpty() const { return m_entries.isEmpty(); }
     bool contains(const AtomicString& eventType) const;
+    bool containsCapturing(const AtomicString& eventType) const;
 
     void clear();
     bool add(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
diff --git a/Source/core/dom/EventNames.h b/Source/core/dom/EventNames.h
index 69796a9..0c01af9 100644
--- a/Source/core/dom/EventNames.h
+++ b/Source/core/dom/EventNames.h
@@ -25,7 +25,7 @@
 #include "EventInterfaces.h"
 #include "EventTargetInterfaces.h"
 #include "core/platform/ThreadGlobalData.h"
-#include <wtf/text/AtomicString.h>
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
@@ -92,6 +92,8 @@
     macro(message) \
     macro(midimessage) \
     macro(mousedown) \
+    macro(mouseenter) \
+    macro(mouseleave) \
     macro(mousemove) \
     macro(mouseout) \
     macro(mouseover) \
diff --git a/Source/core/dom/EventQueue.h b/Source/core/dom/EventQueue.h
index 56ce153..513bf36 100644
--- a/Source/core/dom/EventQueue.h
+++ b/Source/core/dom/EventQueue.h
@@ -27,9 +27,9 @@
 #ifndef EventQueue_h
 #define EventQueue_h
 
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/PassOwnPtr.h>
+#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventRetargeter.cpp b/Source/core/dom/EventRetargeter.cpp
index 415a3fc..153ada7 100644
--- a/Source/core/dom/EventRetargeter.cpp
+++ b/Source/core/dom/EventRetargeter.cpp
@@ -32,9 +32,9 @@
 #include "core/dom/TouchList.h"
 #include "core/dom/TreeScope.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventSender.h b/Source/core/dom/EventSender.h
index 40d8175..d738901 100644
--- a/Source/core/dom/EventSender.h
+++ b/Source/core/dom/EventSender.h
@@ -27,8 +27,8 @@
 #define EventSender_h
 
 #include "core/platform/Timer.h"
-#include <wtf/text/AtomicString.h>
-#include <wtf/Vector.h>
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/EventTarget.cpp b/Source/core/dom/EventTarget.cpp
index 15fb804..f2aa211 100644
--- a/Source/core/dom/EventTarget.cpp
+++ b/Source/core/dom/EventTarget.cpp
@@ -143,7 +143,7 @@
 bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
 {
     if (!event || event->type().isEmpty() || event->isBeingDispatched()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return false;
     }
 
diff --git a/Source/core/dom/EventTarget.h b/Source/core/dom/EventTarget.h
index 2d8a0a9..5b736ed 100644
--- a/Source/core/dom/EventTarget.h
+++ b/Source/core/dom/EventTarget.h
@@ -121,6 +121,7 @@
 
         bool hasEventListeners();
         bool hasEventListeners(const AtomicString& eventType);
+        bool hasCapturingEventListeners(const AtomicString& eventType);
         const EventListenerVector& getEventListeners(const AtomicString& eventType);
 
         bool fireEventListeners(Event*);
@@ -165,9 +166,13 @@
         EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(eventNames().eventName##Event, isolatedWorld); } \
         void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(eventNames().eventName##Event, listener, isolatedWorld); } \
 
-    #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
-        EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event, isolatedWorld) : 0; } \
-        void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
+    #define DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
+        EventListener* on##attribute(DOMWrapperWorld* isolatedWorld); \
+        void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld);
+
+    #define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(type, recipient, attribute) \
+        EventListener* type::on##attribute(DOMWrapperWorld* isolatedWorld) { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event, isolatedWorld) : 0; } \
+        void type::setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); }
 
     inline bool EventTarget::isFiringEventListeners()
     {
@@ -193,6 +198,14 @@
         return d->eventListenerMap.contains(eventType);
     }
 
+    inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventType)
+    {
+        EventTargetData* d = eventTargetData();
+        if (!d)
+            return false;
+        return d->eventListenerMap.containsCapturing(eventType);
+    }
+
 } // namespace WebCore
 
 #endif // EventTarget_h
diff --git a/Source/core/dom/EventTarget.idl b/Source/core/dom/EventTarget.idl
index 32af401..d711cd7 100644
--- a/Source/core/dom/EventTarget.idl
+++ b/Source/core/dom/EventTarget.idl
@@ -19,17 +19,14 @@
  */
 
 [
-    NoInterfaceObject,
     CustomToV8,
-    DoNotGenerateWrap,
-    EventTarget
+    DoNotGenerateWrap
 ] interface EventTarget {
     void addEventListener(DOMString type, 
-                                         EventListener listener, 
-                                         optional boolean useCapture);
+                          EventListener listener,
+                          optional boolean useCapture);
     void removeEventListener(DOMString type, 
-                                         EventListener listener, 
-                                         optional boolean useCapture);
+                             EventListener listener,
+                             optional boolean useCapture);
     [RaisesException] boolean dispatchEvent(Event event);
 };
-
diff --git a/Source/core/dom/ExceptionCode.h b/Source/core/dom/ExceptionCode.h
index cf6dc69..93fbdc0 100644
--- a/Source/core/dom/ExceptionCode.h
+++ b/Source/core/dom/ExceptionCode.h
@@ -31,40 +31,39 @@
     // Some of these are considered historical since they have been
     // changed or removed from the specifications.
     enum {
-        // FIXME: Rename these to use CamelCase matching the exception name.
-        INDEX_SIZE_ERR = 1,
-        HIERARCHY_REQUEST_ERR,
-        WRONG_DOCUMENT_ERR,
-        INVALID_CHARACTER_ERR,
-        NO_MODIFICATION_ALLOWED_ERR,
-        NOT_FOUND_ERR,
-        NOT_SUPPORTED_ERR,
-        INUSE_ATTRIBUTE_ERR, // Historical. Only used in setAttributeNode etc which have been removed from the DOM specs.
+        IndexSizeError = 1,
+        HierarchyRequestError,
+        WrongDocumentError,
+        InvalidCharacterError,
+        NoModificationAllowedError,
+        NotFoundError,
+        NotSupportedError,
+        InUseAttributeError, // Historical. Only used in setAttributeNode etc which have been removed from the DOM specs.
 
+        // FIXME: Rename these to use CamelCase matching the exception name.
         // Introduced in DOM Level 2:
-        INVALID_STATE_ERR,
-        SYNTAX_ERR,
-        INVALID_MODIFICATION_ERR,
-        NAMESPACE_ERR,
-        INVALID_ACCESS_ERR,
+        InvalidStateError,
+        SyntaxError,
+        InvalidModificationError,
+        NamespaceError,
+        InvalidAccessError,
 
         // Introduced in DOM Level 3:
-        TYPE_MISMATCH_ERR, // Historical; use TypeError instead
+        TypeMismatchError, // Historical; use TypeError instead
 
         // XMLHttpRequest extension:
-        SECURITY_ERR,
+        SecurityError,
 
         // Others introduced in HTML5:
-        NETWORK_ERR,
-        ABORT_ERR,
-        URL_MISMATCH_ERR,
-        QUOTA_EXCEEDED_ERR,
-        TIMEOUT_ERR,
-        INVALID_NODE_TYPE_ERR,
-        DATA_CLONE_ERR,
+        NetworkError,
+        AbortError,
+        URLMismatchError,
+        QuotaExceededError,
+        TimeoutError,
+        InvalidNodeTypeError,
+        DataCloneError,
 
         // These are IDB-specific.
-        IDBNotFoundError,
         UnknownError,
         ConstraintError,
         DataError,
@@ -78,25 +77,16 @@
         FSSecurityError,
         FSAbortError,
         FSNotReadableError,
-        FSEncodingError,
+        EncodingError,
         FSNoModificationAllowedError,
         FSInvalidStateError,
         FSSyntaxError,
-        FSInvalidModificationError,
         FSQuotaExceededError,
         FSTypeMismatchError,
-        FSPathExistsError,
+        PathExistsError,
 
         // SQL
-        // FIXME: Consolidate these once https://crbug.com/252233 is fixed.
-        SQLUnknownError,
-        SQLDatabaseError,
-        SQLVersionError,
-        SQLTooLargeError,
-        SQLQuotaExceededError,
-        SQLSyntaxError,
-        SQLConstraintError,
-        SQLTimeoutError,
+        SQLDatabaseError, // Naming conflict with DatabaseError class.
 
         // WebIDL exception types, handled by the binding layer.
         // FIXME: Add GeneralError, EvalError, etc. when implemented in the bindings.
diff --git a/Source/core/dom/ExceptionCodePlaceholder.h b/Source/core/dom/ExceptionCodePlaceholder.h
index 5d19eb3..e6a4fe6 100644
--- a/Source/core/dom/ExceptionCodePlaceholder.h
+++ b/Source/core/dom/ExceptionCodePlaceholder.h
@@ -31,8 +31,8 @@
 #ifndef ExceptionCodePlaceholder_h
 #define ExceptionCodePlaceholder_h
 
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
+#include "wtf/Assertions.h"
+#include "wtf/Noncopyable.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/GenericEventQueue.h b/Source/core/dom/GenericEventQueue.h
index 5900a72..5f4e426 100644
--- a/Source/core/dom/GenericEventQueue.h
+++ b/Source/core/dom/GenericEventQueue.h
@@ -29,9 +29,9 @@
 #include "core/dom/EventQueue.h"
 #include "core/dom/EventTarget.h"
 #include "core/platform/Timer.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/GestureEvent.cpp b/Source/core/dom/GestureEvent.cpp
index 5b1be80..a4f5cf8 100644
--- a/Source/core/dom/GestureEvent.cpp
+++ b/Source/core/dom/GestureEvent.cpp
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "core/dom/Element.h"
 #include "core/dom/GestureEvent.h"
-#include <wtf/text/AtomicString.h>
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
@@ -84,8 +84,10 @@
 
 const AtomicString& GestureEvent::interfaceName() const
 {
-    DEFINE_STATIC_LOCAL(AtomicString, name, ("TBDInterface"));
-    return name;
+    // FIXME: when a GestureEvent.idl interface is defined, return the string "GestureEvent".
+    // Until that happens, do not advertise an interface that does not exist, since it will
+    // trip up the bindings integrity checks.
+    return UIEvent::interfaceName();
 }
 
 GestureEvent::GestureEvent()
diff --git a/Source/core/dom/IdTargetObserver.h b/Source/core/dom/IdTargetObserver.h
index f9007c4..e76b8a5 100644
--- a/Source/core/dom/IdTargetObserver.h
+++ b/Source/core/dom/IdTargetObserver.h
@@ -26,7 +26,7 @@
 #ifndef IdTargetObserver_h
 #define IdTargetObserver_h
 
-#include <wtf/text/AtomicString.h>
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/IdTargetObserverRegistry.h b/Source/core/dom/IdTargetObserverRegistry.h
index ef5d662..fb04ff5 100644
--- a/Source/core/dom/IdTargetObserverRegistry.h
+++ b/Source/core/dom/IdTargetObserverRegistry.h
@@ -26,11 +26,11 @@
 #ifndef IdTargetObserverRegistry_h
 #define IdTargetObserverRegistry_h
 
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/PassOwnPtr.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/Forward.h"
+#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/LiveNodeList.h b/Source/core/dom/LiveNodeList.h
index 7ed7300..c4aa5cb 100644
--- a/Source/core/dom/LiveNodeList.h
+++ b/Source/core/dom/LiveNodeList.h
@@ -28,8 +28,8 @@
 #include "core/dom/Document.h"
 #include "core/dom/NodeList.h"
 #include "core/html/CollectionType.h"
-#include <wtf/Forward.h>
-#include <wtf/RefPtr.h>
+#include "wtf/Forward.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/MessageEvent.cpp b/Source/core/dom/MessageEvent.cpp
index 0e269d7..bec2624 100644
--- a/Source/core/dom/MessageEvent.cpp
+++ b/Source/core/dom/MessageEvent.cpp
@@ -46,7 +46,6 @@
 MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& initializer)
     : Event(type, initializer)
     , m_dataType(DataTypeScriptValue)
-    , m_dataAsScriptValue(initializer.data)
     , m_origin(initializer.origin)
     , m_lastEventId(initializer.lastEventId)
     , m_source(initializer.source)
@@ -55,10 +54,9 @@
     ScriptWrappable::init(this);
 }
 
-MessageEvent::MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
+MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray> ports)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeScriptValue)
-    , m_dataAsScriptValue(data)
     , m_origin(origin)
     , m_lastEventId(lastEventId)
     , m_source(source)
@@ -115,7 +113,7 @@
 {
 }
 
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
 {
     if (dispatched())
         return;
@@ -123,7 +121,6 @@
     initEvent(type, canBubble, cancelable);
 
     m_dataType = DataTypeScriptValue;
-    m_dataAsScriptValue = data;
     m_origin = origin;
     m_lastEventId = lastEventId;
     m_source = source;
diff --git a/Source/core/dom/MessageEvent.h b/Source/core/dom/MessageEvent.h
index 5912f8f..80965bf 100644
--- a/Source/core/dom/MessageEvent.h
+++ b/Source/core/dom/MessageEvent.h
@@ -28,13 +28,12 @@
 #ifndef MessageEvent_h
 #define MessageEvent_h
 
-#include "bindings/v8/ScriptValue.h"
 #include "bindings/v8/SerializedScriptValue.h"
 #include "core/dom/Event.h"
 #include "core/dom/MessagePort.h"
 #include "core/fileapi/Blob.h"
 #include "core/page/DOMWindow.h"
-#include <wtf/ArrayBuffer.h>
+#include "wtf/ArrayBuffer.h"
 
 namespace WebCore {
 
@@ -43,7 +42,6 @@
 struct MessageEventInit : public EventInit {
     MessageEventInit();
 
-    ScriptValue data;
     String origin;
     String lastEventId;
     RefPtr<DOMWindow> source;
@@ -56,9 +54,9 @@
     {
         return adoptRef(new MessageEvent);
     }
-    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const ScriptValue& data = ScriptValue(), const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
+    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
     {
-        return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
+        return adoptRef(new MessageEvent(origin, lastEventId, source, ports));
     }
     static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = "", const String& lastEventId = "", PassRefPtr<DOMWindow> source = 0)
     {
@@ -82,7 +80,7 @@
     }
     virtual ~MessageEvent();
 
-    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const ScriptValue& data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
+    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
     void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
 
     const String& origin() const { return m_origin; }
@@ -100,8 +98,7 @@
         DataTypeArrayBuffer
     };
     DataType dataType() const { return m_dataType; }
-    const ScriptValue& dataAsScriptValue() const { ASSERT(m_dataType == DataTypeScriptValue); return m_dataAsScriptValue; }
-    PassRefPtr<SerializedScriptValue> dataAsSerializedScriptValue() const { ASSERT(m_dataType == DataTypeSerializedScriptValue); return m_dataAsSerializedScriptValue; }
+    SerializedScriptValue* dataAsSerializedScriptValue() const { ASSERT(m_dataType == DataTypeSerializedScriptValue); return m_dataAsSerializedScriptValue.get(); }
     String dataAsString() const { ASSERT(m_dataType == DataTypeString); return m_dataAsString; }
     Blob* dataAsBlob() const { ASSERT(m_dataType == DataTypeBlob); return m_dataAsBlob.get(); }
     ArrayBuffer* dataAsArrayBuffer() const { ASSERT(m_dataType == DataTypeArrayBuffer); return m_dataAsArrayBuffer.get(); }
@@ -109,7 +106,7 @@
 private:
     MessageEvent();
     MessageEvent(const AtomicString&, const MessageEventInit&);
-    MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
+    MessageEvent(const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
     MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
 
     explicit MessageEvent(const String& data, const String& origin);
@@ -117,7 +114,6 @@
     explicit MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin);
 
     DataType m_dataType;
-    ScriptValue m_dataAsScriptValue;
     RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
     String m_dataAsString;
     RefPtr<Blob> m_dataAsBlob;
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index 37181e2..c83921e 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -67,7 +67,7 @@
         for (unsigned int i = 0; i < ports->size(); ++i) {
             MessagePort* dataPort = (*ports)[i].get();
             if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
-                ec = INVALID_STATE_ERR;
+                ec = InvalidStateError;
                 return;
             }
         }
@@ -200,7 +200,7 @@
     for (unsigned int i = 0; i < ports->size(); ++i) {
         MessagePort* port = (*ports)[i].get();
         if (!port || port->isNeutered() || portSet.contains(port)) {
-            ec = DATA_CLONE_ERR;
+            ec = DataCloneError;
             return nullptr;
         }
         portSet.add(port);
diff --git a/Source/core/dom/MessagePort.idl b/Source/core/dom/MessagePort.idl
index 85514c2..18e7284 100644
--- a/Source/core/dom/MessagePort.idl
+++ b/Source/core/dom/MessagePort.idl
@@ -26,9 +26,8 @@
  */
 
 [
-    ActiveDOMObject,
-    EventTarget
-] interface MessagePort {
+    ActiveDOMObject
+] interface MessagePort : EventTarget {
 // We need to have something as an ObjC binding, because MessagePort is used in MessageEvent, which already has one,
 // but we don't want to actually expose the API while it is in flux.
     [Custom, RaisesException] void postMessage(any message, optional Array messagePorts);
@@ -38,14 +37,5 @@
 
     // event handler attributes
     attribute EventListener onmessage;
-
-    // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event evt);
 };
 
diff --git a/Source/core/dom/MouseEvent.cpp b/Source/core/dom/MouseEvent.cpp
index c0a6cbe..e11d1d8 100644
--- a/Source/core/dom/MouseEvent.cpp
+++ b/Source/core/dom/MouseEvent.cpp
@@ -57,9 +57,11 @@
 {
     ASSERT(event.type() == PlatformEvent::MouseMoved || event.button() != NoButton);
 
-    bool isCancelable = eventType != eventNames().mousemoveEvent;
+    bool isMouseEnterOrLeave = eventType == eventNames().mouseenterEvent || eventType == eventNames().mouseleaveEvent;
+    bool isCancelable = eventType != eventNames().mousemoveEvent && !isMouseEnterOrLeave;
+    bool isBubbling = !isMouseEnterOrLeave;
 
-    return MouseEvent::create(eventType, true, isCancelable, view,
+    return MouseEvent::create(eventType, isBubbling, isCancelable, view,
         detail, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
         event.movementDelta().x(), event.movementDelta().y(),
         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.button(),
@@ -189,18 +191,18 @@
 Node* MouseEvent::toElement() const
 {
     // MSIE extension - "the object toward which the user is moving the mouse pointer"
-    if (type() == eventNames().mouseoutEvent) 
+    if (type() == eventNames().mouseoutEvent || type() == eventNames().mouseleaveEvent)
         return relatedTarget() ? relatedTarget()->toNode() : 0;
-    
+
     return target() ? target()->toNode() : 0;
 }
 
 Node* MouseEvent::fromElement() const
 {
     // MSIE extension - "object from which activation or the mouse pointer is exiting during the event" (huh?)
-    if (type() != eventNames().mouseoutEvent)
+    if (type() != eventNames().mouseoutEvent && type() != eventNames().mouseleaveEvent)
         return relatedTarget() ? relatedTarget()->toNode() : 0;
-    
+
     return target() ? target()->toNode() : 0;
 }
 
diff --git a/Source/core/dom/MutationCallback.h b/Source/core/dom/MutationCallback.h
index a60ce8b..af904e2 100644
--- a/Source/core/dom/MutationCallback.h
+++ b/Source/core/dom/MutationCallback.h
@@ -31,9 +31,9 @@
 #ifndef MutationCallback_h
 #define MutationCallback_h
 
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/MutationObserver.cpp b/Source/core/dom/MutationObserver.cpp
index 4c46b09..a2e4084 100644
--- a/Source/core/dom/MutationObserver.cpp
+++ b/Source/core/dom/MutationObserver.cpp
@@ -40,9 +40,9 @@
 #include "core/dom/MutationObserverRegistration.h"
 #include "core/dom/MutationRecord.h"
 #include "core/dom/Node.h"
-#include <wtf/HashSet.h>
-#include <wtf/MainThread.h>
-#include <wtf/Vector.h>
+#include "wtf/HashSet.h"
+#include "wtf/MainThread.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
@@ -84,7 +84,7 @@
 void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary, ExceptionCode& ec)
 {
     if (!node) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -111,7 +111,7 @@
         options |= AttributeFilter;
 
     if (!validateOptions(options)) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return;
     }
 
diff --git a/Source/core/dom/MutationObserverInterestGroup.h b/Source/core/dom/MutationObserverInterestGroup.h
index 981c6e1..2de1070 100644
--- a/Source/core/dom/MutationObserverInterestGroup.h
+++ b/Source/core/dom/MutationObserverInterestGroup.h
@@ -35,8 +35,8 @@
 #include "core/dom/MutationObserver.h"
 #include "core/dom/Node.h"
 #include "core/dom/QualifiedName.h"
-#include <wtf/HashMap.h>
-#include <wtf/PassOwnPtr.h>
+#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/MutationObserverRegistration.h b/Source/core/dom/MutationObserverRegistration.h
index b17d95a..7c0fb52 100644
--- a/Source/core/dom/MutationObserverRegistration.h
+++ b/Source/core/dom/MutationObserverRegistration.h
@@ -32,9 +32,9 @@
 #define MutationObserverRegistration_h
 
 #include "core/dom/MutationObserver.h"
-#include <wtf/HashSet.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/AtomicStringHash.h>
+#include "wtf/HashSet.h"
+#include "wtf/text/AtomicString.h"
+#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NameNodeList.cpp b/Source/core/dom/NameNodeList.cpp
index 19aadbb..c4648c0 100644
--- a/Source/core/dom/NameNodeList.cpp
+++ b/Source/core/dom/NameNodeList.cpp
@@ -25,7 +25,7 @@
 
 #include "core/dom/Element.h"
 #include "core/dom/NodeRareData.h"
-#include <wtf/Assertions.h>
+#include "wtf/Assertions.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NameNodeList.h b/Source/core/dom/NameNodeList.h
index 32c1eff..96bcac4 100644
--- a/Source/core/dom/NameNodeList.h
+++ b/Source/core/dom/NameNodeList.h
@@ -25,8 +25,8 @@
 #define NameNodeList_h
 
 #include "core/dom/LiveNodeList.h"
-#include <wtf/Forward.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/Forward.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NamedFlowCollection.cpp b/Source/core/dom/NamedFlowCollection.cpp
index 8672d6d..ef35fa9 100644
--- a/Source/core/dom/NamedFlowCollection.cpp
+++ b/Source/core/dom/NamedFlowCollection.cpp
@@ -35,9 +35,8 @@
 #include "core/dom/Document.h"
 #include "core/dom/NamedFlow.h"
 #include "core/inspector/InspectorInstrumentation.h"
-
-#include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
+#include "wtf/text/StringHash.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NamedFlowCollection.h b/Source/core/dom/NamedFlowCollection.h
index 47107e0..8d8d32c 100644
--- a/Source/core/dom/NamedFlowCollection.h
+++ b/Source/core/dom/NamedFlowCollection.h
@@ -32,11 +32,11 @@
 
 #include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/NamedFlow.h"
-#include <wtf/Forward.h>
-#include <wtf/ListHashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
+#include "wtf/Forward.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NamedNodeMap.cpp b/Source/core/dom/NamedNodeMap.cpp
index 05f194f..0f93b6d 100644
--- a/Source/core/dom/NamedNodeMap.cpp
+++ b/Source/core/dom/NamedNodeMap.cpp
@@ -63,7 +63,7 @@
 {
     size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(name, shouldIgnoreAttributeCase(m_element)) : notFound;
     if (index == notFound) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
     return m_element->detachAttribute(index);
@@ -73,7 +73,7 @@
 {
     size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)) : notFound;
     if (index == notFound) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
     return m_element->detachAttribute(index);
@@ -82,13 +82,13 @@
 PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec)
 {
     if (!node) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
 
     // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
     if (!node->isAttributeNode()) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return 0;
     }
 
diff --git a/Source/core/dom/NamedNodeMap.h b/Source/core/dom/NamedNodeMap.h
index 609b3b5..cbb12b4 100644
--- a/Source/core/dom/NamedNodeMap.h
+++ b/Source/core/dom/NamedNodeMap.h
@@ -26,9 +26,9 @@
 #define NamedNodeMap_h
 
 #include "bindings/v8/ScriptWrappable.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NamedNodeMap.idl b/Source/core/dom/NamedNodeMap.idl
index 6a8e4e0..d0bd9bd 100644
--- a/Source/core/dom/NamedNodeMap.idl
+++ b/Source/core/dom/NamedNodeMap.idl
@@ -25,9 +25,9 @@
     Node getNamedItem([Default=Undefined] optional DOMString name);
     [NotEnumerable, ImplementedAs=getNamedItem] getter Node ([Default=Undefined] optional DOMString name);
 
-    [RaisesException] Node setNamedItem([Default=Undefined] optional Node node);
+    [RaisesException, DeliverCustomElementCallbacks] Node setNamedItem([Default=Undefined] optional Node node);
 
-    [RaisesException] Node removeNamedItem([Default=Undefined] optional DOMString name);
+    [RaisesException, DeliverCustomElementCallbacks] Node removeNamedItem([Default=Undefined] optional DOMString name);
 
     getter Node item([Default=Undefined] optional unsigned long index);
     
@@ -40,9 +40,9 @@
     /*[RaisesException]*/ Node getNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI, 
                                               [Default=Undefined] optional DOMString localName);
 
-    [RaisesException] Node setNamedItemNS([Default=Undefined] optional Node node);
+    [RaisesException, DeliverCustomElementCallbacks] Node setNamedItemNS([Default=Undefined] optional Node node);
 
-     [RaisesException] Node removeNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI, 
+    [RaisesException, DeliverCustomElementCallbacks] Node removeNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
                                           [Default=Undefined] optional DOMString localName);
 
 };
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 3f107e9..567f730 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -98,7 +98,6 @@
 
 using namespace HTMLNames;
 
-#if ENABLE(PARTITION_ALLOC)
 void* Node::operator new(size_t size)
 {
     return partitionAlloc(Partitions::getObjectModelPartition(), size);
@@ -108,7 +107,6 @@
 {
     partitionFree(ptr);
 }
-#endif // ENABLE(PARTITION_ALLOC)
 
 bool Node::isSupported(const String& feature, const String& version)
 {
@@ -261,25 +259,6 @@
 }
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, nodeCounter, ("WebCoreNode"));
-DEFINE_DEBUG_ONLY_GLOBAL(HashSet<Node*>, ignoreSet, );
-
-#ifndef NDEBUG
-static bool shouldIgnoreLeaks = false;
-#endif
-
-void Node::startIgnoringLeaks()
-{
-#ifndef NDEBUG
-    shouldIgnoreLeaks = true;
-#endif
-}
-
-void Node::stopIgnoringLeaks()
-{
-#ifndef NDEBUG
-    shouldIgnoreLeaks = false;
-#endif
-}
 
 Node::StyleChange Node::diff(const RenderStyle* s1, const RenderStyle* s2, Document* doc)
 {
@@ -346,10 +325,7 @@
 void Node::trackForDebugging()
 {
 #ifndef NDEBUG
-    if (shouldIgnoreLeaks)
-        ignoreSet.add(this);
-    else
-        nodeCounter.increment();
+    nodeCounter.increment();
 #endif
 
 #if DUMP_NODE_STATISTICS
@@ -360,11 +336,7 @@
 Node::~Node()
 {
 #ifndef NDEBUG
-    HashSet<Node*>::iterator it = ignoreSet.find(this);
-    if (it != ignoreSet.end())
-        ignoreSet.remove(it);
-    else
-        nodeCounter.decrement();
+    nodeCounter.decrement();
 #endif
 
 #if DUMP_NODE_STATISTICS
@@ -458,7 +430,7 @@
     return String();
 }
 
-void Node::setNodeValue(const String& /*nodeValue*/, ExceptionCode& ec)
+void Node::setNodeValue(const String&)
 {
     // By default, setting nodeValue has no effect.
 }
@@ -540,40 +512,36 @@
     return lastChild();
 }
 
-bool Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
-    if (!isContainerNode()) {
-        ec = HIERARCHY_REQUEST_ERR;
-        return false;
-    }
-    return toContainerNode(this)->insertBefore(newChild, refChild, ec, attachBehavior);
+    if (isContainerNode())
+        toContainerNode(this)->insertBefore(newChild, refChild, ec, attachBehavior);
+    else
+        ec = HierarchyRequestError;
 }
 
-bool Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
-    if (!isContainerNode()) {
-        ec = HIERARCHY_REQUEST_ERR;
-        return false;
-    }
-    return toContainerNode(this)->replaceChild(newChild, oldChild, ec, attachBehavior);
+    if (isContainerNode())
+        toContainerNode(this)->replaceChild(newChild, oldChild, ec, attachBehavior);
+    else
+        ec = HierarchyRequestError;
 }
 
-bool Node::removeChild(Node* oldChild, ExceptionCode& ec)
+void Node::removeChild(Node* oldChild, ExceptionCode& ec)
 {
-    if (!isContainerNode()) {
-        ec = NOT_FOUND_ERR;
-        return false;
-    }
-    return toContainerNode(this)->removeChild(oldChild, ec);
+    if (isContainerNode())
+        toContainerNode(this)->removeChild(oldChild, ec);
+    else
+        ec = NotFoundError;
 }
 
-bool Node::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, AttachBehavior attachBehavior)
+void Node::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, AttachBehavior attachBehavior)
 {
-    if (!isContainerNode()) {
-        ec = HIERARCHY_REQUEST_ERR;
-        return false;
-    }
-    return toContainerNode(this)->appendChild(newChild, ec, attachBehavior);
+    if (isContainerNode())
+        toContainerNode(this)->appendChild(newChild, ec, attachBehavior);
+    else
+        ec = HierarchyRequestError;
 }
 
 void Node::remove(ExceptionCode& ec)
@@ -646,8 +614,8 @@
 {
     // The spec says that for nodes other than elements and attributes, prefix is always null.
     // It does not say what to do when the user tries to set the prefix on another type of
-    // node, however Mozilla throws a NAMESPACE_ERR exception.
-    ec = NAMESPACE_ERR;
+    // node, however Mozilla throws a NamespaceError exception.
+    ec = NamespaceError;
 }
 
 const AtomicString& Node::localName() const
@@ -683,14 +651,10 @@
 
     for (const Node* node = this; node; node = node->parentNode()) {
         if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
-#if ENABLE(USERSELECT_ALL)
             // Elements with user-select: all style are considered atomic
             // therefore non editable.
             if (node->renderer()->style()->userSelect() == SELECT_ALL && treatment == UserSelectAllIsAlwaysNonEditable)
                 return false;
-#else
-            UNUSED_PARAM(treatment);
-#endif
             switch (node->renderer()->style()->userModify()) {
             case READ_ONLY:
                 return false;
@@ -821,17 +785,14 @@
     deref();
 }
 
-void Node::setNeedsStyleRecalc(StyleChangeType changeType)
+void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource source)
 {
     ASSERT(changeType != NoStyleChange);
     if (!attached()) // changed compared to what?
         return;
 
-    // FIXME: Switch all callers to use setNeedsLayerUpdate and get rid of SyntheticStyleChange.
-    if (changeType == SyntheticStyleChange) {
-        setNeedsLayerUpdate();
-        return;
-    }
+    if (source == StyleChangeFromRenderer)
+        setFlag(NotifyRendererWithIdenticalStyles);
 
     StyleChangeType existingChangeType = styleChangeType();
     if (changeType > existingChangeType)
@@ -841,12 +802,6 @@
         markAncestorsWithChildNeedsStyleRecalc();
 }
 
-void Node::setNeedsLayerUpdate()
-{
-    setFlag(NeedsLayerUpdate);
-    setNeedsStyleRecalc(InlineStyleChange);
-}
-
 void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
 {
     // It's safe to synchronously attach here because we're in the middle of style recalc
@@ -859,7 +814,7 @@
         attach();
         return;
     }
-    setStyleChange(FullStyleChange);
+    setStyleChange(SubtreeStyleChange);
     markAncestorsWithChildNeedsStyleRecalc();
     if (shouldSetAttached == DoNotSetAttached)
         return;
@@ -986,16 +941,16 @@
     // Element::setPrefix() and Attr::setPrefix()
 
     if (!prefix.isEmpty() && !Document::isValidName(prefix)) {
-        ec = INVALID_CHARACTER_ERR;
+        ec = InvalidCharacterError;
         return;
     }
 
-    // FIXME: Raise NAMESPACE_ERR if prefix is malformed per the Namespaces in XML specification.
+    // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
 
     const AtomicString& nodeNamespaceURI = namespaceURI();
     if ((nodeNamespaceURI.isEmpty() && !prefix.isEmpty())
         || (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI)) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return;
     }
     // Attribute-specific checks are in Attr::setPrefix().
@@ -1046,6 +1001,18 @@
     return false;
 }
 
+void Node::reattach(const AttachContext& context)
+{
+    // FIXME: Text::updateTextRenderer calls reattach outside a style recalc.
+    ASSERT(document()->inStyleRecalc() || isTextNode());
+    AttachContext reattachContext(context);
+    reattachContext.performingReattach = true;
+
+    if (attached())
+        detach(reattachContext);
+    attach(reattachContext);
+}
+
 void Node::attach(const AttachContext&)
 {
     ASSERT(!attached());
@@ -1053,7 +1020,8 @@
 
     // If this node got a renderer it may be the previousRenderer() of sibling text nodes and thus affect the
     // result of Text::textRendererIsNeeded() for those nodes.
-    if (renderer()) {
+    // FIXME: This loop is no longer required once we lazy attach all the time.
+    if (renderer() && !document()->inStyleRecalc()) {
         for (Node* next = nextSibling(); next; next = next->nextSibling()) {
             if (next->renderer())
                 break;
@@ -1364,7 +1332,7 @@
 PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, ExceptionCode& ec)
 {
     if (selectors.isEmpty()) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return 0;
     }
 
@@ -1377,7 +1345,7 @@
 PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionCode& ec)
 {
     if (selectors.isEmpty()) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return 0;
     }
 
@@ -1679,7 +1647,7 @@
         case CDATA_SECTION_NODE:
         case COMMENT_NODE:
         case PROCESSING_INSTRUCTION_NODE:
-            setNodeValue(text, ec);
+            setNodeValue(text);
             return;
         case ELEMENT_NODE:
         case ATTRIBUTE_NODE:
@@ -2091,11 +2059,6 @@
         it->value->invalidateCache();
 }
 
-void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
-{
-    addSubresourceAttributeURLs(urls);
-}
-
 Node* Node::enclosingLinkEventParentOrSelf()
 {
     for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
@@ -2311,6 +2274,10 @@
     if (index == notFound)
         return;
 
+    // Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes
+    // before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive).
+    // FIXME: Simplify the registration/transient registration logic to make this understandable by humans.
+    RefPtr<Node> protect(this);
     registry->remove(index);
 }
 
@@ -2504,7 +2471,7 @@
         if (event->hasInterface(eventNames().interfaceForTextEvent))
             if (Frame* frame = document()->frame())
                 frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
-#if ENABLE(PAN_SCROLLING)
+#if OS(WINDOWS)
     } else if (eventType == eventNames().mousedownEvent && event->isMouseEvent()) {
         MouseEvent* mouseEvent = toMouseEvent(event);
         if (mouseEvent->button() == MiddleButton) {
@@ -2738,6 +2705,13 @@
     setFlag(IsCustomElement);
 }
 
+void Node::setIsUpgradedCustomElement()
+{
+    ASSERT(isCustomElement());
+    setFlag(IsUpgradedCustomElement);
+    setNeedsStyleRecalc(); // :unresolved has changed
+}
+
 } // namespace WebCore
 
 #ifndef NDEBUG
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 6df001f..9d9ac54 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -37,9 +37,9 @@
 #include "core/platform/graphics/LayoutRect.h"
 #include "core/rendering/style/RenderStyleConstants.h"
 #include "weborigin/KURLHash.h"
-#include <wtf/Forward.h>
-#include <wtf/ListHashSet.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/Forward.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/text/AtomicString.h"
 
 // This needs to be here because Document.h also depends on it.
 #define DUMP_NODE_STATISTICS 0
@@ -85,15 +85,19 @@
 
 typedef int ExceptionCode;
 
-const int nodeStyleChangeShift = 15;
+const int nodeStyleChangeShift = 14;
 
 enum StyleChangeType {
     NoStyleChange = 0,
-    InlineStyleChange = 1 << nodeStyleChangeShift,
-    FullStyleChange = 2 << nodeStyleChangeShift,
+    LocalStyleChange = 1 << nodeStyleChangeShift,
+    SubtreeStyleChange = 2 << nodeStyleChangeShift,
+};
 
-    // FIXME: SyntheticStyleChange is deprecated, instead you should use setNeedsLayerUpdate().
-    SyntheticStyleChange = 3 << nodeStyleChangeShift,
+// If the style change is from the renderer then we'll call setStyle on the
+// renderer even if the style computed from CSS is identical.
+enum StyleChangeSource {
+    StyleChangeFromCSS,
+    StyleChangeFromRenderer
 };
 
 class NodeRareDataBase {
@@ -154,18 +158,12 @@
         DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
     };
 
-#if ENABLE(PARTITION_ALLOC)
     // All Nodes are placed in their own heap partition for security.
     // See http://crbug.com/246860 for detail.
     void* operator new(size_t);
     void operator delete(void*);
-#endif
 
     static bool isSupported(const String& feature, const String& version);
-
-    static void startIgnoringLeaks();
-    static void stopIgnoringLeaks();
-
     static void dumpStatistics();
 
     enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };    
@@ -180,7 +178,7 @@
     bool hasLocalName(const AtomicString&) const;
     virtual String nodeName() const = 0;
     virtual String nodeValue() const;
-    virtual void setNodeValue(const String&, ExceptionCode&);
+    virtual void setNodeValue(const String&);
     virtual NodeType nodeType() const = 0;
     ContainerNode* parentNode() const;
     Element* parentElement() const;
@@ -203,19 +201,17 @@
     Node* pseudoAwareLastChild() const;
 
     virtual KURL baseURI() const;
-    
-    void getSubresourceURLs(ListHashSet<KURL>&) const;
 
     // These should all actually return a node, but this is only important for language bindings,
     // which will already know and hold a ref on the right node to return. Returning bool allows
     // these methods to be more efficient since they don't need to return a ref
-    bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, AttachBehavior = AttachNow);
-    bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, AttachBehavior = AttachNow);
-    bool removeChild(Node* child, ExceptionCode&);
-    bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, AttachBehavior = AttachNow);
+    void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, AttachBehavior = AttachNow);
+    void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, AttachBehavior = AttachNow);
+    void removeChild(Node* child, ExceptionCode&);
+    void appendChild(PassRefPtr<Node> newChild, ExceptionCode&, AttachBehavior = AttachNow);
 
     bool hasChildNodes() const { return firstChild(); }
-    virtual PassRefPtr<Node> cloneNode(bool deep) = 0;
+    virtual PassRefPtr<Node> cloneNode(bool deep = true) = 0;
     virtual const AtomicString& localName() const;
     virtual const AtomicString& namespaceURI() const;
     virtual const AtomicString& prefix() const;
@@ -250,16 +246,27 @@
 
     bool isCustomElement() const { return getFlag(IsCustomElement); }
     void setIsCustomElement();
+    bool isUpgradedCustomElement() const { return getFlag(IsUpgradedCustomElement); }
+    void setIsUpgradedCustomElement();
 
     virtual bool isMediaControlElement() const { return false; }
     virtual bool isMediaControls() const { return false; }
     virtual bool isWebVTTElement() const { return false; }
-    bool isStyledElement() const { return getFlag(IsStyledElementFlag); }
     virtual bool isAttributeNode() const { return false; }
     virtual bool isCharacterDataNode() const { return false; }
     virtual bool isFrameOwnerElement() const { return false; }
     virtual bool isPluginElement() const { return false; }
 
+    // StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
+    // class names (ex. class="foo bar") and other non-basic styling features. They and also control
+    // if this element can participate in style sharing.
+    //
+    // FIXME: The only things that ever go through StyleResolver that aren't StyledElements are
+    // PseudoElements and WebVTTElements. It's possible we can just eliminate all the checks
+    // since those elements will never have class names, inline style, or other things that
+    // this apparently guards against.
+    bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
+
     bool isDocumentNode() const;
     bool isTreeScope() const { return treeScope()->rootNode() == this; }
     bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
@@ -373,15 +380,14 @@
     void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
     void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
 
-    void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
+    void setNeedsStyleRecalc(StyleChangeType = SubtreeStyleChange, StyleChangeSource = StyleChangeFromCSS);
     void clearNeedsStyleRecalc()
     {
         m_nodeFlags &= ~StyleChangeMask;
-        clearFlag(NeedsLayerUpdate);
+        clearFlag(NotifyRendererWithIdenticalStyles);
     }
 
-    void setNeedsLayerUpdate();
-    bool needsLayerUpdate() const { return getFlag(NeedsLayerUpdate); }
+    bool shouldNotifyRendererWithIdenticalStyles() const { return getFlag(NotifyRendererWithIdenticalStyles); }
 
     void setIsLink(bool f) { setFlag(f, IsLinkFlag); }
     void setIsLink() { setFlag(IsLinkFlag); }
@@ -560,7 +566,7 @@
     void reattach(const AttachContext& = AttachContext());
     void lazyReattachIfAttached();
     ContainerNode* parentNodeForRenderingAndStyle();
-    
+
     // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
     RenderStyle* renderStyle() const;
 
@@ -711,39 +717,40 @@
         IsTextFlag = 1,
         IsContainerFlag = 1 << 1,
         IsElementFlag = 1 << 2,
-        IsStyledElementFlag = 1 << 3,
-        IsHTMLFlag = 1 << 4,
-        IsSVGFlag = 1 << 5,
-        IsAttachedFlag = 1 << 6,
-        ChildNeedsStyleRecalcFlag = 1 << 7,
-        InDocumentFlag = 1 << 8,
-        IsLinkFlag = 1 << 9,
-        IsUserActionElement = 1 << 10,
-        HasRareDataFlag = 1 << 11,
-        IsDocumentFragmentFlag = 1 << 12,
+        IsHTMLFlag = 1 << 3,
+        IsSVGFlag = 1 << 4,
+        IsAttachedFlag = 1 << 5,
+        ChildNeedsStyleRecalcFlag = 1 << 6,
+        InDocumentFlag = 1 << 7,
+        IsLinkFlag = 1 << 8,
+        IsUserActionElement = 1 << 9,
+        HasRareDataFlag = 1 << 10,
+        IsDocumentFragmentFlag = 1 << 11,
 
         // These bits are used by derived classes, pulled up here so they can
         // be stored in the same memory word as the Node bits above.
-        IsParsingChildrenFinishedFlag = 1 << 13, // Element
-        HasSVGRareDataFlag = 1 << 14, // SVGElement
+        IsParsingChildrenFinishedFlag = 1 << 12, // Element
+        HasSVGRareDataFlag = 1 << 13, // SVGElement
 
         StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
 
-        SelfOrAncestorHasDirAutoFlag = 1 << 17,
+        SelfOrAncestorHasDirAutoFlag = 1 << 16,
 
-        HasNameOrIsEditingTextFlag = 1 << 18,
+        HasNameOrIsEditingTextFlag = 1 << 17,
 
-        InNamedFlowFlag = 1 << 19,
-        HasSyntheticAttrChildNodesFlag = 1 << 20,
-        HasCustomStyleCallbacksFlag = 1 << 21,
-        HasScopedHTMLStyleChildFlag = 1 << 22,
-        HasEventTargetDataFlag = 1 << 23,
-        V8CollectableDuringMinorGCFlag = 1 << 24,
-        IsInsertionPointFlag = 1 << 25,
-        IsInShadowTreeFlag = 1 << 26,
-        IsCustomElement = 1 << 27,
+        InNamedFlowFlag = 1 << 18,
+        HasSyntheticAttrChildNodesFlag = 1 << 19,
+        HasCustomStyleCallbacksFlag = 1 << 20,
+        HasScopedHTMLStyleChildFlag = 1 << 21,
+        HasEventTargetDataFlag = 1 << 22,
+        V8CollectableDuringMinorGCFlag = 1 << 23,
+        IsInsertionPointFlag = 1 << 24,
+        IsInShadowTreeFlag = 1 << 25,
+        IsCustomElement = 1 << 26,
 
-        NeedsLayerUpdate = 1 << 28,
+        NotifyRendererWithIdenticalStyles = 1 << 27,
+
+        IsUpgradedCustomElement = 1 << 28,
 
         DefaultNodeFlags = IsParsingChildrenFinishedFlag
     };
@@ -764,9 +771,8 @@
         CreatePseudoElement =  CreateElement | InDocumentFlag,
         CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
         CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
-        CreateStyledElement = CreateElement | IsStyledElementFlag, 
-        CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
-        CreateSVGElement = CreateStyledElement | IsSVGFlag,
+        CreateHTMLElement = CreateElement | IsHTMLFlag,
+        CreateSVGElement = CreateElement | IsSVGFlag,
         CreateDocument = CreateContainer | InDocumentFlag,
         CreateInsertionPoint = CreateHTMLElement | IsInsertionPointFlag,
         CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
@@ -906,16 +912,6 @@
     return parentOrShadowHostNode();
 }
 
-inline void Node::reattach(const AttachContext& context)
-{
-    AttachContext reattachContext(context);
-    reattachContext.performingReattach = true;
-
-    if (attached())
-        detach(reattachContext);
-    attach(reattachContext);
-}
-
 inline void Node::lazyReattachIfAttached()
 {
     if (attached())
diff --git a/Source/core/dom/Node.idl b/Source/core/dom/Node.idl
index ba0eb17..4ecd1d6 100644
--- a/Source/core/dom/Node.idl
+++ b/Source/core/dom/Node.idl
@@ -18,12 +18,10 @@
  * Boston, MA 02110-1301, USA.
  */
 
-// FIXME: Node should inherit EventTarget.
 [
     CustomToV8,
-    EventTarget,
     DependentLifetime
-] interface Node {
+] interface Node : EventTarget {
     // NodeType
     const unsigned short      ELEMENT_NODE                   = 1;
     const unsigned short      ATTRIBUTE_NODE                 = 2;
@@ -41,7 +39,7 @@
     [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString        nodeName;
 
              // FIXME: the spec says this can also raise on retrieval.
-             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException] attribute DOMString        nodeValue;
+             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings] attribute DOMString        nodeValue;
 
     [PerWorldBindings] readonly attribute unsigned short   nodeType;
     [PerWorldBindings] readonly attribute Node             parentNode;
@@ -59,7 +57,7 @@
 
     boolean            hasChildNodes();
     [DeliverCustomElementCallbacks, PerWorldBindings]
-    Node               cloneNode([Default=Undefined] optional boolean deep);
+    Node               cloneNode(optional boolean deep);
     void               normalize();
 
     // Introduced in DOM Level 2:
@@ -74,7 +72,7 @@
     [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString       baseURI;
 
              // FIXME: the spec says this can also raise on retrieval.
-             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException] attribute DOMString       textContent;
+             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, SetterRaisesException, DeliverCustomElementCallbacks] attribute DOMString       textContent;
 
     boolean            isSameNode([Default=Undefined] optional Node other);
     boolean            isEqualNode([Default=Undefined] optional Node other);
@@ -97,12 +95,4 @@
 
     // IE extensions
     [PerWorldBindings] readonly attribute Element          parentElement;
-
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event event);
 };
diff --git a/Source/core/dom/NodeFilterCondition.h b/Source/core/dom/NodeFilterCondition.h
index 9608fcb..4c838e9 100644
--- a/Source/core/dom/NodeFilterCondition.h
+++ b/Source/core/dom/NodeFilterCondition.h
@@ -26,7 +26,7 @@
 #define NodeFilterCondition_h
 
 #include "bindings/v8/ScriptState.h"
-#include <wtf/RefCounted.h>
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index 3d685d2..c23346f 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -93,7 +93,7 @@
 PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionCode& ec)
 {
     if (m_detached) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -122,7 +122,7 @@
 PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionCode& ec)
 {
     if (m_detached) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
diff --git a/Source/core/dom/NodeIterator.h b/Source/core/dom/NodeIterator.h
index 53f3d20..5aafc13 100644
--- a/Source/core/dom/NodeIterator.h
+++ b/Source/core/dom/NodeIterator.h
@@ -28,8 +28,8 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/NodeFilter.h"
 #include "core/dom/Traversal.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/NodeList.h b/Source/core/dom/NodeList.h
index c47182c..d6ddf17 100644
--- a/Source/core/dom/NodeList.h
+++ b/Source/core/dom/NodeList.h
@@ -25,8 +25,8 @@
 #define NodeList_h
 
 #include "bindings/v8/ScriptWrappable.h"
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Notation.h b/Source/core/dom/Notation.h
index 7cbac50..0d59e02 100644
--- a/Source/core/dom/Notation.h
+++ b/Source/core/dom/Notation.h
@@ -38,7 +38,7 @@
 
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
     virtual bool childTypeAllowed(NodeType) const;
 
     String m_name;
diff --git a/Source/core/dom/PendingScript.h b/Source/core/dom/PendingScript.h
index ee183a2..6794959 100644
--- a/Source/core/dom/PendingScript.h
+++ b/Source/core/dom/PendingScript.h
@@ -28,9 +28,9 @@
 
 #include "core/loader/cache/CachedResourceClient.h"
 #include "core/loader/cache/CachedResourceHandle.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/TextPosition.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/TextPosition.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/PopStateEvent.cpp b/Source/core/dom/PopStateEvent.cpp
index 072d28b..78456c8 100644
--- a/Source/core/dom/PopStateEvent.cpp
+++ b/Source/core/dom/PopStateEvent.cpp
@@ -33,10 +33,6 @@
 
 namespace WebCore {
 
-PopStateEventInit::PopStateEventInit()
-{
-}
-
 PopStateEvent::PopStateEvent()
     : Event(eventNames().popstateEvent, false, true)
     , m_serializedState(0)
@@ -47,7 +43,6 @@
 
 PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& initializer)
     : Event(type, initializer)
-    , m_state(initializer.state)
     , m_serializedState(0)
     , m_history(0)
 {
diff --git a/Source/core/dom/PopStateEvent.h b/Source/core/dom/PopStateEvent.h
index 1c59d0f..cbe4627 100644
--- a/Source/core/dom/PopStateEvent.h
+++ b/Source/core/dom/PopStateEvent.h
@@ -27,16 +27,11 @@
 #ifndef PopStateEvent_h
 #define PopStateEvent_h
 
-#include "bindings/v8/ScriptValue.h"
 #include "core/dom/Event.h"
 
 namespace WebCore {
 
-struct PopStateEventInit : public EventInit {
-    PopStateEventInit();
-
-    ScriptValue state;
-};
+typedef EventInit PopStateEventInit;
 
 class History;
 class SerializedScriptValue;
@@ -48,8 +43,7 @@
     static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
     static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
 
-    PassRefPtr<SerializedScriptValue> serializedState() const { return m_serializedState; }
-    const ScriptValue& state() const { return m_state; }
+    SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
     History* history() const { return m_history.get(); }
 
     virtual const AtomicString& interfaceName() const;
@@ -59,7 +53,6 @@
     PopStateEvent(const AtomicString&, const PopStateEventInit&);
     explicit PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
 
-    ScriptValue m_state;
     RefPtr<SerializedScriptValue> m_serializedState;
     RefPtr<History> m_history;
 };
diff --git a/Source/core/dom/Position.cpp b/Source/core/dom/Position.cpp
index 627bfa1..b1d7f07 100644
--- a/Source/core/dom/Position.cpp
+++ b/Source/core/dom/Position.cpp
@@ -35,6 +35,8 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
+#include "core/html/HTMLHtmlElement.h"
+#include "core/html/HTMLTableElement.h"
 #include "core/platform/Logging.h"
 #include "core/rendering/InlineIterator.h"
 #include "core/rendering/InlineTextBox.h"
@@ -548,7 +550,7 @@
         return true;
 
     // Don't include inline tables.
-    if (node->hasTagName(tableTag))
+    if (isHTMLTableElement(node))
         return false;
 
     // There is a VisiblePosition inside an empty inline-block container.
@@ -850,7 +852,6 @@
     return node->parentNode();
 }
 
-#if ENABLE(USERSELECT_ALL)
 bool Position::nodeIsUserSelectAll(const Node* node)
 {
     return node && node->renderer() && node->renderer()->style()->userSelect() == SELECT_ALL;
@@ -877,7 +878,6 @@
     }
     return candidateRoot;
 }
-#endif
 
 bool Position::isCandidate() const
 {
@@ -901,7 +901,7 @@
     if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
         return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
 
-    if (m_anchorNode->hasTagName(htmlTag))
+    if (isHTMLHtmlElement(m_anchorNode.get()))
         return false;
 
     if (renderer->isBlockFlow()) {
diff --git a/Source/core/dom/Position.h b/Source/core/dom/Position.h
index 9cb00f4..5d4fd32 100644
--- a/Source/core/dom/Position.h
+++ b/Source/core/dom/Position.h
@@ -30,9 +30,9 @@
 #include "core/editing/EditingBoundary.h"
 #include "core/editing/TextAffinity.h"
 #include "core/platform/text/TextDirection.h"
-#include <wtf/Assertions.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
+#include "wtf/Assertions.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
@@ -189,10 +189,8 @@
 
     static bool hasRenderedNonAnonymousDescendantsWithHeight(RenderObject*);
     static bool nodeIsUserSelectNone(Node*);
-#if ENABLE(USERSELECT_ALL)
     static bool nodeIsUserSelectAll(const Node*);
     static Node* rootUserSelectAllForNode(Node*);
-#endif
     static ContainerNode* findParent(const Node*);
     
     void debugPosition(const char* msg = "") const;
diff --git a/Source/core/dom/PositionIterator.cpp b/Source/core/dom/PositionIterator.cpp
index c9b2ef0..2156894 100644
--- a/Source/core/dom/PositionIterator.cpp
+++ b/Source/core/dom/PositionIterator.cpp
@@ -29,6 +29,7 @@
 #include "HTMLNames.h"
 #include "core/dom/Node.h"
 #include "core/editing/htmlediting.h"
+#include "core/html/HTMLHtmlElement.h"
 #include "core/rendering/RenderBlock.h"
 
 namespace WebCore {
@@ -159,7 +160,7 @@
     if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
         return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
 
-    if (!m_anchorNode->hasTagName(htmlTag) && renderer->isBlockFlow()) {
+    if (!isHTMLHtmlElement(m_anchorNode) && renderer->isBlockFlow()) {
         if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
                 return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index 7e5d25e..cbd329b 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "core/dom/ProcessingInstruction.h"
 
+#include "CachedResourceInitiatorTypeNames.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/MediaList.h"
 #include "core/css/StyleSheetContents.h"
@@ -29,7 +30,6 @@
 #include "core/loader/cache/CachedCSSStyleSheet.h"
 #include "core/loader/cache/CachedResourceLoader.h"
 #include "core/loader/cache/CachedResourceRequest.h"
-#include "core/loader/cache/CachedResourceRequestInitiators.h"
 #include "core/loader/cache/CachedXSLStyleSheet.h"
 #include "core/xml/XSLStyleSheet.h"
 #include "core/xml/parser/XMLDocumentParser.h" // for parseAttributes()
@@ -90,7 +90,7 @@
     return m_data;
 }
 
-void ProcessingInstruction::setNodeValue(const String& nodeValue, ExceptionCode& ec)
+void ProcessingInstruction::setNodeValue(const String& nodeValue)
 {
     setData(nodeValue);
 }
@@ -154,7 +154,7 @@
             m_loading = true;
             document()->styleSheetCollection()->addPendingSheet();
             
-            CachedResourceRequest request(ResourceRequest(document()->completeURL(href)), cachedResourceRequestInitiators().processinginstruction);
+            CachedResourceRequest request(ResourceRequest(document()->completeURL(href)), CachedResourceInitiatorTypeNames::processinginstruction);
             if (m_isXSL)
                 m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(request);
             else
@@ -291,6 +291,8 @@
     
     document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
 
+    RefPtr<StyleSheet> removedSheet = m_sheet;
+
     if (m_sheet) {
         ASSERT(m_sheet->ownerNode() == this);
         m_sheet->clearOwnerNode();
@@ -299,7 +301,7 @@
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
     if (document()->renderer())
-        document()->styleResolverChanged(DeferRecalcStyle);
+        document()->removedStyleSheet(removedSheet.get());
 }
 
 void ProcessingInstruction::finishParsingChildren()
diff --git a/Source/core/dom/ProcessingInstruction.h b/Source/core/dom/ProcessingInstruction.h
index b24b4ef..b1e0c2b 100644
--- a/Source/core/dom/ProcessingInstruction.h
+++ b/Source/core/dom/ProcessingInstruction.h
@@ -57,8 +57,8 @@
     virtual String nodeName() const;
     virtual NodeType nodeType() const;
     virtual String nodeValue() const;
-    virtual void setNodeValue(const String&, ExceptionCode&);
-    virtual PassRefPtr<Node> cloneNode(bool deep);
+    virtual void setNodeValue(const String&);
+    virtual PassRefPtr<Node> cloneNode(bool deep = true);
     virtual bool offsetInCharacters() const;
     virtual int maxCharacterOffset() const;
 
diff --git a/Source/core/dom/Promise.idl b/Source/core/dom/Promise.idl
index 893b8ee..fe9edf0 100644
--- a/Source/core/dom/Promise.idl
+++ b/Source/core/dom/Promise.idl
@@ -28,8 +28,20 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+callback PromiseInit = void (PromiseResolver resolver);
+callback AnyCallback = any (optional any value);
 [
-   CustomConstructor(any init),
+   CustomConstructor(PromiseInit init),
    EnabledAtRuntime=promise
 ] interface Promise {
+   [Custom] Promise then(optional AnyCallback fulfillCallback, optional AnyCallback rejectCallback);
+   [Custom] Promise catch(optional AnyCallback rejectCallback);
+
+   [Custom] static Promise fulfill(any value);
+   [Custom] static Promise resolve(any value);
+   [Custom] static Promise reject(any value);
+
+   [Custom] static Promise _any(any... values);
+   [Custom] static Promise every(any... values);
+   [Custom] static Promise some(any... values);
 };
diff --git a/Source/core/dom/PseudoElement.cpp b/Source/core/dom/PseudoElement.cpp
index 468883b..ebcc455 100644
--- a/Source/core/dom/PseudoElement.cpp
+++ b/Source/core/dom/PseudoElement.cpp
@@ -81,10 +81,13 @@
     Element::attach(context);
 
     RenderObject* renderer = this->renderer();
-    if (!renderer || !renderer->style()->regionThread().isEmpty())
+    if (!renderer)
         return;
-
     RenderStyle* style = renderer->style();
+    if (!style->regionThread().isEmpty())
+        return;
+    if (style->styleType() != BEFORE && style->styleType() != AFTER)
+        return;
     ASSERT(style->contentData());
 
     for (const ContentData* content = style->contentData(); content; content = content->next()) {
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index 0575704..0f2ad66 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -67,7 +67,7 @@
 
 inline bool pseudoElementRendererIsNeeded(const RenderStyle* style)
 {
-    return style && style->display() != NONE && (style->contentData() || !style->regionThread().isEmpty());
+    return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData() || !style->regionThread().isEmpty());
 }
 
 } // namespace
diff --git a/Source/core/dom/QualifiedName.cpp b/Source/core/dom/QualifiedName.cpp
index 6edcf87..79fad2d 100644
--- a/Source/core/dom/QualifiedName.cpp
+++ b/Source/core/dom/QualifiedName.cpp
@@ -32,9 +32,9 @@
 #include "XMLNames.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/WebCoreMemoryInstrumentation.h"
-#include <wtf/Assertions.h>
-#include <wtf/HashSet.h>
-#include <wtf/StaticConstructors.h>
+#include "wtf/Assertions.h"
+#include "wtf/HashSet.h"
+#include "wtf/StaticConstructors.h"
 
 namespace WebCore {
 
@@ -156,12 +156,12 @@
 
 void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
 {
-    new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, AtomicString(name), nameNamespace);
+    new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace);
 }
 
 void createQualifiedName(void* targetAddress, StringImpl* name)
 {
-    new (reinterpret_cast<void*>(targetAddress)) QualifiedName(nullAtom, AtomicString(name), nullAtom);
+    new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom);
 }
 
 }
diff --git a/Source/core/dom/QualifiedName.h b/Source/core/dom/QualifiedName.h
index 3867315..5933fe7 100644
--- a/Source/core/dom/QualifiedName.h
+++ b/Source/core/dom/QualifiedName.h
@@ -21,10 +21,10 @@
 #ifndef QualifiedName_h
 #define QualifiedName_h
 
-#include <wtf/Forward.h>
-#include <wtf/HashTraits.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/Forward.h"
+#include "wtf/HashTraits.h"
+#include "wtf/RefCounted.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 15a10d0..f0c4659 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -44,10 +44,10 @@
 #include "core/platform/graphics/FloatQuad.h"
 #include "core/rendering/RenderBoxModelObject.h"
 #include "core/rendering/RenderText.h"
-#include <wtf/RefCountedLeakCounter.h>
-#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
-#include <wtf/Vector.h>
+#include "wtf/RefCountedLeakCounter.h"
+#include "wtf/Vector.h"
+#include "wtf/text/CString.h"
+#include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
@@ -131,7 +131,7 @@
 Node* Range::startContainer(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -141,7 +141,7 @@
 int Range::startOffset(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -151,7 +151,7 @@
 Node* Range::endContainer(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -161,7 +161,7 @@
 int Range::endOffset(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -171,7 +171,7 @@
 Node* Range::commonAncestorContainer(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -192,7 +192,7 @@
 bool Range::collapsed(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -214,12 +214,12 @@
 void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -243,12 +243,12 @@
 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -284,7 +284,7 @@
 void Range::collapse(bool toStart, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
@@ -297,12 +297,12 @@
 bool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return false;
     }
 
     if (!refNode) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return false;
     }
 
@@ -326,17 +326,17 @@
     // refNode node and an offset within the node is before, same as, or after the range respectively.
 
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
     if (!refNode) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return 0;
     }
 
     if (!refNode->attached() || refNode->document() != m_ownerDocument) {
-        ec = WRONG_DOCUMENT_ERR;
+        ec = WrongDocumentError;
         return 0;
     }
 
@@ -367,12 +367,12 @@
     // before and after(surrounds), or inside the range, respectively
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return NODE_BEFORE;
     }
     
     if (!m_start.container() && refNode->attached()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return NODE_BEFORE;
     }
 
@@ -392,7 +392,7 @@
     if (!parentNode) {
         // if the node is the top document we should return NODE_BEFORE_AND_AFTER
         // but we throw to match firefox behavior
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return NODE_BEFORE;
     }
 
@@ -410,12 +410,12 @@
 short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
     if (!sourceRange) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return 0;
     }
 
@@ -428,7 +428,7 @@
         return 0;
 
     if (thisCont->document() != sourceCont->document()) {
-        ec = WRONG_DOCUMENT_ERR;
+        ec = WrongDocumentError;
         return 0;
     }
 
@@ -439,7 +439,7 @@
     while (sourceTop->parentNode())
         sourceTop = sourceTop->parentNode();
     if (thisTop != sourceTop) { // in different DocumentFragments
-        ec = WRONG_DOCUMENT_ERR;
+        ec = WrongDocumentError;
         return 0;
     }
 
@@ -454,7 +454,7 @@
             return compareBoundaryPoints(m_start, sourceRange->m_end, ec);
     }
 
-    ec = SYNTAX_ERR;
+    ec = SyntaxError;
     return 0;
 }
 
@@ -520,7 +520,7 @@
     // ### we need to do a traversal here instead
     Node* commonAncestor = commonAncestorContainer(containerA, containerB);
     if (!commonAncestor) {
-        ec = WRONG_DOCUMENT_ERR;
+        ec = WrongDocumentError;
         return 0;
     }
     Node* childA = containerA;
@@ -578,11 +578,11 @@
 
     // Throw exception if the range is already detached.
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return false;
     }
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return false;
     }
 
@@ -597,7 +597,7 @@
     if (!parentNode) {
         // if the node is the top document we should return NODE_BEFORE_AND_AFTER
         // but we throw to match firefox behavior
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return false;
     }
 
@@ -937,7 +937,7 @@
 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -951,22 +951,22 @@
     ec = 0;
 
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!newNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
-    // HIERARCHY_REQUEST_ERR: Raised if the container of the start of the Range is of a type that
+    // HierarchyRequestError: Raised if the container of the start of the Range is of a type that
     // does not allow children of the type of newNode or if newNode is an ancestor of the container.
 
     // an extra one here - if a text node is going to split, it must have a parent to insert into
     bool startIsText = m_start.container()->isTextNode();
     if (startIsText && !m_start.container()->parentNode()) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return;
     }
 
@@ -985,7 +985,7 @@
         numNewChildren = 0;
         for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {
             if (!checkAgainst->childTypeAllowed(c->nodeType())) {
-                ec = HIERARCHY_REQUEST_ERR;
+                ec = HierarchyRequestError;
                 return;
             }
             ++numNewChildren;
@@ -993,29 +993,29 @@
     } else {
         numNewChildren = 1;
         if (!checkAgainst->childTypeAllowed(newNodeType)) {
-            ec = HIERARCHY_REQUEST_ERR;
+            ec = HierarchyRequestError;
             return;
         }
     }
 
     for (Node* n = m_start.container(); n; n = n->parentNode()) {
         if (n == newNode) {
-            ec = HIERARCHY_REQUEST_ERR;
+            ec = HierarchyRequestError;
             return;
         }
     }
 
-    // INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, Notation, ShadowRoot or Document node.
+    // InvalidNodeTypeError: Raised if newNode is an Attr, Entity, Notation, ShadowRoot or Document node.
     switch (newNodeType) {
     case Node::ATTRIBUTE_NODE:
     case Node::ENTITY_NODE:
     case Node::NOTATION_NODE:
     case Node::DOCUMENT_NODE:
-        ec = INVALID_NODE_TYPE_ERR;
+        ec = InvalidNodeTypeError;
         return;
     default:
         if (newNode->isShadowRoot()) {
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return;
         }
         break;
@@ -1056,7 +1056,7 @@
 String Range::toString(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return String();
     }
 
@@ -1096,13 +1096,13 @@
 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
     Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
     if (!element || !element->isHTMLElement()) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return 0;
     }
 
@@ -1118,7 +1118,7 @@
 {
     // Check first to see if we've already detached:
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
@@ -1134,17 +1134,17 @@
         case Node::DOCUMENT_TYPE_NODE:
         case Node::ENTITY_NODE:
         case Node::NOTATION_NODE:
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return 0;
         case Node::CDATA_SECTION_NODE:
         case Node::COMMENT_NODE:
         case Node::TEXT_NODE:
             if (static_cast<unsigned>(offset) > static_cast<CharacterData*>(n)->length())
-                ec = INDEX_SIZE_ERR;
+                ec = IndexSizeError;
             return 0;
         case Node::PROCESSING_INSTRUCTION_NODE:
             if (static_cast<unsigned>(offset) > static_cast<ProcessingInstruction*>(n)->data().length())
-                ec = INDEX_SIZE_ERR;
+                ec = IndexSizeError;
             return 0;
         case Node::ATTRIBUTE_NODE:
         case Node::DOCUMENT_FRAGMENT_NODE:
@@ -1155,7 +1155,7 @@
                 return 0;
             Node* childBefore = n->childNode(offset - 1);
             if (!childBefore)
-                ec = INDEX_SIZE_ERR;
+                ec = IndexSizeError;
             return childBefore;
         }
     }
@@ -1165,7 +1165,7 @@
 
 void Range::checkNodeBA(Node* n, ExceptionCode& ec) const
 {
-    // INVALID_NODE_TYPE_ERR: Raised if the root container of refNode is not an
+    // InvalidNodeTypeError: Raised if the root container of refNode is not an
     // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG shadow DOM tree,
     // or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation node.
 
@@ -1175,7 +1175,7 @@
         case Node::DOCUMENT_NODE:
         case Node::ENTITY_NODE:
         case Node::NOTATION_NODE:
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return;
         case Node::CDATA_SECTION_NODE:
         case Node::COMMENT_NODE:
@@ -1205,7 +1205,7 @@
         case Node::PROCESSING_INSTRUCTION_NODE:
         case Node::TEXT_NODE:
         case Node::XPATH_NAMESPACE_NODE:
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return;
     }
 }
@@ -1213,7 +1213,7 @@
 PassRefPtr<Range> Range::cloneRange(ExceptionCode& ec) const
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return 0;
     }
 
@@ -1223,12 +1223,12 @@
 void Range::setStartAfter(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -1243,12 +1243,12 @@
 void Range::setEndBefore(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -1263,12 +1263,12 @@
 void Range::setEndAfter(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -1283,16 +1283,16 @@
 void Range::selectNode(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
-    // INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode is an Entity, Notation or
+    // InvalidNodeTypeError: Raised if an ancestor of refNode is an Entity, Notation or
     // DocumentType node or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation
     // node.
     for (ContainerNode* anc = refNode->parentNode(); anc; anc = anc->parentNode()) {
@@ -1310,7 +1310,7 @@
             case Node::DOCUMENT_TYPE_NODE:
             case Node::ENTITY_NODE:
             case Node::NOTATION_NODE:
-                ec = INVALID_NODE_TYPE_ERR;
+                ec = InvalidNodeTypeError;
                 return;
         }
     }
@@ -1329,7 +1329,7 @@
         case Node::DOCUMENT_NODE:
         case Node::ENTITY_NODE:
         case Node::NOTATION_NODE:
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return;
     }
 
@@ -1346,16 +1346,16 @@
 void Range::selectNodeContents(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
-    // INVALID_NODE_TYPE_ERR: Raised if refNode or an ancestor of refNode is an Entity, Notation
+    // InvalidNodeTypeError: Raised if refNode or an ancestor of refNode is an Entity, Notation
     // or DocumentType node.
     for (Node* n = refNode; n; n = n->parentNode()) {
         switch (n->nodeType()) {
@@ -1372,7 +1372,7 @@
             case Node::DOCUMENT_TYPE_NODE:
             case Node::ENTITY_NODE:
             case Node::NOTATION_NODE:
-                ec = INVALID_NODE_TYPE_ERR;
+                ec = InvalidNodeTypeError;
                 return;
         }
     }
@@ -1389,16 +1389,16 @@
     RefPtr<Node> newParent = passNewParent;
 
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!newParent) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
-    // INVALID_NODE_TYPE_ERR: Raised if node is an Attr, Entity, DocumentType, Notation,
+    // InvalidNodeTypeError: Raised if node is an Attr, Entity, DocumentType, Notation,
     // Document, or DocumentFragment node.
     switch (newParent->nodeType()) {
         case Node::ATTRIBUTE_NODE:
@@ -1407,7 +1407,7 @@
         case Node::DOCUMENT_TYPE_NODE:
         case Node::ENTITY_NODE:
         case Node::NOTATION_NODE:
-            ec = INVALID_NODE_TYPE_ERR;
+            ec = InvalidNodeTypeError;
             return;
         case Node::CDATA_SECTION_NODE:
         case Node::COMMENT_NODE:
@@ -1418,7 +1418,7 @@
             break;
     }
 
-    // Raise a HIERARCHY_REQUEST_ERR if m_start.container() doesn't accept children like newParent.
+    // Raise a HierarchyRequestError if m_start.container() doesn't accept children like newParent.
     Node* parentOfNewParent = m_start.container();
 
     // If m_start.container() is a character data node, it will be split and it will be its parent that will 
@@ -1427,12 +1427,12 @@
     if (parentOfNewParent->isCharacterDataNode())
         parentOfNewParent = parentOfNewParent->parentNode();
     if (!parentOfNewParent || !parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return;
     }
     
     if (newParent->contains(m_start.container())) {
-        ec = HIERARCHY_REQUEST_ERR;
+        ec = HierarchyRequestError;
         return;
     }
 
@@ -1447,7 +1447,7 @@
     if (endNonTextContainer->nodeType() == Node::TEXT_NODE)
         endNonTextContainer = endNonTextContainer->parentNode();
     if (startNonTextContainer != endNonTextContainer) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
@@ -1472,12 +1472,12 @@
 void Range::setStartBefore(Node* refNode, ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
     if (!refNode) {
-        ec = NOT_FOUND_ERR;
+        ec = NotFoundError;
         return;
     }
 
@@ -1492,7 +1492,7 @@
 void Range::checkDeleteExtract(ExceptionCode& ec)
 {
     if (!m_start.container()) {
-        ec = INVALID_STATE_ERR;
+        ec = InvalidStateError;
         return;
     }
 
@@ -1503,7 +1503,7 @@
     Node* pastLast = pastLastNode();
     for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) {
         if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) {
-            ec = HIERARCHY_REQUEST_ERR;
+            ec = HierarchyRequestError;
             return;
         }
     }
diff --git a/Source/core/dom/RegisteredEventListener.h b/Source/core/dom/RegisteredEventListener.h
index 1da01e6..23a718a 100644
--- a/Source/core/dom/RegisteredEventListener.h
+++ b/Source/core/dom/RegisteredEventListener.h
@@ -25,7 +25,7 @@
 #define RegisteredEventListener_h
 
 #include "core/dom/EventListener.h"
-#include <wtf/RefPtr.h>
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/RequestAnimationFrameCallback.h b/Source/core/dom/RequestAnimationFrameCallback.h
index 52580dc..768e4a1 100644
--- a/Source/core/dom/RequestAnimationFrameCallback.h
+++ b/Source/core/dom/RequestAnimationFrameCallback.h
@@ -31,7 +31,7 @@
 #ifndef RequestAnimationFrameCallback_h
 #define RequestAnimationFrameCallback_h
 
-#include <wtf/RefCounted.h>
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ScopedEventQueue.cpp b/Source/core/dom/ScopedEventQueue.cpp
index 3889936..8072c59 100644
--- a/Source/core/dom/ScopedEventQueue.cpp
+++ b/Source/core/dom/ScopedEventQueue.cpp
@@ -35,8 +35,8 @@
 #include "core/dom/EventDispatchMediator.h"
 #include "core/dom/EventDispatcher.h"
 #include "core/dom/EventTarget.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/RefPtr.h>
+#include "wtf/OwnPtr.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ScopedEventQueue.h b/Source/core/dom/ScopedEventQueue.h
index 262f6a9..4f3c928 100644
--- a/Source/core/dom/ScopedEventQueue.h
+++ b/Source/core/dom/ScopedEventQueue.h
@@ -31,10 +31,10 @@
 #ifndef ScopedEventQueue_h
 #define ScopedEventQueue_h
 
-#include <wtf/Noncopyable.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ScriptElement.cpp b/Source/core/dom/ScriptLoader.cpp
similarity index 73%
rename from Source/core/dom/ScriptElement.cpp
rename to Source/core/dom/ScriptLoader.cpp
index 94018c1..e42b6c3 100644
--- a/Source/core/dom/ScriptElement.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -22,7 +22,7 @@
  */
 
 #include "config.h"
-#include "core/dom/ScriptElement.h"
+#include "core/dom/ScriptLoader.h"
 
 #include "HTMLNames.h"
 #include "SVGNames.h"
@@ -31,6 +31,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/Event.h"
 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
+#include "core/dom/ScriptLoaderClient.h"
 #include "core/dom/ScriptRunner.h"
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/Text.h"
@@ -51,7 +52,7 @@
 
 namespace WebCore {
 
-ScriptElement::ScriptElement(Element* element, bool parserInserted, bool alreadyStarted)
+ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadyStarted)
     : m_element(element)
     , m_cachedScript(0)
     , m_startLineNumber(WTF::OrdinalNumber::beforeFirst())
@@ -66,28 +67,28 @@
     , m_willExecuteInOrder(false)
 {
     ASSERT(m_element);
-    if (parserInserted && m_element->document()->scriptableDocumentParser() && !m_element->document()->isInDocumentWrite())
-        m_startLineNumber = m_element->document()->scriptableDocumentParser()->lineNumber();
+    if (parserInserted && element->document()->scriptableDocumentParser() && !element->document()->isInDocumentWrite())
+        m_startLineNumber = element->document()->scriptableDocumentParser()->lineNumber();
 }
 
-ScriptElement::~ScriptElement()
+ScriptLoader::~ScriptLoader()
 {
     stopLoadRequest();
 }
 
-void ScriptElement::insertedInto(ContainerNode* insertionPoint)
+void ScriptLoader::insertedInto(ContainerNode* insertionPoint)
 {
     if (insertionPoint->inDocument() && !m_parserInserted)
         prepareScript(); // FIXME: Provide a real starting line number here.
 }
 
-void ScriptElement::childrenChanged()
+void ScriptLoader::childrenChanged()
 {
     if (!m_parserInserted && m_element->inDocument())
         prepareScript(); // FIXME: Provide a real starting line number here.
 }
 
-void ScriptElement::handleSourceAttribute(const String& sourceUrl)
+void ScriptLoader::handleSourceAttribute(const String& sourceUrl)
 {
     if (ignoresLoadRequest() || sourceUrl.isEmpty())
         return;
@@ -95,7 +96,7 @@
     prepareScript(); // FIXME: Provide a real starting line number here.
 }
 
-void ScriptElement::handleAsyncAttribute()
+void ScriptLoader::handleAsyncAttribute()
 {
     m_forceAsync = false;
 }
@@ -131,48 +132,60 @@
     return languages.contains(language);
 }
 
-void ScriptElement::dispatchErrorEvent()
+void ScriptLoader::dispatchErrorEvent()
 {
     m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
 }
 
-bool ScriptElement::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
+void ScriptLoader::dispatchLoadEvent()
+{
+    if (ScriptLoaderClient* client = this->client())
+        client->dispatchLoadEvent();
+    setHaveFiredLoadEvent(true);
+}
+
+bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) const
 {
     // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used here to maintain backwards compatibility with existing layout tests. The specific violations are:
     // - Allowing type=javascript. type= should only support MIME types, such as text/javascript.
     // - Allowing a different set of languages for language= and type=. language= supports Javascript 1.1 and 1.4-1.6, but type= does not.
 
-    String type = typeAttributeValue();
-    String language = languageAttributeValue();
+    String type = client()->typeAttributeValue();
+    String language = client()->languageAttributeValue();
     if (type.isEmpty() && language.isEmpty())
         return true; // Assume text/javascript.
     if (type.isEmpty()) {
         type = "text/" + language.lower();
         if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
             return true;
-    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type)))
+    } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
         return true;
+    }
+
     return false;
 }
 
 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script
-bool ScriptElement::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes)
+bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes)
 {
     if (m_alreadyStarted)
         return false;
 
+    ScriptLoaderClient* client = this->client();
+
     bool wasParserInserted;
     if (m_parserInserted) {
         wasParserInserted = true;
         m_parserInserted = false;
-    } else
+    } else {
         wasParserInserted = false;
+    }
 
-    if (wasParserInserted && !asyncAttributeValue())
+    if (wasParserInserted && !client->asyncAttributeValue())
         m_forceAsync = true;
 
     // FIXME: HTML5 spec says we should check that all children are either comments or empty text nodes.
-    if (!hasSourceAttribute() && !m_element->firstChild())
+    if (!client->hasSourceAttribute() && !m_element->firstChild())
         return false;
 
     if (!m_element->inDocument())
@@ -203,29 +216,30 @@
     if (!isScriptForEventSupported())
         return false;
 
-    if (!charsetAttributeValue().isEmpty())
-        m_characterEncoding = charsetAttributeValue();
+    if (!client->charsetAttributeValue().isEmpty())
+        m_characterEncoding = client->charsetAttributeValue();
     else
         m_characterEncoding = document->charset();
 
-    if (hasSourceAttribute())
-        if (!requestScript(sourceAttributeValue()))
+    if (client->hasSourceAttribute()) {
+        if (!requestScript(client->sourceAttributeValue()))
             return false;
+    }
 
-    if (hasSourceAttribute() && deferAttributeValue() && m_parserInserted && !asyncAttributeValue()) {
+    if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parserInserted && !client->asyncAttributeValue()) {
         m_willExecuteWhenDocumentFinishedParsing = true;
         m_willBeParserExecuted = true;
-    } else if (hasSourceAttribute() && m_parserInserted && !asyncAttributeValue())
+    } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) {
         m_willBeParserExecuted = true;
-    else if (!hasSourceAttribute() && m_parserInserted && !document->haveStylesheetsAndImportsLoaded()) {
+    } else if (!client->hasSourceAttribute() && m_parserInserted && !document->haveStylesheetsAndImportsLoaded()) {
         m_willBeParserExecuted = true;
         m_readyToBeParserExecuted = true;
-    } else if (hasSourceAttribute() && !asyncAttributeValue() && !m_forceAsync) {
+    } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
         m_willExecuteInOrder = true;
         document->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::IN_ORDER_EXECUTION);
         m_cachedScript->addClient(this);
-    } else if (hasSourceAttribute()) {
-        m_element->document()->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::ASYNC_EXECUTION);
+    } else if (client->hasSourceAttribute()) {
+        document->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::ASYNC_EXECUTION);
         m_cachedScript->addClient(this);
     } else {
         // Reset line numbering for nested writes.
@@ -237,8 +251,10 @@
     return true;
 }
 
-bool ScriptElement::requestScript(const String& sourceUrl)
+bool ScriptLoader::requestScript(const String& sourceUrl)
 {
+    ASSERT(m_element);
+
     RefPtr<Document> originalDocument = m_element->document();
     if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
         return false;
@@ -247,7 +263,7 @@
 
     ASSERT(!m_cachedScript);
     if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
-        CachedResourceRequest request(ResourceRequest(m_element->document()->completeURL(sourceUrl)), element()->localName());
+        CachedResourceRequest request(ResourceRequest(m_element->document()->completeURL(sourceUrl)), m_element->localName());
 
         String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
         if (!crossOriginMode.isNull()) {
@@ -272,17 +288,17 @@
     return false;
 }
 
-bool isHTMLScriptElement(Element* element)
+bool isHTMLScriptLoader(Element* element)
 {
     return element->hasTagName(HTMLNames::scriptTag);
 }
 
-bool isSVGScriptElement(Element* element)
+bool isSVGScriptLoader(Element* element)
 {
     return element->hasTagName(SVGNames::scriptTag);
 }
 
-void ScriptElement::executeScript(const ScriptSourceCode& sourceCode)
+void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
 {
     ASSERT(m_alreadyStarted);
 
@@ -303,26 +319,24 @@
     }
 
     if (frame) {
-        {
-            IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.get() : 0);
+        IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.get() : 0);
 
-            if (isHTMLScriptElement(m_element))
-                document->pushCurrentScript(toHTMLScriptElement(m_element));
+        if (isHTMLScriptLoader(m_element))
+            document->pushCurrentScript(toHTMLScriptElement(m_element));
 
-            // Create a script from the script element node, using the script
-            // block's source and the script block's type.
-            // Note: This is where the script is compiled and actually executed.
-            frame->script()->executeScriptInMainWorld(sourceCode);
+        // Create a script from the script element node, using the script
+        // block's source and the script block's type.
+        // Note: This is where the script is compiled and actually executed.
+        frame->script()->executeScriptInMainWorld(sourceCode);
 
-            if (isHTMLScriptElement(m_element)) {
-                ASSERT(document->currentScript() == m_element);
-                document->popCurrentScript();
-            }
+        if (isHTMLScriptLoader(m_element)) {
+            ASSERT(document->currentScript() == m_element);
+            document->popCurrentScript();
         }
     }
 }
 
-void ScriptElement::stopLoadRequest()
+void ScriptLoader::stopLoadRequest()
 {
     if (m_cachedScript) {
         if (!m_willBeParserExecuted)
@@ -331,25 +345,25 @@
     }
 }
 
-void ScriptElement::execute(CachedScript* cachedScript)
+void ScriptLoader::execute(CachedScript* cachedScript)
 {
     ASSERT(!m_willBeParserExecuted);
     ASSERT(cachedScript);
-    if (cachedScript->errorOccurred())
+    if (cachedScript->errorOccurred()) {
         dispatchErrorEvent();
-    else if (!cachedScript->wasCanceled()) {
+    } else if (!cachedScript->wasCanceled()) {
         executeScript(ScriptSourceCode(cachedScript));
         dispatchLoadEvent();
     }
     cachedScript->removeClient(this);
 }
 
-void ScriptElement::notifyFinished(CachedResource* resource)
+void ScriptLoader::notifyFinished(CachedResource* resource)
 {
     ASSERT(!m_willBeParserExecuted);
 
     // CachedResource possibly invokes this notifyFinished() more than
-    // once because ScriptElement doesn't unsubscribe itself from
+    // once because ScriptLoader doesn't unsubscribe itself from
     // CachedResource here and does it in execute() instead.
     // We use m_cachedScript to check if this function is already called.
     ASSERT_UNUSED(resource, resource == m_cachedScript);
@@ -368,15 +382,15 @@
     m_cachedScript = 0;
 }
 
-bool ScriptElement::ignoresLoadRequest() const
+bool ScriptLoader::ignoresLoadRequest() const
 {
-    return m_alreadyStarted || m_isExternalScript || m_parserInserted || !m_element->inDocument();
+    return m_alreadyStarted || m_isExternalScript || m_parserInserted || !element() || !element()->inDocument();
 }
 
-bool ScriptElement::isScriptForEventSupported() const
+bool ScriptLoader::isScriptForEventSupported() const
 {
-    String eventAttribute = eventAttributeValue();
-    String forAttribute = forAttributeValue();
+    String eventAttribute = client()->eventAttributeValue();
+    String forAttribute = client()->forAttributeValue();
     if (!eventAttribute.isEmpty() && !forAttribute.isEmpty()) {
         forAttribute = forAttribute.stripWhiteSpace();
         if (!equalIgnoringCase(forAttribute, "window"))
@@ -389,18 +403,30 @@
     return true;
 }
 
-String ScriptElement::scriptContent() const
+String ScriptLoader::scriptContent() const
 {
     return m_element->textFromChildren();
 }
 
-ScriptElement* toScriptElementIfPossible(Element* element)
+ScriptLoaderClient* ScriptLoader::client() const
 {
-    if (isHTMLScriptElement(element))
-        return toHTMLScriptElement(element);
+    if (isHTMLScriptLoader(m_element))
+        return toHTMLScriptElement(m_element);
 
-    if (isSVGScriptElement(element))
-        return toSVGScriptElement(element);
+    if (isSVGScriptLoader(m_element))
+        return toSVGScriptElement(m_element);
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+ScriptLoader* toScriptLoaderIfPossible(Element* element)
+{
+    if (isHTMLScriptLoader(element))
+        return toHTMLScriptElement(element)->loader();
+
+    if (isSVGScriptLoader(element))
+        return toSVGScriptElement(element)->loader();
 
     return 0;
 }
diff --git a/Source/core/dom/ScriptElement.h b/Source/core/dom/ScriptLoader.h
similarity index 78%
rename from Source/core/dom/ScriptElement.h
rename to Source/core/dom/ScriptLoader.h
index 32a011d..55fb167 100644
--- a/Source/core/dom/ScriptElement.h
+++ b/Source/core/dom/ScriptLoader.h
@@ -18,26 +18,27 @@
  *
  */
 
-#ifndef ScriptElement_h
-#define ScriptElement_h
+#ifndef ScriptLoader_h
+#define ScriptLoader_h
 
 #include "core/loader/cache/CachedResourceClient.h"
 #include "core/loader/cache/CachedResourceHandle.h"
-#include <wtf/text/TextPosition.h>
-#include <wtf/text/WTFString.h>
+#include "wtf/text/TextPosition.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
 class CachedScript;
 class ContainerNode;
 class Element;
-class ScriptElement;
+class ScriptLoaderClient;
 class ScriptSourceCode;
 
-class ScriptElement : private CachedResourceClient {
+
+class ScriptLoader : private CachedResourceClient {
 public:
-    ScriptElement(Element*, bool createdByParser, bool isEvaluated);
-    virtual ~ScriptElement();
+    static PassOwnPtr<ScriptLoader> create(Element*, bool createdByParser, bool isEvaluated);
+    virtual ~ScriptLoader();
 
     Element* element() const { return m_element; }
 
@@ -50,7 +51,7 @@
     void execute(CachedScript*);
 
     // XML parser calls these
-    virtual void dispatchLoadEvent() = 0;
+    void dispatchLoadEvent();
     void dispatchErrorEvent();
     bool isScriptTypeSupported(LegacyTypeSupport) const;
 
@@ -60,7 +61,6 @@
     bool willExecuteWhenDocumentFinishedParsing() const { return m_willExecuteWhenDocumentFinishedParsing; }
     CachedResourceHandle<CachedScript> cachedScript() { return m_cachedScript; }
 
-protected:
     void setHaveFiredLoadEvent(bool haveFiredLoad) { m_haveFiredLoad = haveFiredLoad; }
     bool isParserInserted() const { return m_parserInserted; }
     bool alreadyStarted() const { return m_alreadyStarted; }
@@ -73,23 +73,18 @@
     void handleAsyncAttribute();
 
 private:
+    ScriptLoader(Element*, bool createdByParser, bool isEvaluated);
+
     bool ignoresLoadRequest() const;
     bool isScriptForEventSupported() const;
 
     bool requestScript(const String& sourceUrl);
     void stopLoadRequest();
 
-    virtual void notifyFinished(CachedResource*);
+    ScriptLoaderClient* client() const;
 
-    virtual String sourceAttributeValue() const = 0;
-    virtual String charsetAttributeValue() const = 0;
-    virtual String typeAttributeValue() const = 0;
-    virtual String languageAttributeValue() const = 0;
-    virtual String forAttributeValue() const = 0;
-    virtual String eventAttributeValue() const = 0;
-    virtual bool asyncAttributeValue() const = 0;
-    virtual bool deferAttributeValue() const = 0;
-    virtual bool hasSourceAttribute() const = 0;
+    // CachedResourceClient
+    virtual void notifyFinished(CachedResource*) OVERRIDE;
 
     Element* m_element;
     CachedResourceHandle<CachedScript> m_cachedScript;
@@ -107,8 +102,14 @@
     String m_fallbackCharacterEncoding;
 };
 
-ScriptElement* toScriptElementIfPossible(Element*);
+ScriptLoader* toScriptLoaderIfPossible(Element*);
+
+inline PassOwnPtr<ScriptLoader> ScriptLoader::create(Element* element, bool createdByParser, bool isEvaluated)
+{
+    return adoptPtr(new ScriptLoader(element, createdByParser, isEvaluated));
+}
 
 }
 
+
 #endif
diff --git a/Source/core/dom/ScriptLoaderClient.h b/Source/core/dom/ScriptLoaderClient.h
new file mode 100644
index 0000000..7ca9d74
--- /dev/null
+++ b/Source/core/dom/ScriptLoaderClient.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef ScriptLoaderClient_h
+#define ScriptLoaderClient_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ScriptLoaderClient {
+public:
+    virtual ~ScriptLoaderClient() { }
+
+    virtual void dispatchLoadEvent() = 0;
+
+    virtual String sourceAttributeValue() const = 0;
+    virtual String charsetAttributeValue() const = 0;
+    virtual String typeAttributeValue() const = 0;
+    virtual String languageAttributeValue() const = 0;
+    virtual String forAttributeValue() const = 0;
+    virtual String eventAttributeValue() const = 0;
+    virtual bool asyncAttributeValue() const = 0;
+    virtual bool deferAttributeValue() const = 0;
+    virtual bool hasSourceAttribute() const = 0;
+};
+
+}
+
+#endif
diff --git a/Source/core/dom/ScriptRunner.cpp b/Source/core/dom/ScriptRunner.cpp
index 706a1d1..db5f7a5 100644
--- a/Source/core/dom/ScriptRunner.cpp
+++ b/Source/core/dom/ScriptRunner.cpp
@@ -29,7 +29,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/PendingScript.h"
-#include "core/dom/ScriptElement.h"
+#include "core/dom/ScriptLoader.h"
 #include "core/loader/cache/CachedScript.h"
 
 namespace WebCore {
@@ -51,12 +51,12 @@
         m_document->decrementLoadEventDelayCount();
 }
 
-void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType)
+void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType)
 {
-    ASSERT(scriptElement);
+    ASSERT(scriptLoader);
     ASSERT(cachedScript.get());
 
-    Element* element = scriptElement->element();
+    Element* element = scriptLoader->element();
     ASSERT(element);
     ASSERT(element->inDocument());
 
@@ -64,7 +64,7 @@
 
     switch (executionType) {
     case ASYNC_EXECUTION:
-        m_pendingAsyncScripts.add(scriptElement, PendingScript(element, cachedScript.get()));
+        m_pendingAsyncScripts.add(scriptLoader, PendingScript(element, cachedScript.get()));
         break;
 
     case IN_ORDER_EXECUTION:
@@ -84,12 +84,12 @@
         m_timer.startOneShot(0);
 }
 
-void ScriptRunner::notifyScriptReady(ScriptElement* scriptElement, ExecutionType executionType)
+void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType executionType)
 {
     switch (executionType) {
     case ASYNC_EXECUTION:
-        ASSERT(m_pendingAsyncScripts.contains(scriptElement));
-        m_scriptsToExecuteSoon.append(m_pendingAsyncScripts.take(scriptElement));
+        ASSERT(m_pendingAsyncScripts.contains(scriptLoader));
+        m_scriptsToExecuteSoon.append(m_pendingAsyncScripts.take(scriptLoader));
         break;
 
     case IN_ORDER_EXECUTION:
@@ -118,7 +118,7 @@
     for (size_t i = 0; i < size; ++i) {
         CachedScript* cachedScript = scripts[i].cachedScript();
         RefPtr<Element> element = scripts[i].releaseElementAndClear();
-        toScriptElementIfPossible(element.get())->execute(cachedScript);
+        toScriptLoaderIfPossible(element.get())->execute(cachedScript);
         m_document->decrementLoadEventDelayCount();
     }
 }
diff --git a/Source/core/dom/ScriptRunner.h b/Source/core/dom/ScriptRunner.h
index 1790764..6cbb2b9 100644
--- a/Source/core/dom/ScriptRunner.h
+++ b/Source/core/dom/ScriptRunner.h
@@ -38,7 +38,7 @@
 class CachedScript;
 class Document;
 class PendingScript;
-class ScriptElement;
+class ScriptLoader;
 
 class ScriptRunner {
     WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
@@ -47,11 +47,11 @@
     ~ScriptRunner();
 
     enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
-    void queueScriptForExecution(ScriptElement*, CachedResourceHandle<CachedScript>, ExecutionType);
+    void queueScriptForExecution(ScriptLoader*, CachedResourceHandle<CachedScript>, ExecutionType);
     bool hasPendingScripts() const { return !m_scriptsToExecuteSoon.isEmpty() || !m_scriptsToExecuteInOrder.isEmpty() || !m_pendingAsyncScripts.isEmpty(); }
     void suspend();
     void resume();
-    void notifyScriptReady(ScriptElement*, ExecutionType);
+    void notifyScriptReady(ScriptLoader*, ExecutionType);
 
 private:
     explicit ScriptRunner(Document*);
@@ -61,7 +61,7 @@
     Document* m_document;
     Vector<PendingScript> m_scriptsToExecuteInOrder;
     Vector<PendingScript> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
-    HashMap<ScriptElement*, PendingScript> m_pendingAsyncScripts;
+    HashMap<ScriptLoader*, PendingScript> m_pendingAsyncScripts;
     Timer<ScriptRunner> m_timer;
 };
 
diff --git a/Source/core/dom/ScriptableDocumentParser.h b/Source/core/dom/ScriptableDocumentParser.h
index f8a95ad..e40e8dd 100644
--- a/Source/core/dom/ScriptableDocumentParser.h
+++ b/Source/core/dom/ScriptableDocumentParser.h
@@ -28,7 +28,7 @@
 
 #include "core/dom/DecodedDataDocumentParser.h"
 #include "core/dom/ParserContentPolicy.h"
-#include <wtf/text/TextPosition.h>
+#include "wtf/text/TextPosition.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/SecurityContext.cpp b/Source/core/dom/SecurityContext.cpp
index 80fcaba..c40d60c 100644
--- a/Source/core/dom/SecurityContext.cpp
+++ b/Source/core/dom/SecurityContext.cpp
@@ -27,11 +27,11 @@
 #include "config.h"
 #include "core/dom/SecurityContext.h"
 
-#include <wtf/text/StringBuilder.h>
 #include "core/dom/WebCoreMemoryInstrumentation.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/page/ContentSecurityPolicy.h"
 #include "weborigin/SecurityOrigin.h"
+#include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/SecurityContext.h b/Source/core/dom/SecurityContext.h
index 61f0e6a..9685aea 100644
--- a/Source/core/dom/SecurityContext.h
+++ b/Source/core/dom/SecurityContext.h
@@ -27,9 +27,9 @@
 #ifndef SecurityContext_h
 #define SecurityContext_h
 
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/WTFString.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/SecurityPolicyViolationEvent.h b/Source/core/dom/SecurityPolicyViolationEvent.h
index 5915e43..40ff41b 100644
--- a/Source/core/dom/SecurityPolicyViolationEvent.h
+++ b/Source/core/dom/SecurityPolicyViolationEvent.h
@@ -44,6 +44,7 @@
     String sourceFile;
     int lineNumber;
     int columnNumber;
+    int statusCode;
 };
 
 class SecurityPolicyViolationEvent : public Event {
@@ -67,6 +68,7 @@
     const String& sourceFile() const { return m_sourceFile; }
     int lineNumber() const { return m_lineNumber; }
     int columnNumber() const { return m_columnNumber; }
+    int statusCode() const { return m_statusCode; }
 
     virtual const AtomicString& interfaceName() const { return eventNames().interfaceForSecurityPolicyViolationEvent; }
 
@@ -87,6 +89,7 @@
         , m_sourceFile(initializer.sourceFile)
         , m_lineNumber(initializer.lineNumber)
         , m_columnNumber(initializer.columnNumber)
+        , m_statusCode(initializer.statusCode)
     {
         ScriptWrappable::init(this);
     }
@@ -100,6 +103,7 @@
     String m_sourceFile;
     int m_lineNumber;
     int m_columnNumber;
+    int m_statusCode;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/SecurityPolicyViolationEvent.idl b/Source/core/dom/SecurityPolicyViolationEvent.idl
index 528b0cc..8eab91e 100644
--- a/Source/core/dom/SecurityPolicyViolationEvent.idl
+++ b/Source/core/dom/SecurityPolicyViolationEvent.idl
@@ -35,4 +35,5 @@
     [InitializedByEventConstructor] readonly attribute DOMString sourceFile;
     [InitializedByEventConstructor] readonly attribute long      lineNumber;
     [InitializedByEventConstructor] readonly attribute long      columnNumber;
+    [InitializedByEventConstructor] readonly attribute long      statusCode;
 };
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index 32ed0f3..dd04402 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -220,13 +220,13 @@
     parser.parseSelector(selectors, selectorList);
 
     if (!selectorList.first() || selectorList.hasInvalidSelector()) {
-        ec = SYNTAX_ERR;
+        ec = SyntaxError;
         return 0;
     }
 
-    // throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
+    // throw a NamespaceError if the selector includes any namespace prefixes.
     if (selectorList.selectorsNeedNamespaceResolution()) {
-        ec = NAMESPACE_ERR;
+        ec = NamespaceError;
         return 0;
     }
 
diff --git a/Source/core/dom/SelectorQuery.h b/Source/core/dom/SelectorQuery.h
index 79e6381..c3bd41a 100644
--- a/Source/core/dom/SelectorQuery.h
+++ b/Source/core/dom/SelectorQuery.h
@@ -27,9 +27,9 @@
 #define SelectorQuery_h
 
 #include "core/css/CSSSelectorList.h"
-#include <wtf/HashMap.h>
-#include <wtf/text/AtomicStringHash.h>
-#include <wtf/Vector.h>
+#include "wtf/HashMap.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/SpaceSplitString.h b/Source/core/dom/SpaceSplitString.h
index 53b588f..7f9816c 100644
--- a/Source/core/dom/SpaceSplitString.h
+++ b/Source/core/dom/SpaceSplitString.h
@@ -21,9 +21,9 @@
 #ifndef SpaceSplitString_h
 #define SpaceSplitString_h
 
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/StaticNodeList.h b/Source/core/dom/StaticNodeList.h
index 823f48f..ece0926 100644
--- a/Source/core/dom/StaticNodeList.h
+++ b/Source/core/dom/StaticNodeList.h
@@ -30,9 +30,9 @@
 #define StaticNodeList_h
 
 #include "core/dom/NodeList.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/StringCallback.cpp b/Source/core/dom/StringCallback.cpp
index 687821e..092f70e 100644
--- a/Source/core/dom/StringCallback.cpp
+++ b/Source/core/dom/StringCallback.cpp
@@ -32,7 +32,7 @@
 #include "core/dom/StringCallback.h"
 
 #include "core/dom/ScriptExecutionContext.h"
-#include <wtf/text/WTFString.h>
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/StringCallback.h b/Source/core/dom/StringCallback.h
index 92e83e2..e600847 100644
--- a/Source/core/dom/StringCallback.h
+++ b/Source/core/dom/StringCallback.h
@@ -31,8 +31,8 @@
 #ifndef StringCallback_h
 #define StringCallback_h
 
-#include <wtf/Forward.h>
-#include <wtf/RefCounted.h>
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/StyleElement.cpp b/Source/core/dom/StyleElement.cpp
index 83f797b..4ac26c2 100644
--- a/Source/core/dom/StyleElement.cpp
+++ b/Source/core/dom/StyleElement.cpp
@@ -29,8 +29,8 @@
 #include "core/dom/Element.h"
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/page/ContentSecurityPolicy.h"
-#include <wtf/text/StringBuilder.h>
-#include <wtf/text/TextPosition.h>
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/TextPosition.h"
 
 namespace WebCore {
 
@@ -71,12 +71,14 @@
     ASSERT(element);
     document->styleSheetCollection()->removeStyleSheetCandidateNode(element);
 
+    RefPtr<StyleSheet> removedSheet = m_sheet;
+
     if (m_sheet)
         clearSheet();
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
     if (document->renderer())
-        document->styleResolverChanged(DeferRecalcStyle);
+        document->removedStyleSheet(removedSheet.get());
 }
 
 void StyleElement::clearDocumentData(Document* document, Element* element)
@@ -143,7 +145,7 @@
             m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document->inputEncoding());
             m_sheet->setMediaQueries(mediaQueries.release());
             m_sheet->setTitle(e->title());
-            m_sheet->contents()->parseStringAtLine(text, startPosition.m_line.zeroBasedInt(), m_createdByParser);
+            m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser);
 
             m_loading = false;
         }
diff --git a/Source/core/dom/StyleSheetCollection.cpp b/Source/core/dom/StyleSheetCollection.cpp
new file mode 100644
index 0000000..2f3c5b7
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollection.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/StyleSheetCollection.h"
+
+#include "HTMLNames.h"
+#include "SVGNames.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleInvalidationAnalysis.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Document.h"
+#include "core/dom/DocumentStyleSheetCollection.h"
+#include "core/dom/Element.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/dom/WebCoreMemoryInstrumentation.h"
+#include "core/html/HTMLIFrameElement.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+#include "core/page/Page.h"
+#include "core/page/PageGroup.h"
+#include "core/page/Settings.h"
+#include "core/page/UserContentURLPattern.h"
+#include "core/svg/SVGStyleElement.h"
+#include "wtf/MemoryInstrumentationListHashSet.h"
+#include "wtf/MemoryInstrumentationVector.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+StyleSheetCollection::StyleSheetCollection(TreeScope* treeScope)
+    : m_treeScope(treeScope)
+    , m_hadActiveLoadingStylesheet(false)
+{
+}
+
+void StyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+    if (!node->inDocument())
+        return;
+
+    // Until the <body> exists, we have no choice but to compare document positions,
+    // since styles outside of the body and head continue to be shunted into the head
+    // (and thus can shift to end up before dynamically added DOM content that is also
+    // outside the body).
+    if (createdByParser && document()->body()) {
+        m_styleSheetCandidateNodes.parserAdd(node);
+        return;
+    }
+
+    m_styleSheetCandidateNodes.add(node);
+}
+
+void StyleSheetCollection::removeStyleSheetCandidateNode(Node* node)
+{
+    m_styleSheetCandidateNodes.remove(node);
+}
+
+void StyleSheetCollection::collectStyleSheets(DocumentStyleSheetCollection* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
+{
+    if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
+        return;
+
+    DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
+    DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
+    for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
+        Node* n = *it;
+        StyleSheet* sheet = 0;
+        CSSStyleSheet* activeSheet = 0;
+        if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
+            // Processing instruction (XML documents only).
+            // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+            ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
+            // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
+            if (pi->isXSL() && !document()->transformSourceDocument()) {
+                // Don't apply XSL transforms until loading is finished.
+                if (!document()->parsing())
+                    document()->applyXSLTransform(pi);
+                return;
+            }
+            sheet = pi->sheet();
+            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
+                activeSheet = static_cast<CSSStyleSheet*>(sheet);
+        } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
+            Element* e = toElement(n);
+            AtomicString title = e->getAttribute(titleAttr);
+            bool enabledViaScript = false;
+            if (e->hasLocalName(linkTag)) {
+                // <LINK> element
+                HTMLLinkElement* linkElement = toHTMLLinkElement(n);
+                enabledViaScript = linkElement->isEnabledViaScript();
+                if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
+                    // it is loading but we should still decide which style sheet set to use
+                    if (!enabledViaScript && !title.isEmpty() && collections->preferredStylesheetSetName().isEmpty()) {
+                        const AtomicString& rel = e->getAttribute(relAttr);
+                        if (!rel.contains("alternate")) {
+                            collections->setPreferredStylesheetSetName(title);
+                            collections->setSelectedStylesheetSetName(title);
+                        }
+                    }
+
+                    continue;
+                }
+                sheet = linkElement->sheet();
+                if (!sheet)
+                    title = nullAtom;
+            } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
+                sheet = static_cast<SVGStyleElement*>(n)->sheet();
+            } else {
+                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
+            }
+
+            if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
+                activeSheet = static_cast<CSSStyleSheet*>(sheet);
+
+            // Check to see if this sheet belongs to a styleset
+            // (thus making it PREFERRED or ALTERNATE rather than
+            // PERSISTENT).
+            AtomicString rel = e->getAttribute(relAttr);
+            if (!enabledViaScript && sheet && !title.isEmpty()) {
+                // Yes, we have a title.
+                if (collections->preferredStylesheetSetName().isEmpty()) {
+                    // No preferred set has been established. If
+                    // we are NOT an alternate sheet, then establish
+                    // us as the preferred set. Otherwise, just ignore
+                    // this sheet.
+                    if (e->hasLocalName(styleTag) || !rel.contains("alternate")) {
+                        collections->setPreferredStylesheetSetName(title);
+                        collections->setSelectedStylesheetSetName(title);
+                    }
+                }
+                if (title != collections->preferredStylesheetSetName())
+                    activeSheet = 0;
+            }
+
+            if (rel.contains("alternate") && title.isEmpty())
+                activeSheet = 0;
+        }
+        if (sheet)
+            styleSheets.append(sheet);
+        if (activeSheet)
+            activeSheets.append(activeSheet);
+    }
+}
+
+StyleSheetCollection::StyleResolverUpdateType StyleSheetCollection::compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets)
+{
+    // Find out which stylesheets are new.
+    unsigned newStylesheetCount = newStylesheets.size();
+    unsigned oldStylesheetCount = oldStyleSheets.size();
+    if (newStylesheetCount < oldStylesheetCount)
+        return Reconstruct;
+
+    unsigned newIndex = 0;
+    for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
+        if (newIndex >= newStylesheetCount)
+            return Reconstruct;
+        while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+            addedSheets.append(newStylesheets[newIndex]->contents());
+            ++newIndex;
+            if (newIndex == newStylesheetCount)
+                return Reconstruct;
+        }
+        ++newIndex;
+    }
+    bool hasInsertions = !addedSheets.isEmpty();
+    while (newIndex < newStylesheetCount) {
+        addedSheets.append(newStylesheets[newIndex]->contents());
+        ++newIndex;
+    }
+    // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
+    // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
+    return hasInsertions ? Reset : Additive;
+}
+
+bool StyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets)
+{
+    // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
+    bool hasActiveLoadingStylesheet = false;
+    unsigned newStylesheetCount = newStyleSheets.size();
+    for (unsigned i = 0; i < newStylesheetCount; ++i) {
+        if (newStyleSheets[i]->isLoading())
+            hasActiveLoadingStylesheet = true;
+    }
+    if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
+        m_hadActiveLoadingStylesheet = false;
+        return true;
+    }
+    m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
+    return false;
+}
+
+void StyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets, StyleResolverUpdateType& styleResolverUpdateType, bool& requiresFullStyleRecalc)
+{
+    styleResolverUpdateType = Reconstruct;
+    requiresFullStyleRecalc = true;
+
+    if (activeLoadingStyleSheetLoaded(newStyleSheets))
+        return;
+
+    if (updateMode != AnalyzedStyleUpdate)
+        return;
+    if (!document()->styleResolverIfExists())
+        return;
+
+    // Find out which stylesheets are new.
+    Vector<StyleSheetContents*> addedSheets;
+    styleResolverUpdateType = compareStyleSheets(oldStyleSheets, newStyleSheets, addedSheets);
+
+    // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
+    if (!document()->body() || document()->hasNodesWithPlaceholderStyle())
+        return;
+    StyleInvalidationAnalysis invalidationAnalysis(addedSheets);
+    if (invalidationAnalysis.dirtiesAllStyle())
+        return;
+    invalidationAnalysis.invalidateStyle(document());
+    requiresFullStyleRecalc = false;
+}
+
+static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
+{
+    HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
+    if (!seamlessParentIFrame)
+        return;
+    sheets.append(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
+}
+
+bool StyleSheetCollection::updateActiveStyleSheets(DocumentStyleSheetCollection* collections, StyleResolverUpdateMode updateMode, StyleResolverUpdateType& styleResolverUpdateType)
+{
+    Vector<RefPtr<StyleSheet> > styleSheets;
+    Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
+    activeCSSStyleSheets.append(collections->injectedAuthorStyleSheets());
+    activeCSSStyleSheets.append(collections->documentAuthorStyleSheets());
+    collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, document());
+    collectStyleSheets(collections, styleSheets, activeCSSStyleSheets);
+
+    bool requiresFullStyleRecalc;
+    analyzeStyleSheetChange(updateMode, activeAuthorStyleSheets(), activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
+
+    if (styleResolverUpdateType == Reconstruct) {
+        document()->clearStyleResolver();
+    } else {
+        StyleResolver* styleResolver = document()->styleResolver();
+        if (styleResolverUpdateType == Reset) {
+            styleResolver->resetAuthorStyle();
+            styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
+        } else {
+            ASSERT(styleResolverUpdateType == Additive);
+            styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
+        }
+    }
+    m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
+    m_styleSheetsForStyleSheetList.swap(styleSheets);
+
+    return requiresFullStyleRecalc;
+}
+
+void StyleSheetCollection::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
+    info.addMember(m_activeAuthorStyleSheets, "activeAuthorStyleSheets");
+    info.addMember(m_styleSheetsForStyleSheetList, "styleSheetsForStyleSheetList");
+    info.addMember(m_styleSheetCandidateNodes, "styleSheetCandidateNodes");
+    info.addMember(m_treeScope, "treeScope");
+}
+
+}
diff --git a/Source/core/dom/StyleSheetCollection.h b/Source/core/dom/StyleSheetCollection.h
new file mode 100644
index 0000000..fd0d176
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollection.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef StyleSheetCollection_h
+#define StyleSheetCollection_h
+
+#include "core/dom/Document.h"
+#include "core/dom/DocumentOrderedList.h"
+#include "core/dom/TreeScope.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class DocumentStyleSheetCollection;
+class Node;
+class StyleSheet;
+class StyleSheetContents;
+class StyleSheetList;
+
+class StyleSheetCollection {
+    WTF_MAKE_NONCOPYABLE(StyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit StyleSheetCollection(TreeScope*);
+
+    void addStyleSheetCandidateNode(Node*, bool createdByParser);
+    void removeStyleSheetCandidateNode(Node*);
+
+    Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
+    Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
+    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+
+    DocumentOrderedList& styleSheetCandidateNodes() { return m_styleSheetCandidateNodes; }
+
+    enum StyleResolverUpdateType {
+        Reconstruct,
+        Reset,
+        Additive
+    };
+    bool updateActiveStyleSheets(DocumentStyleSheetCollection*, StyleResolverUpdateMode, StyleResolverUpdateType&);
+
+    void reportMemoryUsage(MemoryObjectInfo*) const;
+
+private:
+    Document* document() { return m_treeScope->documentScope(); }
+
+    void collectStyleSheets(DocumentStyleSheetCollection* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
+
+    StyleResolverUpdateType compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets);
+    bool activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets);
+
+    void analyzeStyleSheetChange(StyleResolverUpdateMode, const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, StyleResolverUpdateType&, bool& requiresFullStyleRecalc);
+
+    Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
+    Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
+
+    TreeScope* m_treeScope;
+    bool m_hadActiveLoadingStylesheet;
+
+    DocumentOrderedList m_styleSheetCandidateNodes;
+};
+
+}
+
+#endif
+
diff --git a/Source/core/dom/TagNodeList.cpp b/Source/core/dom/TagNodeList.cpp
index 1835c65..b0e34f6 100644
--- a/Source/core/dom/TagNodeList.cpp
+++ b/Source/core/dom/TagNodeList.cpp
@@ -26,7 +26,7 @@
 
 #include "core/dom/Element.h"
 #include "core/dom/NodeRareData.h"
-#include <wtf/Assertions.h>
+#include "wtf/Assertions.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/TagNodeList.h b/Source/core/dom/TagNodeList.h
index f580ca0..3ef510b 100644
--- a/Source/core/dom/TagNodeList.h
+++ b/Source/core/dom/TagNodeList.h
@@ -26,7 +26,7 @@
 
 #include "core/dom/Element.h"
 #include "core/dom/LiveNodeList.h"
-#include <wtf/text/AtomicString.h>
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index c36409b..9886613 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -26,6 +26,7 @@
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExceptionCodePlaceholder.h"
+#include "core/dom/NodeRenderStyle.h"
 #include "core/dom/NodeRenderingContext.h"
 #include "core/dom/ScopedEventQueue.h"
 #include "core/dom/shadow/ShadowRoot.h"
@@ -58,10 +59,10 @@
 {
     ec = 0;
 
-    // INDEX_SIZE_ERR: Raised if the specified offset is negative or greater than
+    // IndexSizeError: Raised if the specified offset is negative or greater than
     // the number of 16-bit units in data.
     if (offset > length()) {
-        ec = INDEX_SIZE_ERR;
+        ec = IndexSizeError;
         return 0;
     }
 
@@ -217,7 +218,7 @@
     
     if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
         return true;
-    
+
     RenderObject* prev = context.previousRenderer();
     if (prev && prev->isBR()) // <span><br/> <br/></span>
         return false;
@@ -277,20 +278,32 @@
     CharacterData::attach(context);
 }
 
-void Text::recalcTextStyle(StyleChange change)
+bool Text::recalcTextStyle(StyleChange change)
 {
-    RenderText* renderer = toRenderText(this->renderer());
-
-    if (renderer) {
+    if (RenderText* renderer = toRenderText(this->renderer())) {
         if (change != NoChange || needsStyleRecalc())
             renderer->setStyle(document()->styleResolver()->styleForText(this));
         if (needsStyleRecalc())
             renderer->setText(dataImpl());
-    } else if (needsStyleRecalc()) {
+        clearNeedsStyleRecalc();
+    } else if (needsStyleRecalc() || needsWhitespaceRenderer()) {
         reattach();
+        return true;
     }
+    return false;
+}
 
-    clearNeedsStyleRecalc();
+// If a whitespace node had no renderer and goes through a recalcStyle it may
+// need to create one if the parent style now has white-space: pre.
+bool Text::needsWhitespaceRenderer()
+{
+    ASSERT(!renderer());
+    ContainerNode* parent = parentNodeForRenderingAndStyle();
+    if (!parent)
+        return false;
+    if (RenderStyle* style = parent->renderStyle())
+        return style->preserveNewline();
+    return false;
 }
 
 void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
diff --git a/Source/core/dom/Text.h b/Source/core/dom/Text.h
index e4b3b1c..65f7738 100644
--- a/Source/core/dom/Text.h
+++ b/Source/core/dom/Text.h
@@ -46,7 +46,7 @@
     String wholeText() const;
     PassRefPtr<Text> replaceWholeText(const String&);
     
-    void recalcTextStyle(StyleChange);
+    bool recalcTextStyle(StyleChange);
     void createTextRendererIfNeeded();
     bool textRendererIsNeeded(const NodeRenderingContext&);
     virtual RenderText* createTextRenderer(RenderStyle*);
@@ -66,9 +66,11 @@
 
 private:
     virtual String nodeName() const OVERRIDE;
-    virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE FINAL;
+    virtual PassRefPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
     virtual bool childTypeAllowed(NodeType) const OVERRIDE;
 
+    bool needsWhitespaceRenderer();
+
     virtual PassRefPtr<Text> cloneWithData(const String&);
 
 #ifndef NDEBUG
diff --git a/Source/core/dom/TextLinkColors.cpp b/Source/core/dom/TextLinkColors.cpp
new file mode 100644
index 0000000..f6e1fd8
--- /dev/null
+++ b/Source/core/dom/TextLinkColors.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/TextLinkColors.h"
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/rendering/RenderTheme.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+TextLinkColors::TextLinkColors()
+    : m_textColor(Color::black)
+{
+    resetLinkColor();
+    resetVisitedLinkColor();
+    resetActiveLinkColor();
+}
+
+void TextLinkColors::resetLinkColor()
+{
+    m_linkColor = Color(0, 0, 238);
+}
+
+void TextLinkColors::resetVisitedLinkColor()
+{
+    m_visitedLinkColor = Color(85, 26, 139);
+}
+
+void TextLinkColors::resetActiveLinkColor()
+{
+    m_activeLinkColor.setNamedColor("red");
+}
+
+static Color colorForCSSValue(CSSValueID cssValueId)
+{
+    struct ColorValue {
+        CSSValueID cssValueId;
+        RGBA32 color;
+    };
+
+    static const ColorValue colorValues[] = {
+        { CSSValueAqua, 0xFF00FFFF },
+        { CSSValueBlack, 0xFF000000 },
+        { CSSValueBlue, 0xFF0000FF },
+        { CSSValueFuchsia, 0xFFFF00FF },
+        { CSSValueGray, 0xFF808080 },
+        { CSSValueGreen, 0xFF008000  },
+        { CSSValueGrey, 0xFF808080 },
+        { CSSValueLime, 0xFF00FF00 },
+        { CSSValueMaroon, 0xFF800000 },
+        { CSSValueNavy, 0xFF000080 },
+        { CSSValueOlive, 0xFF808000  },
+        { CSSValueOrange, 0xFFFFA500 },
+        { CSSValuePurple, 0xFF800080 },
+        { CSSValueRed, 0xFFFF0000 },
+        { CSSValueSilver, 0xFFC0C0C0 },
+        { CSSValueTeal, 0xFF008080  },
+        { CSSValueTransparent, 0x00000000 },
+        { CSSValueWhite, 0xFFFFFFFF },
+        { CSSValueYellow, 0xFFFFFF00 },
+        { CSSValueInvalid, CSSValueInvalid }
+    };
+
+    for (const ColorValue* col = colorValues; col->cssValueId; ++col) {
+        if (col->cssValueId == cssValueId)
+            return col->color;
+    }
+    return RenderTheme::defaultTheme()->systemColor(cssValueId);
+}
+
+Color TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, Color currentColor, bool forVisitedLink) const
+{
+    if (value->isRGBColor())
+        return Color(value->getRGBA32Value());
+
+    CSSValueID valueID = value->getValueID();
+    switch (valueID) {
+    case 0:
+        return Color();
+    case CSSValueWebkitText:
+        return textColor();
+    case CSSValueWebkitLink:
+        return forVisitedLink ? visitedLinkColor() : linkColor();
+    case CSSValueWebkitActivelink:
+        return activeLinkColor();
+    case CSSValueWebkitFocusRingColor:
+        return RenderTheme::focusRingColor();
+    case CSSValueCurrentcolor:
+        return currentColor;
+    default:
+        return colorForCSSValue(valueID);
+    }
+}
+
+}
diff --git a/Source/core/dom/TextLinkColors.h b/Source/core/dom/TextLinkColors.h
new file mode 100644
index 0000000..6d2728c
--- /dev/null
+++ b/Source/core/dom/TextLinkColors.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TextLinkColors_h
+#define TextLinkColors_h
+
+#include "core/platform/graphics/Color.h"
+#include "wtf/Noncopyable.h"
+
+namespace WebCore {
+
+class CSSPrimitiveValue;
+class Element;
+
+class TextLinkColors {
+WTF_MAKE_NONCOPYABLE(TextLinkColors);
+public:
+    TextLinkColors();
+
+    void setTextColor(const Color& color) { m_textColor = color; }
+    Color textColor() const { return m_textColor; }
+
+    const Color& linkColor() const { return m_linkColor; }
+    const Color& visitedLinkColor() const { return m_visitedLinkColor; }
+    const Color& activeLinkColor() const { return m_activeLinkColor; }
+    void setLinkColor(const Color& color) { m_linkColor = color; }
+    void setVisitedLinkColor(const Color& color) { m_visitedLinkColor = color; }
+    void setActiveLinkColor(const Color& color) { m_activeLinkColor = color; }
+    void resetLinkColor();
+    void resetVisitedLinkColor();
+    void resetActiveLinkColor();
+    Color colorFromPrimitiveValue(const CSSPrimitiveValue*, Color currentColor, bool forVisitedLink = false) const;
+private:
+
+    Color m_textColor;
+    Color m_linkColor;
+    Color m_visitedLinkColor;
+    Color m_activeLinkColor;
+};
+
+}
+
+#endif
diff --git a/Source/core/dom/TouchEvent.idl b/Source/core/dom/TouchEvent.idl
index 6348e68..b054441 100644
--- a/Source/core/dom/TouchEvent.idl
+++ b/Source/core/dom/TouchEvent.idl
@@ -22,8 +22,9 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
-interface TouchEvent : UIEvent {
+[
+    AllowJSCreationOnlyIfFeatureEnabled
+] interface TouchEvent : UIEvent {
     readonly attribute TouchList touches;
     readonly attribute TouchList targetTouches;
     readonly attribute TouchList changedTouches;
diff --git a/Source/core/dom/TransformSource.h b/Source/core/dom/TransformSource.h
index 002e912..f637ce3 100644
--- a/Source/core/dom/TransformSource.h
+++ b/Source/core/dom/TransformSource.h
@@ -20,11 +20,11 @@
 #ifndef TransformSource_h
 #define TransformSource_h
 
+#include "wtf/FastAllocBase.h"
+#include "wtf/Forward.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/text/WTFString.h"
 #include <libxml/tree.h>
-#include <wtf/FastAllocBase.h>
-#include <wtf/Forward.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
diff --git a/Source/core/dom/Traversal.h b/Source/core/dom/Traversal.h
index 3e70886..58ef152 100644
--- a/Source/core/dom/Traversal.h
+++ b/Source/core/dom/Traversal.h
@@ -26,7 +26,7 @@
 #define Traversal_h
 
 #include "bindings/v8/ScriptState.h"
-#include <wtf/RefPtr.h>
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index 2c447dc..1d778d9 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -35,6 +35,7 @@
 #include "core/dom/IdTargetObserverRegistry.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/TreeScopeAdopter.h"
+#include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
@@ -204,8 +205,8 @@
     size_t hashPos = url.find('#');
     String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl();
     if (rootNode()->document()->isHTMLDocument())
-        return static_cast<HTMLMapElement*>(m_imageMapsByName->getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
-    return static_cast<HTMLMapElement*>(m_imageMapsByName->getElementByMapName(AtomicString(name).impl(), this));
+        return toHTMLMapElement(m_imageMapsByName->getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
+    return toHTMLMapElement(m_imageMapsByName->getElementByMapName(AtomicString(name).impl(), this));
 }
 
 Node* nodeFromPoint(Document* document, int x, int y, LayoutPoint* localPoint)
@@ -237,10 +238,12 @@
 Element* TreeScope::elementFromPoint(int x, int y) const
 {
     Node* node = nodeFromPoint(rootNode()->document(), x, y);
-    while (node && !node->isElementNode())
+    if (node && node->isTextNode())
         node = node->parentNode();
-    if (node)
-        node = ancestorInThisScope(node);
+    ASSERT(!node || node->isElementNode() || node->isShadowRoot());
+    node = ancestorInThisScope(node);
+    if (!node || !node->isElementNode())
+        return 0;
     return toElement(node);
 }
 
@@ -265,8 +268,8 @@
         // Populate the map on first access.
         m_labelsByForAttribute = adoptPtr(new DocumentOrderedMap);
         for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(element)) {
-            if (element->hasTagName(labelTag)) {
-                HTMLLabelElement* label = static_cast<HTMLLabelElement*>(element);
+            if (isHTMLLabelElement(element)) {
+                HTMLLabelElement* label = toHTMLLabelElement(element);
                 const AtomicString& forValue = label->fastGetAttribute(forAttr);
                 if (!forValue.isEmpty())
                     addLabel(forValue, label);
@@ -274,7 +277,7 @@
         }
     }
 
-    return static_cast<HTMLLabelElement*>(m_labelsByForAttribute->getElementByLabelForAttribute(forAttributeValue.impl(), this));
+    return toHTMLLabelElement(m_labelsByForAttribute->getElementByLabelForAttribute(forAttributeValue.impl(), this));
 }
 
 DOMSelection* TreeScope::getSelection() const
@@ -299,8 +302,8 @@
     if (Element* element = getElementById(name))
         return element;
     for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(element)) {
-        if (element->hasTagName(aTag)) {
-            HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(element);
+        if (isHTMLAnchorElement(element)) {
+            HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
             if (rootNode()->document()->inQuirksMode()) {
                 // Quirks mode, case insensitive comparison of names.
                 if (equalIgnoringCase(anchor->name(), name))
@@ -345,7 +348,7 @@
     return 0;
 }
 
-Node* TreeScope::focusedNode()
+Element* TreeScope::adjustedFocusedElement()
 {
     Document* document = rootNode()->document();
     Node* node = document->focusedNode();
@@ -361,7 +364,7 @@
         else if (walker.isVisitingInsertionPointInReprojection())
             targetStack.append(targetStack.last());
         if (node == rootNode())
-            return targetStack.last();
+            return toElement(targetStack.last());
         if (node->isShadowRoot()) {
             ASSERT(!targetStack.isEmpty());
             targetStack.removeLast();
@@ -492,4 +495,21 @@
     return false;
 }
 
+Element* TreeScope::getElementByAccessKey(const String& key) const
+{
+    if (key.isEmpty())
+        return 0;
+    Element* result = 0;
+    Node* root = rootNode();
+    for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(element, root)) {
+        if (element->fastGetAttribute(accesskeyAttr) == key)
+            result = element;
+        for (ShadowRoot* shadowRoot = element->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
+            if (Element* shadowResult = shadowRoot->getElementByAccessKey(key))
+                result = shadowResult;
+        }
+    }
+    return result;
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
index 18eb059..989638c 100644
--- a/Source/core/dom/TreeScope.h
+++ b/Source/core/dom/TreeScope.h
@@ -28,8 +28,8 @@
 #define TreeScope_h
 
 #include "core/dom/DocumentOrderedMap.h"
-#include <wtf/Forward.h>
-#include <wtf/text/AtomicString.h>
+#include "wtf/Forward.h"
+#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
@@ -54,7 +54,7 @@
     TreeScope* parentTreeScope() const { return m_parentTreeScope; }
     void setParentTreeScope(TreeScope*);
 
-    Node* focusedNode();
+    Element* adjustedFocusedElement();
     Element* getElementById(const AtomicString&) const;
     bool hasElementWithId(AtomicStringImpl* id) const;
     bool containsMultipleElementsWithId(const AtomicString& id) const;
@@ -130,6 +130,8 @@
     bool isInclusiveAncestorOf(const TreeScope*) const;
     unsigned short comparePosition(const TreeScope*) const;
 
+    Element* getElementByAccessKey(const String& key) const;
+
 protected:
     TreeScope(ContainerNode*, Document*);
     TreeScope(Document*);
diff --git a/Source/core/dom/TreeWalker.cpp b/Source/core/dom/TreeWalker.cpp
index 8ed9d78..626a4fc 100644
--- a/Source/core/dom/TreeWalker.cpp
+++ b/Source/core/dom/TreeWalker.cpp
@@ -30,7 +30,7 @@
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/NodeFilter.h"
 #include "core/dom/NodeTraversal.h"
-#include <wtf/PassRefPtr.h>
+#include "wtf/PassRefPtr.h"
 
 namespace WebCore {
 
@@ -44,7 +44,7 @@
 void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionCode& ec)
 {
     if (!node) {
-        ec = NOT_SUPPORTED_ERR;
+        ec = NotSupportedError;
         return;
     }
     m_current = node;
diff --git a/Source/core/dom/TreeWalker.h b/Source/core/dom/TreeWalker.h
index 0ab3976..9fcc954 100644
--- a/Source/core/dom/TreeWalker.h
+++ b/Source/core/dom/TreeWalker.h
@@ -28,8 +28,8 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/NodeFilter.h"
 #include "core/dom/Traversal.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/UserGestureIndicator.cpp b/Source/core/dom/UserGestureIndicator.cpp
index c4e891f..dc98aed 100644
--- a/Source/core/dom/UserGestureIndicator.cpp
+++ b/Source/core/dom/UserGestureIndicator.cpp
@@ -25,19 +25,36 @@
 
 #include "config.h"
 #include "core/dom/UserGestureIndicator.h"
+#include "wtf/CurrentTime.h"
 
 namespace WebCore {
 
 namespace {
 
+// User gestures timeout in 1 second.
+const double userGestureTimeout = 1.0;
+
+// For out of process tokens we allow a 10 second delay.
+const double userGestureOutOfProcessTimeout = 10.0;
+
 class GestureToken : public UserGestureToken {
 public:
     static PassRefPtr<UserGestureToken> create() { return adoptRef(new GestureToken); }
 
     virtual ~GestureToken() { }
-    virtual bool hasGestures() const OVERRIDE { return m_consumableGestures > 0; }
+    virtual bool hasGestures() const OVERRIDE
+    {
+        if (m_consumableGestures < 1 || WTF::currentTime() - m_timestamp > (m_outOfProcess ? userGestureOutOfProcessTimeout : userGestureTimeout))
+            return false;
+        return true;
+    }
 
-    void addGesture() { m_consumableGestures++; }
+    void addGesture()
+    {
+        m_consumableGestures++;
+        m_timestamp = WTF::currentTime();
+    }
+
     bool consumeGesture()
     {
         if (!m_consumableGestures)
@@ -46,13 +63,25 @@
         return true;
     }
 
+    virtual void setOutOfProcess() OVERRIDE
+    {
+        if (WTF::currentTime() - m_timestamp > userGestureTimeout)
+            return;
+        if (hasGestures())
+            m_outOfProcess = true;
+    }
+
 private:
     GestureToken()
-        : m_consumableGestures(0)
+        : m_consumableGestures(0),
+        m_timestamp(0),
+        m_outOfProcess(false)
     {
     }
 
     size_t m_consumableGestures;
+    double m_timestamp;
+    bool m_outOfProcess;
 };
 
 }
diff --git a/Source/core/dom/UserGestureIndicator.h b/Source/core/dom/UserGestureIndicator.h
index 4c29acb..7eaaf05 100644
--- a/Source/core/dom/UserGestureIndicator.h
+++ b/Source/core/dom/UserGestureIndicator.h
@@ -26,9 +26,9 @@
 #ifndef UserGestureIndicator_h
 #define UserGestureIndicator_h
 
-#include <wtf/Noncopyable.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
+#include "wtf/Noncopyable.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
@@ -45,6 +45,7 @@
 public:
     virtual ~UserGestureToken() { }
     virtual bool hasGestures() const = 0;
+    virtual void setOutOfProcess() = 0;
 };
 
 class UserGestureIndicatorDisabler {
diff --git a/Source/core/dom/UserTypingGestureIndicator.cpp b/Source/core/dom/UserTypingGestureIndicator.cpp
index 5b6684e..1200868 100644
--- a/Source/core/dom/UserTypingGestureIndicator.cpp
+++ b/Source/core/dom/UserTypingGestureIndicator.cpp
@@ -29,7 +29,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/Node.h"
 #include "core/page/Frame.h"
-#include <wtf/StdLibExtras.h>
+#include "wtf/StdLibExtras.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/UserTypingGestureIndicator.h b/Source/core/dom/UserTypingGestureIndicator.h
index 21f4c7e..149c430 100644
--- a/Source/core/dom/UserTypingGestureIndicator.h
+++ b/Source/core/dom/UserTypingGestureIndicator.h
@@ -26,8 +26,8 @@
 #ifndef UserTypingGestureIndicator_h
 #define UserTypingGestureIndicator_h
 
-#include <wtf/Noncopyable.h>
-#include <wtf/RefPtr.h>
+#include "wtf/Noncopyable.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/ViewportArguments.cpp b/Source/core/dom/ViewportArguments.cpp
index e0b346d..d6a56f9 100644
--- a/Source/core/dom/ViewportArguments.cpp
+++ b/Source/core/dom/ViewportArguments.cpp
@@ -114,10 +114,10 @@
         ASSERT(resultMaxHeight != ViewportArguments::ValueDeviceHeight);
 
         if (resultMinWidth != ViewportArguments::ValueAuto || resultMaxWidth != ViewportArguments::ValueAuto)
-            resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, deviceSize.width(), min), max);
+            resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
 
         if (resultMinHeight != ViewportArguments::ValueAuto || resultMaxHeight != ViewportArguments::ValueAuto)
-            resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, deviceSize.height(), min), max);
+            resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
 
         if (resultMinZoom != ViewportArguments::ValueAuto && resultMaxZoom != ViewportArguments::ValueAuto)
             resultMaxZoom = max(resultMinZoom, resultMaxZoom);
@@ -125,25 +125,20 @@
         if (resultZoom != ViewportArguments::ValueAuto)
             resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
 
-        if (resultWidth == ViewportArguments::ValueAuto && resultZoom == ViewportArguments::ValueAuto)
-            resultWidth = deviceSize.width();
+        if (resultWidth == ViewportArguments::ValueAuto && (resultHeight == ViewportArguments::ValueAuto || !initialViewportSize.height()))
+            resultWidth = initialViewportSize.width();
 
-        if (resultWidth == ViewportArguments::ValueAuto && resultHeight == ViewportArguments::ValueAuto)
-            resultWidth = deviceSize.width() / resultZoom;
-
-        if (resultWidth == ViewportArguments::ValueAuto)
-            resultWidth = resultHeight * deviceSize.width() / deviceSize.height();
-
-        if (resultHeight == ViewportArguments::ValueAuto)
-            resultHeight = resultWidth * deviceSize.height() / deviceSize.width();
-
-        if (resultZoom != ViewportArguments::ValueAuto || resultMaxZoom != ViewportArguments::ValueAuto) {
-            resultWidth = compareIgnoringAuto(resultWidth, deviceSize.width() / compareIgnoringAuto(resultZoom, resultMaxZoom, min), max);
-            resultHeight = compareIgnoringAuto(resultHeight, deviceSize.height() / compareIgnoringAuto(resultZoom, resultMaxZoom, min), max);
+        if (resultWidth == ViewportArguments::ValueAuto) {
+            ASSERT(initialViewportSize.height()); // If height is 0, resultWidth should be resolved above.
+            resultWidth = resultHeight * initialViewportSize.width() / initialViewportSize.height();
         }
 
-        resultWidth = max<float>(1, resultWidth);
-        resultHeight = max<float>(1, resultHeight);
+        if (resultHeight == ViewportArguments::ValueAuto) {
+            if (!initialViewportSize.width())
+                resultHeight = initialViewportSize.height();
+            else
+                resultHeight = resultWidth * initialViewportSize.height() / initialViewportSize.width();
+        }
     }
 
     if (type != ViewportArguments::CSSDeviceAdaptation && type != ViewportArguments::Implicit) {
@@ -175,9 +170,9 @@
     result.initialScale = resultZoom;
     if (resultZoom == ViewportArguments::ValueAuto) {
         result.initialScale = initialViewportSize.width() / defaultWidth;
-        if (resultWidth != ViewportArguments::ValueAuto)
+        if (resultWidth != ViewportArguments::ValueAuto && resultWidth > 0)
             result.initialScale = initialViewportSize.width() / resultWidth;
-        if (resultHeight != ViewportArguments::ValueAuto) {
+        if (resultHeight != ViewportArguments::ValueAuto && resultHeight > 0) {
             // if 'auto', the initial-scale will be negative here and thus ignored.
             result.initialScale = max<float>(result.initialScale, initialViewportSize.height() / resultHeight);
         }
diff --git a/Source/core/dom/ViewportArguments.h b/Source/core/dom/ViewportArguments.h
index a311af6..925604a 100644
--- a/Source/core/dom/ViewportArguments.h
+++ b/Source/core/dom/ViewportArguments.h
@@ -30,7 +30,7 @@
 
 #include "core/page/PageScaleConstraints.h"
 #include "core/platform/graphics/FloatSize.h"
-#include <wtf/Forward.h>
+#include "wtf/Forward.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/VisitedLinkState.cpp b/Source/core/dom/VisitedLinkState.cpp
index d6236d4..77e8fd1 100644
--- a/Source/core/dom/VisitedLinkState.cpp
+++ b/Source/core/dom/VisitedLinkState.cpp
@@ -50,16 +50,16 @@
 
 inline static LinkHash linkHashForElement(Document* document, Element* element)
 {
-    if (element->hasTagName(aTag))
-        return static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
+    if (isHTMLAnchorElement(element))
+        return toHTMLAnchorElement(element)->visitedLinkHash();
     return visitedLinkHash(document->baseURL(), linkAttribute(element));
 }
 
 inline static LinkHash linkHashForElementWithAttribute(Document* document, Element* element, const AtomicString& attribute)
 {
     ASSERT(linkAttribute(element) == attribute);
-    if (element->hasTagName(aTag))
-        return static_cast<HTMLAnchorElement*>(element)->visitedLinkHash();
+    if (isHTMLAnchorElement(element))
+        return toHTMLAnchorElement(element)->visitedLinkHash();
     return visitedLinkHash(document->baseURL(), attribute);
 }
 
diff --git a/Source/core/dom/WebCoreMemoryInstrumentation.h b/Source/core/dom/WebCoreMemoryInstrumentation.h
index 4fe69b2..dc0e49e 100644
--- a/Source/core/dom/WebCoreMemoryInstrumentation.h
+++ b/Source/core/dom/WebCoreMemoryInstrumentation.h
@@ -32,7 +32,7 @@
 #define WebCoreMemoryInstrumentation_h
 
 #include "core/platform/PlatformMemoryInstrumentation.h"
-#include <wtf/MemoryInstrumentationString.h>
+#include "wtf/MemoryInstrumentationString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/WebKitNamedFlow.idl b/Source/core/dom/WebKitNamedFlow.idl
index 5a008bd..68f2858 100644
--- a/Source/core/dom/WebKitNamedFlow.idl
+++ b/Source/core/dom/WebKitNamedFlow.idl
@@ -30,23 +30,13 @@
 [
     NoInterfaceObject,
     EnabledAtRuntime=cssRegions,
-    EventTarget,
     ImplementedAs=NamedFlow,
     GenerateIsReachable=ownerNode
-] interface WebKitNamedFlow {
+] interface WebKitNamedFlow : EventTarget {
     readonly attribute DOMString name;
     readonly attribute boolean overset;
     readonly attribute long firstEmptyRegionIndex;
     NodeList getRegionsByContent(Node contentNode);
     NodeList getRegions();
     NodeList getContent();
-
-    // EventTarget interface
-    void addEventListener(DOMString type, 
-                          EventListener listener, 
-                          optional boolean useCapture);
-    void removeEventListener(DOMString type, 
-                             EventListener listener, 
-                             optional boolean useCapture);
-    [RaisesException] boolean dispatchEvent(Event event);
 };
diff --git a/Source/core/dom/WindowEventContext.h b/Source/core/dom/WindowEventContext.h
index a19e04d..5d0aa7c 100644
--- a/Source/core/dom/WindowEventContext.h
+++ b/Source/core/dom/WindowEventContext.h
@@ -27,7 +27,7 @@
 #ifndef WindowEventContext_h
 #define WindowEventContext_h
 
-#include <wtf/RefPtr.h>
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/default/PlatformMessagePortChannel.h b/Source/core/dom/default/PlatformMessagePortChannel.h
index 1a087af..f8dffd0 100644
--- a/Source/core/dom/default/PlatformMessagePortChannel.h
+++ b/Source/core/dom/default/PlatformMessagePortChannel.h
@@ -33,9 +33,9 @@
 
 #include "core/dom/MessagePortChannel.h"
 
-#include <wtf/MessageQueue.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/Threading.h>
+#include "wtf/MessageQueue.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/Threading.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
index 08a95c8..f4b8373 100644
--- a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
+++ b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
@@ -34,8 +34,8 @@
 
 #include "core/dom/MessagePortChannel.h"
 #include "public/platform/WebMessagePortChannelClient.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/Threading.h>
+#include "wtf/PassRefPtr.h"
+#include "wtf/Threading.h"
 
 namespace WebKit {
 class WebMessagePortChannel;
diff --git a/Source/core/dom/shadow/ContentDistributor.cpp b/Source/core/dom/shadow/ContentDistributor.cpp
index b3daf77..5b3a68b 100644
--- a/Source/core/dom/shadow/ContentDistributor.cpp
+++ b/Source/core/dom/shadow/ContentDistributor.cpp
@@ -436,7 +436,7 @@
 {
     for (NodeInsertionPointMap::iterator i = m_nodeToInsertionPoint.begin(); i != m_nodeToInsertionPoint.end(); ++i) {
         if (i->value == insertionPoint)
-            const_cast<Node*>(i->key)->setNeedsStyleRecalc(InlineStyleChange);
+            const_cast<Node*>(i->key)->setNeedsStyleRecalc(LocalStyleChange);
     }
 }
 
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 52165d6..42152f7 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -108,7 +108,7 @@
 
 PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
 {
-    ec = DATA_CLONE_ERR;
+    ec = DataCloneError;
     return 0;
 }
 
@@ -120,7 +120,7 @@
 void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
 {
     if (isOrphan()) {
-        ec = INVALID_ACCESS_ERR;
+        ec = InvalidAccessError;
         return;
     }
 
@@ -158,17 +158,30 @@
         return;
     }
 
-    // When we're set to lazyAttach we'll have a FullStyleChange and we'll need
+    // When we're set to lazyAttach we'll have a SubtreeStyleChange and we'll need
     // to promote the change to a Force for all our descendants so they get a
     // recalc and will attach.
-    if (styleChangeType() == FullStyleChange)
+    if (styleChangeType() == SubtreeStyleChange)
         change = Force;
 
+    // FIXME: This doesn't handle :hover + div properly like Element::recalcStyle does.
+    bool forceReattachOfAnyWhitespaceSibling = false;
     for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->isElementNode())
-            toElement(child)->recalcStyle(change);
-        else if (child->isTextNode())
-            toText(child)->recalcTextStyle(change);
+        bool didReattach = false;
+
+        if (child->renderer())
+            forceReattachOfAnyWhitespaceSibling = false;
+
+        if (child->isTextNode()) {
+            if (forceReattachOfAnyWhitespaceSibling && toText(child)->containsOnlyWhitespace())
+                child->reattach();
+            else
+                didReattach = toText(child)->recalcTextStyle(change);
+        } else if (child->isElementNode() && shouldRecalcStyle(change, child)) {
+            didReattach = toElement(child)->recalcStyle(change);
+        }
+
+        forceReattachOfAnyWhitespaceSibling = didReattach || forceReattachOfAnyWhitespaceSibling;
     }
 
     styleResolver->popParentShadowRoot(this);
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 203e2b6..9d17cad 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -96,6 +96,7 @@
     ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
 
     PassRefPtr<Node> cloneNode(bool, ExceptionCode&);
+    PassRefPtr<Node> cloneNode(ExceptionCode& ec) { return cloneNode(true, ec); }
 
     virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
 
@@ -126,8 +127,8 @@
 
 inline Element* ShadowRoot::activeElement() const
 {
-    if (Node* node = treeScope()->focusedNode())
-        return node->isElementNode() ? toElement(node) : 0;
+    if (Element* element = treeScope()->adjustedFocusedElement())
+        return element;
     return 0;
 }