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;
}