Merge from Chromium at DEPS revision r220549
This commit was generated by merge_to_master.py.
Change-Id: I0d3288f5db2b121c1681ea8d4a70c964cbed1fbd
diff --git a/Source/core/dom/ActiveDOMObject.cpp b/Source/core/dom/ActiveDOMObject.cpp
index de838fe..1614288 100644
--- a/Source/core/dom/ActiveDOMObject.cpp
+++ b/Source/core/dom/ActiveDOMObject.cpp
@@ -38,10 +38,7 @@
, m_suspendIfNeededCalled(false)
#endif
{
- if (!m_scriptExecutionContext)
- return;
-
- ASSERT(m_scriptExecutionContext->isContextThread());
+ ASSERT(!scriptExecutionContext || scriptExecutionContext->isContextThread());
}
ActiveDOMObject::~ActiveDOMObject()
@@ -52,12 +49,11 @@
// ContextLifecycleObserver::contextDestroyed() (which we implement /
// inherit). Hence, we should ensure that this is not 0 before use it
// here.
- if (!m_scriptExecutionContext)
+ if (!scriptExecutionContext())
return;
ASSERT(m_suspendIfNeededCalled);
- ASSERT(m_scriptExecutionContext->isContextThread());
- observeContext(0, ActiveDOMObjectType);
+ ASSERT(scriptExecutionContext()->isContextThread());
}
void ActiveDOMObject::suspendIfNeeded()
@@ -66,10 +62,8 @@
ASSERT(!m_suspendIfNeededCalled);
m_suspendIfNeededCalled = true;
#endif
- if (!m_scriptExecutionContext)
- return;
-
- m_scriptExecutionContext->suspendActiveDOMObjectIfNeeded(this);
+ if (ScriptExecutionContext* context = scriptExecutionContext())
+ scriptExecutionContext()->suspendActiveDOMObjectIfNeeded(this);
}
bool ActiveDOMObject::hasPendingActivity() const
diff --git a/Source/core/dom/AnimationEvent.h b/Source/core/dom/AnimationEvent.h
deleted file mode 100644
index 3eadf3d..0000000
--- a/Source/core/dom/AnimationEvent.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 AnimationEvent_h
-#define AnimationEvent_h
-
-#include "core/dom/Event.h"
-
-namespace WebCore {
-
-struct AnimationEventInit : public EventInit {
- AnimationEventInit();
-
- String animationName;
- double elapsedTime;
-};
-
-class AnimationEvent : public Event {
-public:
- static PassRefPtr<AnimationEvent> create()
- {
- return adoptRef(new AnimationEvent);
- }
- static PassRefPtr<AnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
- {
- return adoptRef(new AnimationEvent(type, animationName, elapsedTime));
- }
- static PassRefPtr<AnimationEvent> create(const AtomicString& type, const AnimationEventInit& initializer)
- {
- return adoptRef(new AnimationEvent(type, initializer));
- }
-
- virtual ~AnimationEvent();
-
- const String& animationName() const;
- double elapsedTime() const;
-
- virtual const AtomicString& interfaceName() const;
-
-private:
- AnimationEvent();
- AnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime);
- AnimationEvent(const AtomicString&, const AnimationEventInit&);
-
- String m_animationName;
- double m_elapsedTime;
-};
-
-} // namespace WebCore
-
-#endif // AnimationEvent_h
diff --git a/Source/core/dom/BeforeUnloadEvent.cpp b/Source/core/dom/BeforeUnloadEvent.cpp
index 25f7b0e..a22374c 100644
--- a/Source/core/dom/BeforeUnloadEvent.cpp
+++ b/Source/core/dom/BeforeUnloadEvent.cpp
@@ -1,8 +1,9 @@
-/**
+/*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
* Copyright (C) 2003, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2013 Samsung Electronics.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,20 +31,16 @@
BeforeUnloadEvent::BeforeUnloadEvent()
: Event(eventNames().beforeunloadEvent, false, true)
{
+ ScriptWrappable::init(this);
}
BeforeUnloadEvent::~BeforeUnloadEvent()
{
}
-bool BeforeUnloadEvent::storesResultAsString() const
+bool BeforeUnloadEvent::isBeforeUnloadEvent() const
{
return true;
}
-void BeforeUnloadEvent::storeResult(const String& s)
-{
- m_result = s;
-}
-
} // namespace WebCore
diff --git a/Source/core/dom/BeforeUnloadEvent.h b/Source/core/dom/BeforeUnloadEvent.h
index c3be346..a76ad52 100644
--- a/Source/core/dom/BeforeUnloadEvent.h
+++ b/Source/core/dom/BeforeUnloadEvent.h
@@ -3,6 +3,7 @@
* Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
* Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
* Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2013 Samsung Electronics.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,28 +26,37 @@
#define BeforeUnloadEvent_h
#include "core/dom/Event.h"
+#include "core/dom/EventNames.h"
namespace WebCore {
- class BeforeUnloadEvent : public Event {
- public:
- virtual ~BeforeUnloadEvent();
+class BeforeUnloadEvent : public Event {
+public:
+ virtual ~BeforeUnloadEvent();
- static PassRefPtr<BeforeUnloadEvent> create()
- {
- return adoptRef(new BeforeUnloadEvent);
- }
+ static PassRefPtr<BeforeUnloadEvent> create()
+ {
+ return adoptRef(new BeforeUnloadEvent);
+ }
- virtual bool storesResultAsString() const;
- virtual void storeResult(const String&);
+ virtual bool isBeforeUnloadEvent() const OVERRIDE;
- String result() const { return m_result; }
+ void setReturnValue(const String& returnValue) { m_returnValue = returnValue; }
+ String returnValue() const { return m_returnValue; }
- private:
- BeforeUnloadEvent();
+ virtual const AtomicString& interfaceName() const OVERRIDE { return eventNames().interfaceForBeforeUnloadEvent; }
- String m_result;
- };
+private:
+ BeforeUnloadEvent();
+
+ String m_returnValue;
+};
+
+inline BeforeUnloadEvent* toBeforeUnloadEvent(Event* event)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!event || event->isBeforeUnloadEvent());
+ return static_cast<BeforeUnloadEvent*>(event);
+}
} // namespace WebCore
diff --git a/Source/core/dom/BeforeUnloadEvent.idl b/Source/core/dom/BeforeUnloadEvent.idl
new file mode 100644
index 0000000..618d558
--- /dev/null
+++ b/Source/core/dom/BeforeUnloadEvent.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics. 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.
+ */
+
+interface BeforeUnloadEvent : Event {
+ attribute DOMString returnValue;
+};
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index c184a5e..94c37e5 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -48,7 +48,7 @@
static void dispatchChildInsertionEvents(Node*);
static void dispatchChildRemovalEvents(Node*);
-static void updateTreeAfterInsertion(ContainerNode*, Node*, AttachBehavior);
+static void updateTreeAfterInsertion(ContainerNode*, Node*);
typedef pair<NodeCallback, RefPtr<Node> > CallbackInfo;
typedef Vector<CallbackInfo> NodeCallbackQueue;
@@ -63,6 +63,17 @@
unsigned NoEventDispatchAssertion::s_count = 0;
#endif
+static inline void attachAfterInsertion(Node* node, AttachBehavior attachBehavior = AttachLazily)
+{
+ if (node->attached() || !node->parentNode() || !node->parentNode()->attached())
+ return;
+
+ if (attachBehavior == AttachLazily)
+ node->lazyAttach();
+ else
+ node->attach();
+}
+
static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionState& es)
{
if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
@@ -106,13 +117,11 @@
children[i]->detach();
// FIXME: We need a no mutation event version of adoptNode.
RefPtr<Node> child = document()->adoptNode(children[i].release(), ASSERT_NO_EXCEPTION);
- parserAppendChild(child.get());
// FIXME: Together with adoptNode above, the tree scope might get updated recursively twice
// (if the document changed or oldParent was in a shadow tree, AND *this is in a shadow tree).
// Can we do better?
treeScope()->adoptIfNeeded(child.get());
- if (attached() && !child->attached())
- child->attach();
+ parserAppendChild(child.get(), DeprecatedAttachNow);
}
}
@@ -214,7 +223,7 @@
return checkAcceptChild(newParent, newChild, oldChild, es);
}
-void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es, AttachBehavior attachBehavior)
+void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
@@ -224,7 +233,7 @@
// insertBefore(node, 0) is equivalent to appendChild(node)
if (!refChild) {
- appendChild(newChild, es, attachBehavior);
+ appendChild(newChild, es);
return;
}
@@ -273,7 +282,7 @@
insertBeforeCommon(next.get(), child);
- updateTreeAfterInsertion(this, child, attachBehavior);
+ updateTreeAfterInsertion(this, child);
}
dispatchSubtreeModifiedEvent();
@@ -305,7 +314,7 @@
newChild->setNextSibling(nextChild);
}
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild, AttachBehavior attachBehavior)
{
ASSERT(newChild);
ASSERT(nextChild);
@@ -326,10 +335,13 @@
ChildListMutationScope(this).childAdded(newChild.get());
childrenChanged(true, newChild->previousSibling(), nextChild, 1);
+
ChildNodeInsertionNotifier(this).notify(newChild.get());
+
+ attachAfterInsertion(newChild.get(), attachBehavior);
}
-void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es, AttachBehavior attachBehavior)
+void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
{
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
@@ -407,7 +419,7 @@
appendChildToContainer(child, this);
}
- updateTreeAfterInsertion(this, child, attachBehavior);
+ updateTreeAfterInsertion(this, child);
}
dispatchSubtreeModifiedEvent();
@@ -587,7 +599,7 @@
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es, AttachBehavior attachBehavior)
+void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& es)
{
RefPtr<ContainerNode> protect(this);
@@ -635,13 +647,13 @@
appendChildToContainer(child, this);
}
- updateTreeAfterInsertion(this, child, attachBehavior);
+ updateTreeAfterInsertion(this, child);
}
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
+void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild, AttachBehavior attachBehavior)
{
ASSERT(newChild);
ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
@@ -665,6 +677,8 @@
childrenChanged(true, last, 0, 1);
ChildNodeInsertionNotifier(this).notify(newChild.get());
+
+ attachAfterInsertion(newChild.get(), attachBehavior);
}
void ContainerNode::suspendPostAttachCallbacks()
@@ -891,7 +905,7 @@
if (renderStyle()->affectedByActive() || (isElementNode() && toElement(this)->childrenAffectedByActive()))
setNeedsStyleRecalc();
if (renderStyle()->hasAppearance())
- renderer()->theme()->stateChanged(renderer(), PressedState);
+ RenderTheme::theme().stateChanged(renderer(), PressedState);
}
}
@@ -919,7 +933,7 @@
if (renderStyle()->affectedByHover() || (isElementNode() && toElement(this)->childrenAffectedByHover()))
setNeedsStyleRecalc();
if (renderer() && renderer()->style()->hasAppearance())
- renderer()->theme()->stateChanged(renderer(), HoverState);
+ RenderTheme::theme().stateChanged(renderer(), HoverState);
}
}
@@ -1015,7 +1029,7 @@
}
}
-static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, AttachBehavior attachBehavior)
+static void updateTreeAfterInsertion(ContainerNode* parent, Node* child)
{
ASSERT(parent->refCount());
ASSERT(child->refCount());
@@ -1026,14 +1040,8 @@
ChildNodeInsertionNotifier(parent).notify(child);
- // FIXME: Attachment should be the first operation in this function, but some code
- // (for example, HTMLFormControlElement's autofocus support) requires this ordering.
- if (parent->attached() && !child->attached() && child->parentNode() == parent) {
- if (attachBehavior == AttachLazily)
- child->lazyAttach();
- else
- child->attach();
- }
+ // FIXME: Decide if it's safe to go through ::insertedInto while aleady attached() and then move this first.
+ attachAfterInsertion(child);
dispatchChildInsertionEvents(child);
}
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index f795436..7ed7733 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -99,17 +99,17 @@
unsigned childNodeCount() const;
Node* childNode(unsigned index) const;
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+ void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState& = ASSERT_NO_EXCEPTION);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+ void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
// These methods are only used during parsing.
// They don't send DOM mutation events or handle reparenting.
// However, arbitrary code may be run by beforeload handlers.
- void parserAppendChild(PassRefPtr<Node>);
+ void parserAppendChild(PassRefPtr<Node>, AttachBehavior = AttachLazily);
void parserRemoveChild(Node*);
- void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
+ void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild, AttachBehavior = AttachLazily);
void removeChildren();
void takeAllChildrenFrom(ContainerNode*);
diff --git a/Source/core/dom/ContextLifecycleNotifier.cpp b/Source/core/dom/ContextLifecycleNotifier.cpp
index f00e431..205380d 100644
--- a/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -42,23 +42,23 @@
{
}
-void ContextLifecycleNotifier::addObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void ContextLifecycleNotifier::addObserver(LifecycleObserver* observer)
{
- LifecycleNotifier::addObserver(observer, type);
+ LifecycleNotifier::addObserver(observer);
RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
- if (type == LifecycleObserver::ActiveDOMObjectType) {
+ if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
m_activeDOMObjects.add(static_cast<ActiveDOMObject*>(observer));
}
}
-void ContextLifecycleNotifier::removeObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void ContextLifecycleNotifier::removeObserver(LifecycleObserver* observer)
{
- LifecycleNotifier::removeObserver(observer, type);
+ LifecycleNotifier::removeObserver(observer);
RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
- if (type == LifecycleObserver::ActiveDOMObjectType) {
+ if (observer->observerType() == LifecycleObserver::ActiveDOMObjectType) {
RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
m_activeDOMObjects.remove(static_cast<ActiveDOMObject*>(observer));
}
diff --git a/Source/core/dom/ContextLifecycleNotifier.h b/Source/core/dom/ContextLifecycleNotifier.h
index 04801e4..42a61f3 100644
--- a/Source/core/dom/ContextLifecycleNotifier.h
+++ b/Source/core/dom/ContextLifecycleNotifier.h
@@ -48,8 +48,8 @@
const ActiveDOMObjectSet& activeDOMObjects() const { return m_activeDOMObjects; }
- virtual void addObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
- virtual void removeObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
+ virtual void addObserver(LifecycleObserver*) OVERRIDE;
+ virtual void removeObserver(LifecycleObserver*) OVERRIDE;
void notifyResumingActiveDOMObjects();
void notifySuspendingActiveDOMObjects(ActiveDOMObject::ReasonForSuspension);
diff --git a/Source/core/dom/ContextLifecycleObserver.cpp b/Source/core/dom/ContextLifecycleObserver.cpp
index baaa37c..be2d6c4 100644
--- a/Source/core/dom/ContextLifecycleObserver.cpp
+++ b/Source/core/dom/ContextLifecycleObserver.cpp
@@ -32,39 +32,17 @@
namespace WebCore {
ContextLifecycleObserver::ContextLifecycleObserver(ScriptExecutionContext* scriptExecutionContext, Type type)
- : LifecycleObserver(scriptExecutionContext)
- , m_scriptExecutionContext(0)
+ : LifecycleObserver(scriptExecutionContext, type)
{
- observeContext(scriptExecutionContext, type);
}
ContextLifecycleObserver::~ContextLifecycleObserver()
{
- if (m_scriptExecutionContext)
- observeContext(0, GenericType);
}
-void ContextLifecycleObserver::observeContext(ScriptExecutionContext* scriptExecutionContext, Type as)
+ScriptExecutionContext* ContextLifecycleObserver::scriptExecutionContext() const
{
- if (m_scriptExecutionContext) {
- ASSERT(m_scriptExecutionContext->isContextThread());
- m_scriptExecutionContext->wasUnobservedBy(this, as);
- }
-
- m_scriptExecutionContext = scriptExecutionContext;
- m_lifecycleContext = scriptExecutionContext;
-
- if (m_scriptExecutionContext) {
- ASSERT(m_scriptExecutionContext->isContextThread());
- m_scriptExecutionContext->wasObservedBy(this, as);
- }
-}
-
-void ContextLifecycleObserver::contextDestroyed()
-{
- m_scriptExecutionContext = 0;
-
- LifecycleObserver::contextDestroyed();
+ return static_cast<ScriptExecutionContext*>(m_lifecycleContext);
}
} // namespace WebCore
diff --git a/Source/core/dom/ContextLifecycleObserver.h b/Source/core/dom/ContextLifecycleObserver.h
index a56b91c..c48a1ed 100644
--- a/Source/core/dom/ContextLifecycleObserver.h
+++ b/Source/core/dom/ContextLifecycleObserver.h
@@ -36,17 +36,10 @@
class ContextLifecycleObserver : public LifecycleObserver {
public:
explicit ContextLifecycleObserver(ScriptExecutionContext*, Type = GenericType);
-
- virtual void contextDestroyed() OVERRIDE;
-
- ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
+ ScriptExecutionContext* scriptExecutionContext() const;
protected:
virtual ~ContextLifecycleObserver();
-
- void observeContext(ScriptExecutionContext*, Type);
-
- ScriptExecutionContext* m_scriptExecutionContext;
};
} // namespace WebCore
diff --git a/Source/core/dom/CrossThreadTask.h b/Source/core/dom/CrossThreadTask.h
index 7a8761c..22864b8 100644
--- a/Source/core/dom/CrossThreadTask.h
+++ b/Source/core/dom/CrossThreadTask.h
@@ -31,7 +31,6 @@
#ifndef CrossThreadTask_h
#define CrossThreadTask_h
-#include <memory>
#include "core/dom/ScriptExecutionContext.h"
#include "core/platform/CrossThreadCopier.h"
#include "wtf/PassOwnPtr.h"
diff --git a/Source/core/dom/DecodedDataDocumentParser.cpp b/Source/core/dom/DecodedDataDocumentParser.cpp
index 7ceaabe..53c846b 100644
--- a/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -26,60 +26,11 @@
#include "config.h"
#include "core/dom/DecodedDataDocumentParser.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Document.h"
-#include "core/dom/Element.h"
#include "core/loader/TextResourceDecoder.h"
-#include "wtf/text/TextEncodingRegistry.h"
namespace WebCore {
-namespace {
-
-class TitleEncodingFixer {
-public:
- explicit TitleEncodingFixer(Document* document)
- : m_document(document)
- , m_firstEncoding(document->decoder()->encoding())
- {
- }
-
- // It's possible for the encoding of the document to change while we're decoding
- // data. That can only occur while we're processing the <head> portion of the
- // document. There isn't much user-visible content in the <head>, but there is
- // the <title> element. This function detects that situation and re-decodes the
- // document's title so that the user doesn't see an incorrectly decoded title
- // in the title bar.
- inline void fixTitleEncodingIfNeeded()
- {
- if (m_firstEncoding == m_document->decoder()->encoding())
- return; // In the common case, the encoding doesn't change and there isn't any work to do.
- fixTitleEncoding();
- }
-
-private:
- void fixTitleEncoding();
-
- Document* m_document;
- WTF::TextEncoding m_firstEncoding;
-};
-
-void TitleEncodingFixer::fixTitleEncoding()
-{
- RefPtr<Element> titleElement = m_document->titleElement();
- if (!titleElement
- || titleElement->firstElementChild()
- || m_firstEncoding != Latin1Encoding()
- || !titleElement->textContent().containsOnlyLatin1())
- return; // Either we don't have a title yet or something bizzare as happened and we give up.
- CString originalBytes = titleElement->textContent().latin1();
- OwnPtr<TextCodec> codec = newTextCodec(m_document->decoder()->encoding());
- String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
- titleElement->setTextContent(correctlyDecodedTitle, IGNORE_EXCEPTION);
-}
-
-}
-
DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
: DocumentParser(document)
{
@@ -90,11 +41,8 @@
if (!length)
return 0;
- TitleEncodingFixer encodingFixer(document());
-
String decoded = document()->decoder()->decode(data, length);
-
- encodingFixer.fixTitleEncodingIfNeeded();
+ document()->setEncoding(document()->decoder()->encoding());
if (decoded.isEmpty())
return 0;
@@ -113,6 +61,7 @@
if (!decoder)
return 0;
String remainingData = decoder->flush();
+ document()->setEncoding(document()->decoder()->encoding());
if (remainingData.isEmpty())
return 0;
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 9dfe1b6..bc0bd80 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -64,7 +64,6 @@
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/DocumentSharedObjectPool.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
@@ -90,6 +89,7 @@
#include "core/dom/ScriptRunner.h"
#include "core/dom/ScriptedAnimationController.h"
#include "core/dom/SelectorQuery.h"
+#include "core/dom/StyleSheetCollections.h"
#include "core/dom/TouchList.h"
#include "core/dom/TransformSource.h"
#include "core/dom/TreeWalker.h"
@@ -105,6 +105,7 @@
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLHeadElement.h"
@@ -176,6 +177,7 @@
#include "wtf/StdLibExtras.h"
#include "wtf/UnusedParam.h"
#include "wtf/text/StringBuffer.h"
+#include "wtf/text/TextEncodingRegistry.h"
using namespace std;
using namespace WTF;
@@ -300,7 +302,7 @@
if (!frame || !root)
return false;
- return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
+ return frame->editor().shouldBeginEditing(rangeOfContents(root).get());
}
static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
@@ -396,7 +398,7 @@
, m_domTreeVersion(++s_globalTreeVersion)
, m_listenerTypes(0)
, m_mutationObserverTypes(0)
- , m_styleSheetCollection(DocumentStyleSheetCollection::create(this))
+ , m_styleSheetCollections(StyleSheetCollections::create(this))
, m_visitedLinkState(VisitedLinkState::create(this))
, m_visuallyOrdered(false)
, m_readyState(Complete)
@@ -536,7 +538,7 @@
if (this == topDocument())
clearAXObjectCache();
- m_decoder = 0;
+ setDecoder(PassRefPtr<TextResourceDecoder>());
if (m_styleSheetList)
m_styleSheetList->detachFromDocument();
@@ -546,7 +548,7 @@
m_import = 0;
}
- m_styleSheetCollection.clear();
+ m_styleSheetCollections.clear();
if (m_elemSheet)
m_elemSheet->clearOwnerNode();
@@ -587,6 +589,7 @@
m_documentElement = 0;
m_contextFeatures = ContextFeatures::defaultSwitch();
m_userActionElements.documentDidRemoveLastRef();
+ m_associatedFormControls.clear();
detachParser();
@@ -647,8 +650,8 @@
selectorQueryCache()->invalidate();
if (inQuirksMode() != wasInQuirksMode) {
// All user stylesheets have to reparse using the different mode.
- m_styleSheetCollection->clearPageUserSheet();
- m_styleSheetCollection->invalidateInjectedStyleSheetCache();
+ m_styleSheetCollections->clearPageUserSheet();
+ m_styleSheetCollections->invalidateInjectedStyleSheetCache();
}
}
@@ -657,7 +660,7 @@
return inQuirksMode() ? "BackCompat" : "CSS1Compat";
}
-void Document::setDocType(PassRefPtr<DocumentType> docType)
+void Document::setDoctype(PassRefPtr<DocumentType> docType)
{
// This should never be called more than once.
ASSERT(!m_docType || !docType);
@@ -806,6 +809,10 @@
es.throwDOMException(NotSupportedError);
return 0;
}
+ if (data.find("]]>") != WTF::notFound) {
+ es.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
+ return 0;
+ }
return CDATASection::create(this, data);
}
@@ -1101,17 +1108,15 @@
}
m_readyState = readyState;
- dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false));
+ dispatchEvent(Event::create(eventNames().readystatechangeEvent));
}
-String Document::encoding() const
+String Document::encodingName() const
{
// TextEncoding::domName() returns a char*, no need to allocate a new
// String for it each time.
// FIXME: We should fix TextEncoding to speak AtomicString anyway.
- if (TextResourceDecoder* d = decoder())
- return AtomicString(d->encoding().domName());
- return String();
+ return AtomicString(m_encoding.domName());
}
String Document::defaultCharset() const
@@ -1126,6 +1131,7 @@
if (!decoder())
return;
decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
+ setEncoding(m_decoder->encoding());
}
void Document::setContentLanguage(const String& language)
@@ -1238,9 +1244,8 @@
* 3. Collapse internal whitespace.
*/
template <typename CharacterType>
-static inline StringWithDirection canonicalizedTitle(Document* document, const StringWithDirection& titleWithDirection)
+static inline String canonicalizedTitle(Document* document, const String& title)
{
- const String& title = titleWithDirection.string();
const CharacterType* characters = title.getCharacters<CharacterType>();
unsigned length = title.length();
unsigned i;
@@ -1256,7 +1261,7 @@
}
if (i == length)
- return StringWithDirection();
+ return String();
// Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
bool previousCharWasWS = false;
@@ -1281,32 +1286,30 @@
}
if (!builderIndex && buffer[builderIndex] == ' ')
- return StringWithDirection();
+ return String();
buffer.shrink(builderIndex + 1);
// Replace the backslashes with currency symbols if the encoding requires it.
document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
- return StringWithDirection(String::adopt(buffer), titleWithDirection.direction());
+ return String::adopt(buffer);
}
-void Document::updateTitle(const StringWithDirection& title)
+void Document::updateTitle(const String& title)
{
if (m_rawTitle == title)
return;
m_rawTitle = title;
- StringWithDirection oldTitle = m_title;
- if (m_rawTitle.string().isEmpty())
- m_title = StringWithDirection();
- else {
- if (m_rawTitle.string().is8Bit())
- m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
- else
- m_title = canonicalizedTitle<UChar>(this, m_rawTitle);
- }
+ String oldTitle = m_title;
+ if (m_rawTitle.isEmpty())
+ m_title = String();
+ else if (m_rawTitle.is8Bit())
+ m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
+ else
+ m_title = canonicalizedTitle<UChar>(this, m_rawTitle);
if (!m_frame || oldTitle == m_title)
return;
@@ -1327,8 +1330,7 @@
}
}
- // The DOM API has no method of specifying direction, so assume LTR.
- updateTitle(StringWithDirection(title, LTR));
+ updateTitle(title);
if (m_titleElement) {
ASSERT(isHTMLTitleElement(m_titleElement.get()));
@@ -1337,7 +1339,7 @@
}
}
-void Document::setTitleElement(const StringWithDirection& title, Element* titleElement)
+void Document::setTitleElement(const String& title, Element* titleElement)
{
if (titleElement != m_titleElement) {
if (m_titleElement || m_titleSetExplicitly)
@@ -1357,19 +1359,20 @@
m_titleElement = 0;
m_titleSetExplicitly = false;
+ // FIXME: This is broken for SVG.
// 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 (isHTMLTitleElement(e)) {
- HTMLTitleElement* titleElement = toHTMLTitleElement(e);
- setTitleElement(titleElement->textWithDirection(), titleElement);
- break;
- }
+ for (Element* element = headElement->firstElementChild(); element; element = element->nextElementSibling()) {
+ if (!isHTMLTitleElement(element))
+ continue;
+ HTMLTitleElement* title = toHTMLTitleElement(element);
+ setTitleElement(title->text(), title);
+ break;
}
}
if (!m_titleElement)
- updateTitle(StringWithDirection());
+ updateTitle(String());
}
PageVisibilityState Document::visibilityState() const
@@ -1395,7 +1398,7 @@
void Document::dispatchVisibilityStateChangeEvent()
{
- dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent, false, false));
+ dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent));
}
DOMSecurityPolicy* Document::securityPolicy()
@@ -1620,13 +1623,13 @@
// re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
// hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
- if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
- m_styleSheetCollection->updateActiveStyleSheets(FullStyleUpdate);
+ if (m_styleSheetCollections->needsUpdateActiveStylesheetsOnStyleRecalc())
+ m_styleSheetCollections->updateActiveStyleSheets(FullStyleUpdate);
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
- m_styleSheetCollection->setUsesRemUnit(true);
+ m_styleSheetCollections->setUsesRemUnit(true);
m_inStyleRecalc = true;
{
@@ -1673,15 +1676,15 @@
unscheduleStyleRecalc();
// FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
- // See DocumentStyleSheetCollection::updateActiveStyleSheets.
- if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
+ // See StyleSheetCollections::updateActiveStyleSheets.
+ if (m_styleSheetCollections->needsUpdateActiveStylesheetsOnStyleRecalc())
setNeedsStyleRecalc();
m_inStyleRecalc = false;
// Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
if (m_styleResolver)
- m_styleSheetCollection->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
+ m_styleSheetCollections->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
if (frameView) {
frameView->resumeScheduledEvents();
@@ -1741,8 +1744,6 @@
updateStyleIfNeeded();
- StackStats::LayoutCheckPoint layoutCheckPoint;
-
// Only do a layout if changes have occurred that make it necessary.
if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
frameView->layout();
@@ -1865,7 +1866,7 @@
if (Settings* docSettings = settings())
matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
- m_styleSheetCollection->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
+ m_styleSheetCollections->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
}
void Document::clearStyleResolver()
@@ -2340,7 +2341,7 @@
m_loadEventProgress = BeforeUnloadEventCompleted;
if (!beforeUnloadEvent->defaultPrevented())
defaultEventHandler(beforeUnloadEvent.get());
- if (beforeUnloadEvent->result().isNull())
+ if (beforeUnloadEvent->returnValue().isNull())
return true;
if (navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel) {
@@ -2348,7 +2349,7 @@
return true;
}
- String text = displayStringModifiedByEncoding(beforeUnloadEvent->result());
+ String text = displayStringModifiedByEncoding(beforeUnloadEvent->returnValue());
if (chrome.runBeforeUnloadConfirmPanel(text, m_frame)) {
navigatingDocument->m_didAllowNavigationViaBeforeUnloadConfirmationPanel = true;
return true;
@@ -2377,7 +2378,7 @@
// time into freed memory.
RefPtr<DocumentLoader> documentLoader = m_frame->loader()->provisionalDocumentLoader();
m_loadEventProgress = UnloadEventInProgress;
- RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent, false, false));
+ RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent));
if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
DocumentLoadTiming* timing = documentLoader->timing();
ASSERT(timing->navigationStart());
@@ -2704,7 +2705,7 @@
void Document::seamlessParentUpdatedStylesheets()
{
- m_styleSheetCollection->didModifySeamlessParentStyleSheet();
+ m_styleSheetCollections->didModifySeamlessParentStyleSheet();
styleResolverChanged(RecalcStyleImmediately);
}
@@ -2780,8 +2781,8 @@
// 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);
+ m_styleSheetCollections->setSelectedStylesheetSetName(content);
+ m_styleSheetCollections->setPreferredStylesheetSetName(content);
styleResolverChanged(RecalcStyleDeferred);
}
@@ -3104,17 +3105,17 @@
String Document::preferredStylesheetSet() const
{
- return m_styleSheetCollection->preferredStylesheetSetName();
+ return m_styleSheetCollections->preferredStylesheetSetName();
}
String Document::selectedStylesheetSet() const
{
- return m_styleSheetCollection->selectedStylesheetSetName();
+ return m_styleSheetCollections->selectedStylesheetSetName();
}
void Document::setSelectedStylesheetSet(const String& aString)
{
- m_styleSheetCollection->setSelectedStylesheetSetName(aString);
+ m_styleSheetCollections->setSelectedStylesheetSetName(aString);
styleResolverChanged(RecalcStyleDeferred);
}
@@ -3134,14 +3135,14 @@
}
m_didCalculateStyleResolver = true;
- bool needsRecalc = m_styleSheetCollection->updateActiveStyleSheets(updateMode);
+ bool needsRecalc = m_styleSheetCollections->updateActiveStyleSheets(updateMode);
if (updateType >= RecalcStyleDeferred) {
setNeedsStyleRecalc();
return;
}
- if (didLayoutWithPendingStylesheets() && !m_styleSheetCollection->hasPendingSheets()) {
+ if (didLayoutWithPendingStylesheets() && !m_styleSheetCollections->hasPendingSheets()) {
m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
if (renderer())
renderView()->repaintViewAndCompositedLayers();
@@ -3313,7 +3314,7 @@
}
if (oldFocusedElement->isRootEditableElement())
- frame()->editor()->didEndEditing();
+ frame()->editor().didEndEditing();
if (view()) {
Widget* oldWidget = widgetForElement(oldFocusedElement.get());
@@ -3362,7 +3363,7 @@
m_focusedElement->setFocus(true);
if (m_focusedElement->isRootEditableElement())
- frame()->editor()->didBeginEditing(m_focusedElement.get());
+ frame()->editor().didBeginEditing(m_focusedElement.get());
// eww, I suck. set the qt focus correctly
// ### find a better place in the code for this
@@ -3389,7 +3390,7 @@
cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
}
- if (!focusChangeBlocked)
+ if (!focusChangeBlocked && page())
page()->chrome().focusedNodeChanged(m_focusedElement.get());
SetFocusedElementDone:
@@ -3629,11 +3630,11 @@
addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
else if (eventType == eventNames().overflowchangedEvent)
addListenerType(OVERFLOWCHANGED_LISTENER);
- else if (eventType == eventNames().webkitAnimationStartEvent)
+ else if (eventType == eventNames().webkitAnimationStartEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationstartEvent))
addListenerType(ANIMATIONSTART_LISTENER);
- else if (eventType == eventNames().webkitAnimationEndEvent)
+ else if (eventType == eventNames().webkitAnimationEndEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationendEvent))
addListenerType(ANIMATIONEND_LISTENER);
- else if (eventType == eventNames().webkitAnimationIterationEvent)
+ else if (eventType == eventNames().webkitAnimationIterationEvent || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == eventNames().animationiterationEvent))
addListenerType(ANIMATIONITERATION_LISTENER);
else if (eventType == eventNames().webkitTransitionEndEvent || eventType == eventNames().transitionendEvent)
addListenerType(TRANSITIONEND_LISTENER);
@@ -3939,6 +3940,32 @@
void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
{
m_decoder = decoder;
+ setEncoding(m_decoder ? m_decoder->encoding() : WTF::TextEncoding());
+}
+
+void Document::setEncoding(const WTF::TextEncoding& encoding)
+{
+ if (m_encoding == encoding)
+ return;
+
+ // It's possible for the encoding of the document to change while we're decoding
+ // data. That can only occur while we're processing the <head> portion of the
+ // document. There isn't much user-visible content in the <head>, but there is
+ // the <title> element. This function detects that situation and re-decodes the
+ // document's title so that the user doesn't see an incorrectly decoded title
+ // in the title bar.
+ if (m_titleElement
+ && !m_titleElement->firstElementChild()
+ && m_encoding == Latin1Encoding()
+ && m_titleElement->textContent().containsOnlyLatin1()) {
+
+ CString originalBytes = m_titleElement->textContent().latin1();
+ OwnPtr<TextCodec> codec = newTextCodec(encoding);
+ String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+ m_titleElement->setTextContent(correctlyDecodedTitle, IGNORE_EXCEPTION);
+ }
+
+ m_encoding = encoding;
}
KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
@@ -3974,9 +4001,7 @@
return Editor::Command();
document->updateStyleIfNeeded();
-
- return frame->editor()->command(commandName,
- userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
+ return frame->editor().command(commandName, userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
}
bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
@@ -4227,7 +4252,7 @@
setParsing(false);
if (!m_documentTiming.domContentLoadedEventStart)
m_documentTiming.domContentLoadedEventStart = monotonicallyIncreasingTime();
- dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
+ dispatchEvent(Event::createBubble(eventNames().DOMContentLoadedEvent));
if (!m_documentTiming.domContentLoadedEventEnd)
m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
@@ -4441,6 +4466,25 @@
contentSecurityPolicy()->didReceiveHeaders(headers);
}
+bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, const String& contextURL, const WTF::OrdinalNumber& contextLine)
+{
+ if (!contentSecurityPolicy()->allowInlineEventHandlers(contextURL, contextLine))
+ return false;
+
+ // HTML says that inline script needs browsing context to create its execution environment.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
+ // Also, if the listening node came from other document, which happens on context-less event dispatching,
+ // we also need to ask the owner document of the node.
+ if (!m_frame)
+ return false;
+ if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript))
+ return false;
+ if (node && node->document() != this && !node->document()->allowInlineEventHandlers(node, listener, contextURL, contextLine))
+ return false;
+
+ return true;
+}
+
void Document::didUpdateSecurityOrigin()
{
if (!m_frame)
@@ -4742,6 +4786,13 @@
element->setIsInTopLayer(false);
}
+HTMLDialogElement* Document::activeModalDialog() const
+{
+ if (m_topLayerElements.isEmpty())
+ return 0;
+ return static_cast<HTMLDialogElement*>(m_topLayerElements.last().get());
+}
+
void Document::webkitExitPointerLock()
{
if (!page())
@@ -4874,9 +4925,7 @@
{
if (!m_touchEventTargets.get())
return;
- // TODO(rbyers): Re-enable this ASSERT - http://crbug.com/254203.
- // The known failure is benign, but the fix somehow causes a perf regression.
- // ASSERT(m_touchEventTargets->contains(handler));
+ ASSERT(m_touchEventTargets->contains(handler));
m_touchEventTargets->remove(handler);
if (Document* parent = parentDocument()) {
parent->didRemoveTouchEventHandler(this);
@@ -4899,9 +4948,12 @@
void Document::didRemoveEventTargetNode(Node* handler)
{
- if (m_touchEventTargets) {
- m_touchEventTargets->removeAll(handler);
- if ((handler == this || m_touchEventTargets->isEmpty()) && parentDocument())
+ if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
+ if (handler == this)
+ m_touchEventTargets->clear();
+ else
+ m_touchEventTargets->removeAll(handler);
+ if (m_touchEventTargets->isEmpty() && parentDocument())
parentDocument()->didRemoveEventTargetNode(this);
}
}
@@ -5180,7 +5232,7 @@
bool Document::haveStylesheetsLoaded() const
{
- return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;
+ return !m_styleSheetCollections->hasPendingSheets() || m_ignorePendingStylesheets;
}
Locale& Document::getCachedLocale(const AtomicString& locale)
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index f0145de..b5fc9e6 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -48,7 +48,6 @@
#include "core/page/PageVisibilityState.h"
#include "weborigin/ReferrerPolicy.h"
#include "core/platform/Timer.h"
-#include "core/platform/text/StringWithDirection.h"
#include "core/rendering/HitTestRequest.h"
#include "wtf/Deque.h"
#include "wtf/HashSet.h"
@@ -88,7 +87,6 @@
class DocumentMarkerController;
class DocumentParser;
class DocumentSharedObjectPool;
-class DocumentStyleSheetCollection;
class DocumentTimeline;
class DocumentType;
class Element;
@@ -103,6 +101,7 @@
class HTMLAllCollection;
class HTMLCanvasElement;
class HTMLCollection;
+class HTMLDialogElement;
class HTMLDocument;
class HTMLElement;
class HTMLFrameOwnerElement;
@@ -147,6 +146,7 @@
class Settings;
class StyleResolver;
class StyleSheet;
+class StyleSheetCollections;
class StyleSheetContents;
class StyleSheetList;
class Text;
@@ -290,7 +290,7 @@
DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
void setViewportArguments(const ViewportArguments& viewportArguments) { m_viewportArguments = viewportArguments; }
- ViewportArguments viewportArguments() const { return m_viewportArguments; }
+ const ViewportArguments& viewportArguments() const { return m_viewportArguments; }
#ifndef NDEBUG
bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
#endif
@@ -298,6 +298,7 @@
void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
+ void setDoctype(PassRefPtr<DocumentType>);
DocumentType* doctype() const { return m_docType.get(); }
DOMImplementation* implementation();
@@ -351,11 +352,11 @@
String defaultCharset() const;
- String inputEncoding() const { return Document::encoding(); }
- String charset() const { return Document::encoding(); }
- String characterSet() const { return Document::encoding(); }
+ String inputEncoding() const { return Document::encodingName(); }
+ String charset() const { return Document::encodingName(); }
+ String characterSet() const { return Document::encodingName(); }
- String encoding() const;
+ String encodingName() const;
void setCharset(const String&);
@@ -439,7 +440,7 @@
// This is a DOM function.
StyleSheetList* styleSheets();
- DocumentStyleSheetCollection* styleSheetCollection() { return m_styleSheetCollection.get(); }
+ StyleSheetCollections* styleSheetCollections() { return m_styleSheetCollections.get(); }
bool gotoAnchorNeededAfterStylesheetsLoad() { return m_gotoAnchorNeededAfterStylesheetsLoad; }
void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
@@ -762,14 +763,11 @@
HTMLIFrameElement* seamlessParentIFrame() const;
bool shouldDisplaySeamlesslyWithParent() const;
- // Used by DOM bindings; no direction known.
- String title() const { return m_title.string(); }
+ String title() const { return m_title; }
void setTitle(const String&);
- const StringWithDirection& titleWithDirection() const { return m_title; }
-
Element* titleElement() const { return m_titleElement.get(); }
- void setTitleElement(const StringWithDirection&, Element* titleElement);
+ void setTitleElement(const String& title, Element* titleElement);
void removeTitle(Element* titleElement);
String cookie(ExceptionState&) const;
@@ -857,8 +855,6 @@
void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
uint64_t domTreeVersion() const { return m_domTreeVersion; }
- void setDocType(PassRefPtr<DocumentType>);
-
enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
@@ -894,6 +890,9 @@
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
+ void setEncoding(const WTF::TextEncoding&);
+ const WTF::TextEncoding& encoding() const { return m_encoding; }
+
String displayStringModifiedByEncoding(const String&) const;
PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
void displayBufferModifiedByEncoding(LChar* buffer, unsigned len) const
@@ -921,6 +920,8 @@
void initSecurityContext(const DocumentInit&);
void initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders&);
+ bool allowInlineEventHandlers(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine);
+
void statePopped(PassRefPtr<SerializedScriptValue>);
enum LoadEventProgress {
@@ -1008,8 +1009,7 @@
PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionState&);
- // FIXME: When embedders switch to using WebDocument::registerEmbedderCustomElement, make the default name set StandardNames.
- ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::AllNames);
+ ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::StandardNames);
CustomElementRegistrationContext* registrationContext() { return m_registrationContext.get(); }
void setImport(HTMLImport*);
@@ -1045,7 +1045,7 @@
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; }
+ HTMLDialogElement* activeModalDialog() const;
const Document* templateDocument() const;
Document* ensureTemplateDocument();
@@ -1109,7 +1109,7 @@
virtual double timerAlignmentInterval() const;
- void updateTitle(const StringWithDirection&);
+ void updateTitle(const String&);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
@@ -1224,7 +1224,7 @@
MutationObserverOptions m_mutationObserverTypes;
- OwnPtr<DocumentStyleSheetCollection> m_styleSheetCollection;
+ OwnPtr<StyleSheetCollections> m_styleSheetCollections;
RefPtr<StyleSheetList> m_styleSheetList;
OwnPtr<FormController> m_formController;
@@ -1249,8 +1249,8 @@
// http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
unsigned m_ignoreDestructiveWriteCount;
- StringWithDirection m_title;
- StringWithDirection m_rawTitle;
+ String m_title;
+ String m_rawTitle;
bool m_titleSetExplicitly;
RefPtr<Element> m_titleElement;
@@ -1282,6 +1282,7 @@
String m_contentLanguage;
RefPtr<TextResourceDecoder> m_decoder;
+ WTF::TextEncoding m_encoding;
InheritedBool m_designMode;
diff --git a/Source/core/dom/DocumentLifecycleObserver.cpp b/Source/core/dom/DocumentLifecycleObserver.cpp
index ee45688..497d2ea 100644
--- a/Source/core/dom/DocumentLifecycleObserver.cpp
+++ b/Source/core/dom/DocumentLifecycleObserver.cpp
@@ -38,7 +38,6 @@
DocumentLifecycleObserver::~DocumentLifecycleObserver()
{
- observeContext(0, DocumentLifecycleObserverType);
}
DocumentLifecycleNotifier::DocumentLifecycleNotifier(ScriptExecutionContext* context)
@@ -46,24 +45,24 @@
{
}
-void DocumentLifecycleNotifier::addObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void DocumentLifecycleNotifier::addObserver(LifecycleObserver* observer)
{
- if (type == LifecycleObserver::DocumentLifecycleObserverType) {
+ if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
m_documentObservers.add(static_cast<DocumentLifecycleObserver*>(observer));
}
- ContextLifecycleNotifier::addObserver(observer, type);
+ ContextLifecycleNotifier::addObserver(observer);
}
-void DocumentLifecycleNotifier::removeObserver(LifecycleObserver* observer, LifecycleObserver::Type type)
+void DocumentLifecycleNotifier::removeObserver(LifecycleObserver* observer)
{
- if (type == LifecycleObserver::DocumentLifecycleObserverType) {
+ if (observer->observerType() == LifecycleObserver::DocumentLifecycleObserverType) {
RELEASE_ASSERT(m_iterating != IteratingOverDocumentObservers);
m_documentObservers.remove(static_cast<DocumentLifecycleObserver*>(observer));
}
- ContextLifecycleNotifier::removeObserver(observer, type);
+ ContextLifecycleNotifier::removeObserver(observer);
}
} // namespace WebCore
diff --git a/Source/core/dom/DocumentLifecycleObserver.h b/Source/core/dom/DocumentLifecycleObserver.h
index dd7d521..27f1a68 100644
--- a/Source/core/dom/DocumentLifecycleObserver.h
+++ b/Source/core/dom/DocumentLifecycleObserver.h
@@ -51,8 +51,8 @@
void notifyDocumentWasDetached();
void notifyDocumentWasDisposed();
- virtual void addObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
- virtual void removeObserver(LifecycleObserver*, LifecycleObserver::Type) OVERRIDE;
+ virtual void addObserver(LifecycleObserver*) OVERRIDE;
+ virtual void removeObserver(LifecycleObserver*) OVERRIDE;
private:
explicit DocumentLifecycleNotifier(ScriptExecutionContext*);
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index bbcbe43..3fa1ce5 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -3,11 +3,10 @@
* (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) 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) 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.
+ * 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
@@ -31,432 +30,157 @@
#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/Element.h"
#include "core/dom/ProcessingInstruction.h"
-#include "core/dom/ShadowTreeStyleSheetCollection.h"
-#include "core/dom/shadow/ShadowRoot.h"
+#include "core/dom/StyleSheetCollections.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"
namespace WebCore {
using namespace HTMLNames;
-DocumentStyleSheetCollection::DocumentStyleSheetCollection(Document* document)
- : m_document(document)
- , m_pendingStylesheets(0)
- , m_injectedStyleSheetCacheValid(false)
- , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
- , m_usesSiblingRules(false)
- , m_usesSiblingRulesOverride(false)
- , m_usesFirstLineRules(false)
- , m_usesFirstLetterRules(false)
- , m_usesBeforeAfterRules(false)
- , m_usesBeforeAfterRulesOverride(false)
- , m_usesRemUnits(false)
- , m_collectionForDocument(document)
- , m_needsDocumentStyleSheetsUpdate(true)
+DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope* treeScope)
+ : StyleSheetCollection(treeScope)
{
+ ASSERT(treeScope->rootNode() == treeScope->rootNode()->document());
}
-DocumentStyleSheetCollection::~DocumentStyleSheetCollection()
+void DocumentStyleSheetCollection::collectStyleSheets(StyleSheetCollections* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
{
- if (m_pageUserSheet)
- m_pageUserSheet->clearOwnerNode();
- for (unsigned i = 0; i < m_injectedUserStyleSheets.size(); ++i)
- m_injectedUserStyleSheets[i]->clearOwnerNode();
- for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
- m_injectedAuthorStyleSheets[i]->clearOwnerNode();
- for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
- m_userStyleSheets[i]->clearOwnerNode();
- for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
- m_authorStyleSheets[i]->clearOwnerNode();
-}
-
-void DocumentStyleSheetCollection::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeScope* treeScope)
-{
- if (treeScopes.isEmpty()) {
- treeScopes.add(treeScope);
- return;
- }
- if (treeScopes.contains(treeScope))
+ if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
return;
- TreeScopeSet::iterator begin = treeScopes.begin();
- TreeScopeSet::iterator end = treeScopes.end();
- TreeScopeSet::iterator it = end;
- TreeScope* followingTreeScope = 0;
- do {
- --it;
- TreeScope* n = *it;
- unsigned short position = n->comparePosition(treeScope);
- if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
- treeScopes.insertBefore(followingTreeScope, treeScope);
- 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 && !document()->isHTMLDocument()) {
+ // 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() && !pi->isLoading())
+ 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;
}
- followingTreeScope = n;
- } while (it != begin);
-
- treeScopes.insertBefore(followingTreeScope, treeScope);
-}
-
-StyleSheetCollection* DocumentStyleSheetCollection::ensureStyleSheetCollectionFor(TreeScope* treeScope)
-{
- if (treeScope == m_document)
- return &m_collectionForDocument;
-
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(treeScope, nullptr);
- if (result.isNewEntry)
- result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
- return result.iterator->value.get();
-}
-
-StyleSheetCollection* DocumentStyleSheetCollection::styleSheetCollectionFor(TreeScope* treeScope)
-{
- if (treeScope == m_document)
- return &m_collectionForDocument;
-
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(treeScope);
- if (it == m_styleSheetCollectionMap.end())
- return 0;
- return it->value.get();
-}
-
-const Vector<RefPtr<StyleSheet> >& DocumentStyleSheetCollection::styleSheetsForStyleSheetList()
-{
- return m_collectionForDocument.styleSheetsForStyleSheetList();
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::activeAuthorStyleSheets() const
-{
- return m_collectionForDocument.activeAuthorStyleSheets();
-}
-
-void DocumentStyleSheetCollection::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
-{
- activeAuthorStyleSheets.append(&m_collectionForDocument.activeAuthorStyleSheets());
-
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
- for (; it != end; ++it) {
- const StyleSheetCollection* collection = it->get();
- activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
+ if (sheet)
+ styleSheets.append(sheet);
+ if (activeSheet)
+ activeSheets.append(activeSheet);
}
}
-void DocumentStyleSheetCollection::combineCSSFeatureFlags(const RuleFeatureSet& features)
+static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
{
- // 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).
- m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
- m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules();
- m_usesBeforeAfterRules = m_usesBeforeAfterRules || features.usesBeforeAfterRules();
-}
-
-void DocumentStyleSheetCollection::resetCSSFeatureFlags(const RuleFeatureSet& features)
-{
- m_usesSiblingRules = features.usesSiblingRules();
- m_usesFirstLineRules = features.usesFirstLineRules();
- m_usesBeforeAfterRules = features.usesBeforeAfterRules();
-}
-
-CSSStyleSheet* DocumentStyleSheetCollection::pageUserSheet()
-{
- if (m_pageUserSheet)
- return m_pageUserSheet.get();
-
- Page* owningPage = m_document->page();
- if (!owningPage)
- return 0;
-
- String userSheetText = owningPage->userStyleSheet();
- if (userSheetText.isEmpty())
- return 0;
-
- // Parse the sheet and cache it.
- m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
- m_pageUserSheet->contents()->setIsUserStyleSheet(true);
- m_pageUserSheet->contents()->parseString(userSheetText);
- return m_pageUserSheet.get();
-}
-
-void DocumentStyleSheetCollection::clearPageUserSheet()
-{
- if (m_pageUserSheet) {
- RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
- m_pageUserSheet = 0;
- m_document->removedStyleSheet(removedSheet.get());
- }
-}
-
-void DocumentStyleSheetCollection::updatePageUserSheet()
-{
- clearPageUserSheet();
- // FIXME: Why is this immediately and not defer?
- if (StyleSheet* addedSheet = pageUserSheet())
- m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::injectedUserStyleSheets() const
-{
- updateInjectedStyleSheetCache();
- return m_injectedUserStyleSheets;
-}
-
-const Vector<RefPtr<CSSStyleSheet> >& DocumentStyleSheetCollection::injectedAuthorStyleSheets() const
-{
- updateInjectedStyleSheetCache();
- return m_injectedAuthorStyleSheets;
-}
-
-void DocumentStyleSheetCollection::updateInjectedStyleSheetCache() const
-{
- if (m_injectedStyleSheetCacheValid)
+ HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
+ if (!seamlessParentIFrame)
return;
- m_injectedStyleSheetCacheValid = true;
- m_injectedUserStyleSheets.clear();
- m_injectedAuthorStyleSheets.clear();
-
- Page* owningPage = m_document->page();
- if (!owningPage)
- return;
-
- const PageGroup& pageGroup = owningPage->group();
- const UserStyleSheetVector& sheets = pageGroup.userStyleSheets();
- for (unsigned i = 0; i < sheets.size(); ++i) {
- const UserStyleSheet* sheet = sheets[i].get();
- if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document->ownerElement())
- continue;
- if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
- continue;
- RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
- bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
- if (isUserStyleSheet)
- m_injectedUserStyleSheets.append(groupSheet);
- else
- m_injectedAuthorStyleSheets.append(groupSheet);
- groupSheet->contents()->setIsUserStyleSheet(isUserStyleSheet);
- groupSheet->contents()->parseString(sheet->source());
- }
+ sheets.append(seamlessParentIFrame->document()->styleSheetCollections()->activeAuthorStyleSheets());
}
-void DocumentStyleSheetCollection::invalidateInjectedStyleSheetCache()
+bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleSheetCollections* collections, StyleResolverUpdateMode updateMode)
{
- m_injectedStyleSheetCacheValid = false;
- m_needsDocumentStyleSheetsUpdate = true;
- // FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
- // and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
- m_document->styleResolverChanged(RecalcStyleDeferred);
-}
+ Vector<RefPtr<StyleSheet> > styleSheets;
+ Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
+ activeCSSStyleSheets.append(collections->injectedAuthorStyleSheets());
+ activeCSSStyleSheets.append(collections->documentAuthorStyleSheets());
+ collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, document());
+ collectStyleSheets(collections, styleSheets, activeCSSStyleSheets);
-void DocumentStyleSheetCollection::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
-{
- ASSERT(!authorSheet->isUserStyleSheet());
- m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
- m_document->addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
- m_needsDocumentStyleSheetsUpdate = true;
-}
+ StyleResolverUpdateType styleResolverUpdateType;
+ bool requiresFullStyleRecalc;
+ analyzeStyleSheetChange(updateMode, activeAuthorStyleSheets(), activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
-void DocumentStyleSheetCollection::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
-{
- ASSERT(userSheet->isUserStyleSheet());
- m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
- m_document->addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
- m_needsDocumentStyleSheetsUpdate = true;
-}
-
-// This method is called whenever a top-level stylesheet has finished loading.
-void DocumentStyleSheetCollection::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
-{
- // Make sure we knew this sheet was pending, and that our count isn't out of sync.
- ASSERT(m_pendingStylesheets > 0);
-
- m_pendingStylesheets--;
-
- TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? styleSheetCandidateNode->treeScope() : m_document;
- if (treeScope == m_document)
- m_needsDocumentStyleSheetsUpdate = true;
- else
- m_dirtyTreeScopes.add(treeScope);
-
- if (m_pendingStylesheets)
- return;
-
- if (notification == RemovePendingSheetNotifyLater) {
- 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;
-
- TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
- ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
-
- StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
- ASSERT(collection);
- collection->addStyleSheetCandidateNode(node, createdByParser);
-
- if (treeScope == m_document) {
- m_needsDocumentStyleSheetsUpdate = true;
- return;
- }
-
- insertTreeScopeInDocumentOrder(m_activeTreeScopes, treeScope);
- m_dirtyTreeScopes.add(treeScope);
-}
-
-void DocumentStyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
-{
- TreeScope* treeScope = scopingNode ? scopingNode->treeScope() : m_document;
- ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
-
- StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
- ASSERT(collection);
- collection->removeStyleSheetCandidateNode(node, scopingNode);
-
- if (treeScope == m_document) {
- m_needsDocumentStyleSheetsUpdate = true;
- return;
- }
- m_dirtyTreeScopes.add(treeScope);
- m_activeTreeScopes.remove(treeScope);
-}
-
-void DocumentStyleSheetCollection::modifiedStyleSheetCandidateNode(Node* node)
-{
- if (!node->inDocument())
- return;
-
- TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
- ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
- if (treeScope == m_document) {
- m_needsDocumentStyleSheetsUpdate = true;
- return;
- }
- m_dirtyTreeScopes.add(treeScope);
-}
-
-bool DocumentStyleSheetCollection::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
-{
- return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
-}
-
-bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
-{
- if (m_document->inStyleRecalc()) {
- // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
- // https://bugs.webkit.org/show_bug.cgi?id=54344
- // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
- m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
- return false;
-
- }
- if (!m_document->renderer() || !m_document->attached())
- return false;
-
- bool requiresFullStyleRecalc = false;
- if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate)
- requiresFullStyleRecalc = m_collectionForDocument.updateActiveStyleSheets(this, updateMode);
-
- if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
- TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
- HashSet<TreeScope*> treeScopesRemoved;
-
- for (TreeScopeSet::iterator it = treeScopes.begin(); it != treeScopes.end(); ++it) {
- TreeScope* treeScope = *it;
- ASSERT(treeScope != m_document);
- ShadowTreeStyleSheetCollection* collection = static_cast<ShadowTreeStyleSheetCollection*>(styleSheetCollectionFor(treeScope));
- ASSERT(collection);
- collection->updateActiveStyleSheets(this, updateMode);
- if (!collection->hasStyleSheetCandidateNodes())
- treeScopesRemoved.add(treeScope);
+ if (styleResolverUpdateType == Reconstruct) {
+ document()->clearStyleResolver();
+ } else {
+ StyleResolver* styleResolver = document()->styleResolverIfExists();
+ ASSERT(styleResolver);
+ // FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
+ // Need to change "false" to some valid condition.
+ styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
+ if (styleResolverUpdateType == Reset) {
+ resetAllRuleSetsInTreeScope(styleResolver);
+ styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
+ } else {
+ ASSERT(styleResolverUpdateType == Additive);
+ styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
}
- if (!treeScopesRemoved.isEmpty())
- for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
- m_activeTreeScopes.remove(*it);
- m_dirtyTreeScopes.clear();
}
-
- if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) {
- styleResolver->finishAppendAuthorStyleSheets();
- resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
- }
-
- m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
- activeStyleSheetsUpdatedForInspector();
- m_usesRemUnits = m_collectionForDocument.usesRemUnits();
-
- if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
- m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
- m_needsDocumentStyleSheetsUpdate = false;
- }
+ m_scopingNodesForStyleScoped.didRemoveScopingNodes();
+ m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
+ m_styleSheetsForStyleSheetList.swap(styleSheets);
+ updateUsesRemUnits();
return requiresFullStyleRecalc;
}
-void DocumentStyleSheetCollection::activeStyleSheetsUpdatedForInspector()
-{
- if (m_activeTreeScopes.isEmpty()) {
- InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_collectionForDocument.styleSheetsForStyleSheetList());
- return;
- }
- Vector<RefPtr<StyleSheet> > activeStyleSheets;
-
- activeStyleSheets.append(m_collectionForDocument.styleSheetsForStyleSheetList());
-
- TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
- TreeScopeSet::iterator end = m_activeTreeScopes.end();
- for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
- activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
- }
-
- // FIXME: Inspector needs a vector which has all active stylesheets.
- // However, creating such a large vector might cause performance regression.
- // Need to implement some smarter solution.
- InspectorInstrumentation::activeStyleSheetsUpdated(m_document, activeStyleSheets);
-}
-
-void DocumentStyleSheetCollection::didRemoveShadowRoot(ShadowRoot* shadowRoot)
-{
- m_styleSheetCollectionMap.remove(shadowRoot);
-}
-
-void DocumentStyleSheetCollection::appendActiveAuthorStyleSheets(StyleResolver* styleResolver)
-{
- ASSERT(styleResolver);
-
- styleResolver->setBuildScopedStyleTreeInDocumentOrder(true);
- styleResolver->appendAuthorStyleSheets(0, m_collectionForDocument.activeAuthorStyleSheets());
-
- TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
- TreeScopeSet::iterator end = m_activeTreeScopes.end();
- for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
- styleResolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
- styleResolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
- }
- }
- styleResolver->finishAppendAuthorStyleSheets();
- styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
-}
-
}
diff --git a/Source/core/dom/DocumentStyleSheetCollection.h b/Source/core/dom/DocumentStyleSheetCollection.h
index 2dd47c5..4072cc8 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/Source/core/dom/DocumentStyleSheetCollection.h
@@ -6,7 +6,7 @@
* 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.
+ * 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
@@ -28,136 +28,25 @@
#ifndef DocumentStyleSheetCollection_h
#define DocumentStyleSheetCollection_h
-#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"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
class CSSStyleSheet;
-class Node;
-class RuleFeatureSet;
class StyleSheet;
-class StyleSheetContents;
-class StyleSheetList;
+class StyleSheetCollection;
+class StyleSheetCollections;
+class TreeScope;
-class DocumentStyleSheetCollection {
- WTF_MAKE_FAST_ALLOCATED;
+class DocumentStyleSheetCollection FINAL : public StyleSheetCollection {
+ WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<DocumentStyleSheetCollection> create(Document* document) { return adoptPtr(new DocumentStyleSheetCollection(document)); }
+ explicit DocumentStyleSheetCollection(TreeScope*);
- ~DocumentStyleSheetCollection();
-
- const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList();
- const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
-
- CSSStyleSheet* pageUserSheet();
- const Vector<RefPtr<CSSStyleSheet> >& documentUserStyleSheets() const { return m_userStyleSheets; }
- const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
- const Vector<RefPtr<CSSStyleSheet> >& injectedUserStyleSheets() const;
- const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
-
- void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
- void modifiedStyleSheetCandidateNode(Node*);
-
- void clearPageUserSheet();
- void updatePageUserSheet();
- void invalidateInjectedStyleSheetCache();
- void updateInjectedStyleSheetCache() const;
-
- void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
- void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
-
- bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
-
- bool updateActiveStyleSheets(StyleResolverUpdateMode);
-
- String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
- String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
- void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
- void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
-
- void addPendingSheet() { m_pendingStylesheets++; }
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
- void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
-
- bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
-
- bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
- void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
- bool usesFirstLineRules() const { return m_usesFirstLineRules; }
- bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
- void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
- bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
- void setUsesBeforeAfterRulesOverride(bool b) { m_usesBeforeAfterRulesOverride = b; }
- bool usesRemUnits() const { return m_usesRemUnits; }
- void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
- bool hasScopedStyleSheet() { return m_collectionForDocument.scopingNodesForStyleScoped(); }
-
- void combineCSSFeatureFlags(const RuleFeatureSet&);
- void resetCSSFeatureFlags(const RuleFeatureSet&);
-
- void didModifySeamlessParentStyleSheet() { m_needsDocumentStyleSheetsUpdate = true; }
- void didRemoveShadowRoot(ShadowRoot*);
- void appendActiveAuthorStyleSheets(StyleResolver*);
- void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
+ bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
private:
- DocumentStyleSheetCollection(Document*);
-
- StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope*);
- StyleSheetCollection* styleSheetCollectionFor(TreeScope*);
- void activeStyleSheetsUpdatedForInspector();
- bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
-
- typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
- static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
-
- Document* m_document;
-
- // 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
- // elements and when it is safe to execute scripts.
- int m_pendingStylesheets;
-
- RefPtr<CSSStyleSheet> m_pageUserSheet;
-
- mutable Vector<RefPtr<CSSStyleSheet> > m_injectedUserStyleSheets;
- mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
- mutable bool m_injectedStyleSheetCacheValid;
-
- Vector<RefPtr<CSSStyleSheet> > m_userStyleSheets;
- Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
-
- bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
-
- StyleSheetCollectionForDocument m_collectionForDocument;
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
-
- TreeScopeSet m_dirtyTreeScopes;
- TreeScopeSet m_activeTreeScopes;
- bool m_needsDocumentStyleSheetsUpdate;
-
- String m_preferredStylesheetSetName;
- String m_selectedStylesheetSetName;
-
- bool m_usesSiblingRules;
- bool m_usesSiblingRulesOverride;
- bool m_usesFirstLineRules;
- bool m_usesFirstLetterRules;
- bool m_usesBeforeAfterRules;
- bool m_usesBeforeAfterRulesOverride;
- bool m_usesRemUnits;
+ void collectStyleSheets(StyleSheetCollections*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
};
}
diff --git a/Source/core/dom/DocumentType.cpp b/Source/core/dom/DocumentType.cpp
index e85936b..12fbd2f 100644
--- a/Source/core/dom/DocumentType.cpp
+++ b/Source/core/dom/DocumentType.cpp
@@ -60,24 +60,18 @@
Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* insertionPoint)
{
Node::insertedInto(insertionPoint);
- if (!insertionPoint->inDocument())
- return InsertionDone;
- // Our document node can be null if we were created by a DOMImplementation. We use the parent() instead.
- ASSERT(parentNode() && parentNode()->isDocumentNode());
- if (parentNode() && parentNode()->isDocumentNode()) {
- Document* doc = toDocument(parentNode());
- if (!doc->doctype())
- doc->setDocType(this);
- }
+ // DocumentType can only be inserted into a Document.
+ ASSERT(parentNode()->isDocumentNode());
+
+ document()->setDoctype(this);
return InsertionDone;
}
void DocumentType::removedFrom(ContainerNode* insertionPoint)
{
- if (insertionPoint->inDocument() && document() && document()->doctype() == this)
- document()->setDocType(0);
+ document()->setDoctype(0);
Node::removedFrom(insertionPoint);
}
diff --git a/Source/core/dom/DocumentType.h b/Source/core/dom/DocumentType.h
index aefc21d..0ad56fa 100644
--- a/Source/core/dom/DocumentType.h
+++ b/Source/core/dom/DocumentType.h
@@ -37,9 +37,10 @@
return adoptRef(new DocumentType(document, name, publicId, systemId));
}
- // FIXME: We never fill m_entities and m_notations. Current implementation of NamedNodeMap doesn't work without an associated Element yet.
- NamedNodeMap* entities() const { return m_entities.get(); }
- NamedNodeMap* notations() const { return m_notations.get(); }
+ // FIXME: These wre removed from DOM4, we should add a UseCounter and see if
+ // we can remove them since they never worked anyway.
+ NamedNodeMap* entities() const { return 0; }
+ NamedNodeMap* notations() const { return 0; }
const String& name() const { return m_name; }
const String& publicId() const { return m_publicId; }
@@ -49,17 +50,14 @@
private:
DocumentType(Document*, const String& name, const String& publicId, const String& systemId);
- virtual KURL baseURI() const;
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep);
+ virtual KURL baseURI() const OVERRIDE;
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- OwnPtr<NamedNodeMap> m_entities;
- OwnPtr<NamedNodeMap> m_notations;
-
String m_name;
String m_publicId;
String m_systemId;
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 9577774..ce5e91a 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -35,6 +35,7 @@
#include "bindings/v8/ExceptionState.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/animation/DocumentTimeline.h"
+#include "core/animation/css/CSSAnimations.h"
#include "core/css/CSSParser.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValuePool.h"
@@ -1449,64 +1450,75 @@
if (hasCustomStyleCallbacks())
willRecalcStyle(change);
- // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
- RefPtr<RenderStyle> currentStyle = renderStyle();
- bool hasParentStyle = static_cast<bool>(parentRenderStyle());
- bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
- bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
if (hasRareData() && (change > NoChange || needsStyleRecalc())) {
ElementRareData* data = elementRareData();
data->resetStyleState();
data->clearComputedStyle();
}
- if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
- StyleChange localChange = Detach;
- RefPtr<RenderStyle> newStyle;
- if (currentStyle) {
- newStyle = styleForRenderer();
- localChange = Node::diff(currentStyle.get(), newStyle.get(), document());
- } else if (attached() && isActiveInsertionPoint(this)) {
- // Active InsertionPoints will never have renderers so there's no reason to
- // reattach them repeatedly once they're already attached.
- localChange = change;
- }
- if (localChange == Detach) {
- AttachContext reattachContext;
- reattachContext.resolvedStyle = newStyle.get();
- reattach(reattachContext);
+ // Active InsertionPoints have no renderers so they never need to go through a recalc.
+ if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(this))
+ change = recalcOwnStyle(change);
- if (hasCustomStyleCallbacks())
- didRecalcStyle(change);
- return true;
- }
+ // If we reattached we don't need to recalc the style of our descendants anymore.
+ if (change < Reattach)
+ recalcChildStyle(change);
- InspectorInstrumentation::didRecalculateStyleForElement(this);
+ clearNeedsStyleRecalc();
+ clearChildNeedsStyleRecalc();
- if (RenderObject* renderer = this->renderer()) {
- 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
- // fooled into believing this style is the same.
- renderer->setStyleInternal(newStyle.get());
- }
- }
+ if (hasCustomStyleCallbacks())
+ didRecalcStyle(change);
- // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
- // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
- if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
- // Cached RenderStyles may depend on the re units.
- document()->styleResolver()->invalidateMatchedPropertiesCache();
- change = Force;
- }
+ return change == Reattach;
+}
- if (styleChangeType() >= SubtreeStyleChange)
- change = Force;
- else if (change != Force)
- change = localChange;
+Node::StyleChange Element::recalcOwnStyle(StyleChange change)
+{
+ ASSERT(document()->inStyleRecalc());
+
+ CSSAnimationUpdateScope cssAnimationUpdateScope(this);
+ RefPtr<RenderStyle> oldStyle = renderStyle();
+ RefPtr<RenderStyle> newStyle = styleForRenderer();
+ StyleChange localChange = oldStyle ? Node::diff(oldStyle.get(), newStyle.get(), document()) : Reattach;
+
+ if (localChange == Reattach) {
+ AttachContext reattachContext;
+ reattachContext.resolvedStyle = newStyle.get();
+ reattach(reattachContext);
+ return Reattach;
}
+
+ InspectorInstrumentation::didRecalculateStyleForElement(this);
+
+ if (RenderObject* renderer = this->renderer()) {
+ if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.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
+ // fooled into believing this style is the same.
+ renderer->setStyleInternal(newStyle.get());
+ }
+ }
+
+ // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
+ // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
+ if (document()->styleSheetCollections()->usesRemUnits() && document()->documentElement() == this && oldStyle && newStyle && oldStyle->fontSize() != newStyle->fontSize()) {
+ // Cached RenderStyles may depend on the re units.
+ document()->styleResolver()->invalidateMatchedPropertiesCache();
+ return Force;
+ }
+
+ if (styleChangeType() >= SubtreeStyleChange)
+ return Force;
+
+ return max(localChange, change);
+}
+
+void Element::recalcChildStyle(StyleChange change)
+{
+ ASSERT(document()->inStyleRecalc());
+
StyleResolverParentPusher parentPusher(this);
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
@@ -1522,6 +1534,8 @@
// FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
// For now we will just worry about the common case, since it's a lot trickier to get the second case right
// without doing way too much re-resolution.
+ bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+ bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
bool forceCheckOfNextElementSibling = false;
bool forceCheckOfAnyElementSibling = false;
bool forceReattachOfAnyWhitespaceSibling = false;
@@ -1560,13 +1574,6 @@
updatePseudoElement(AFTER, change);
updatePseudoElement(BACKDROP, change);
}
-
- clearNeedsStyleRecalc();
- clearChildNeedsStyleRecalc();
-
- if (hasCustomStyleCallbacks())
- didRecalcStyle(change);
- return false;
}
ElementShadow* Element::shadow() const
@@ -1636,11 +1643,6 @@
return shadowRoot;
}
-bool Element::supportsShadowElementForUserAgentShadow() const
-{
- return true;
-}
-
bool Element::childTypeAllowed(NodeType type) const
{
switch (type) {
@@ -2463,9 +2465,6 @@
void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
{
- if ((pseudoId == BEFORE || pseudoId == AFTER) && !document()->styleSheetCollection()->usesBeforeAfterRules())
- return;
-
if (pseudoId == BACKDROP && !isInTopLayer())
return;
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 556fe4f..1b35d58 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -447,7 +447,6 @@
ShadowRoot* userAgentShadowRoot() const;
ShadowRoot* ensureUserAgentShadowRoot();
- virtual bool supportsShadowElementForUserAgentShadow() const;
virtual const AtomicString& shadowPseudoId() const { return !part().isEmpty() ? part() : pseudo(); }
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
@@ -664,7 +663,7 @@
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void removeAllEventListeners() OVERRIDE FINAL;
+ virtual void removeAllEventListeners() OVERRIDE;
virtual void willRecalcStyle(StyleChange);
virtual void didRecalcStyle(StyleChange);
@@ -698,6 +697,9 @@
void setInlineStyleFromString(const AtomicString&);
MutableStylePropertySet* ensureMutableInlineStyle();
+ StyleChange recalcOwnStyle(StyleChange);
+ void recalcChildStyle(StyleChange);
+
void makePresentationAttributeCacheKey(PresentationAttributeCacheKey&) const;
void rebuildPresentationAttributeStyle();
diff --git a/Source/core/dom/Event.cpp b/Source/core/dom/Event.cpp
index 1b714f7..5b653df 100644
--- a/Source/core/dom/Event.cpp
+++ b/Source/core/dom/Event.cpp
@@ -148,18 +148,14 @@
return false;
}
-bool Event::storesResultAsString() const
-{
- return false;
-}
-
bool Event::isBeforeTextInsertedEvent() const
{
return false;
}
-void Event::storeResult(const String&)
+bool Event::isBeforeUnloadEvent() const
{
+ return false;
}
void Event::setTarget(PassRefPtr<EventTarget> target)
diff --git a/Source/core/dom/Event.h b/Source/core/dom/Event.h
index 7875b1e..f867528 100644
--- a/Source/core/dom/Event.h
+++ b/Source/core/dom/Event.h
@@ -76,6 +76,22 @@
{
return adoptRef(new Event);
}
+
+ // A factory for a simple event. The event doesn't bubble, and isn't
+ // cancelable.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#fire-a-simple-event
+ static PassRefPtr<Event> create(const AtomicString& type)
+ {
+ return adoptRef(new Event(type, false, false));
+ }
+ static PassRefPtr<Event> createCancelable(const AtomicString& type)
+ {
+ return adoptRef(new Event(type, false, true));
+ }
+ static PassRefPtr<Event> createBubble(const AtomicString& type)
+ {
+ return adoptRef(new Event(type, true, false));
+ }
static PassRefPtr<Event> create(const AtomicString& type, bool canBubble, bool cancelable)
{
return adoptRef(new Event(type, canBubble, cancelable));
@@ -112,8 +128,8 @@
// IE Extensions
EventTarget* srcElement() const { return target(); } // MSIE extension - "the object that fired the event"
- bool returnValue() const { return !defaultPrevented(); }
- void setReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
+ bool legacyReturnValue() const { return !defaultPrevented(); }
+ void setLegacyReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
Clipboard* clipboardData() const { return isClipboardEvent() ? clipboard() : 0; }
@@ -134,6 +150,8 @@
virtual bool isClipboardEvent() const;
virtual bool isBeforeTextInsertedEvent() const;
+ virtual bool isBeforeUnloadEvent() const;
+
bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; }
bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
@@ -157,9 +175,6 @@
EventPath& eventPath() { return m_eventPath; }
PassRefPtr<NodeList> path() const;
- virtual bool storesResultAsString() const;
- virtual void storeResult(const String&);
-
virtual Clipboard* clipboard() const { return 0; }
bool isBeingDispatched() const { return eventPhase(); }
diff --git a/Source/core/dom/Event.idl b/Source/core/dom/Event.idl
index 74af6e1..88d704f 100644
--- a/Source/core/dom/Event.idl
+++ b/Source/core/dom/Event.idl
@@ -69,7 +69,7 @@
// IE Extensions
readonly attribute EventTarget srcElement;
- attribute boolean returnValue;
+ [ImplementedAs=legacyReturnValue, DeprecateAs=EventReturnValue] attribute boolean returnValue;
attribute boolean cancelBubble;
[EnabledAtRuntime=ShadowDOM] readonly attribute NodeList path;
diff --git a/Source/core/dom/EventAliases.in b/Source/core/dom/EventAliases.in
index 07c2e49..a4b61c2 100644
--- a/Source/core/dom/EventAliases.in
+++ b/Source/core/dom/EventAliases.in
@@ -1,4 +1,5 @@
# Aliases
+AnimationEvent ImplementedAs=WebKitAnimationEvent, EnabledAtRuntime=cssAnimationUnprefixedEnabled
Events ImplementedAs=Event
HTMLEvents ImplementedAs=Event
KeyboardEvents ImplementedAs=KeyboardEvent
diff --git a/Source/core/dom/EventListenerMap.cpp b/Source/core/dom/EventListenerMap.cpp
index ad0b72b..35af02f 100644
--- a/Source/core/dom/EventListenerMap.cpp
+++ b/Source/core/dom/EventListenerMap.cpp
@@ -38,7 +38,7 @@
#include "wtf/Vector.h"
#ifndef NDEBUG
-#include "wtf/Threading.h"
+#include "wtf/ThreadingPrimitives.h"
#endif
using namespace WTF;
diff --git a/Source/core/dom/EventNames.h b/Source/core/dom/EventNames.h
index 098071d..1633336 100644
--- a/Source/core/dom/EventNames.h
+++ b/Source/core/dom/EventNames.h
@@ -40,6 +40,7 @@
macro(blocked) \
macro(blur) \
macro(cached) \
+ macro(cancel) \
macro(change) \
macro(chargingchange) \
macro(chargingtimechange) \
@@ -190,8 +191,11 @@
macro(stalled) \
macro(suspend) \
\
+ macro(animationend) \
macro(webkitAnimationEnd) \
+ macro(animationstart) \
macro(webkitAnimationStart) \
+ macro(animationiteration) \
macro(webkitAnimationIteration) \
\
macro(webkitTransitionEnd) \
diff --git a/Source/core/dom/EventRetargeter.cpp b/Source/core/dom/EventRetargeter.cpp
index c113fd1..cf2d449 100644
--- a/Source/core/dom/EventRetargeter.cpp
+++ b/Source/core/dom/EventRetargeter.cpp
@@ -100,8 +100,6 @@
eventPath.append(adoptPtr(new TouchEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
else
eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
- if (!inDocument)
- break;
if (!node->isShadowRoot())
continue;
if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
diff --git a/Source/core/dom/EventTarget.cpp b/Source/core/dom/EventTarget.cpp
index 30c6854..991f785 100644
--- a/Source/core/dom/EventTarget.cpp
+++ b/Source/core/dom/EventTarget.cpp
@@ -32,6 +32,7 @@
#include "config.h"
#include "core/dom/EventTarget.h"
+#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptController.h"
@@ -186,12 +187,64 @@
if (event->type() == eventNames().transitionendEvent)
return eventNames().webkitTransitionEndEvent;
+ if (event->type() == eventNames().animationstartEvent)
+ return eventNames().webkitAnimationStartEvent;
+
+ if (event->type() == eventNames().animationendEvent)
+ return eventNames().webkitAnimationEndEvent;
+
+ if (event->type() == eventNames().animationiterationEvent)
+ return eventNames().webkitAnimationIterationEvent;
+
if (event->type() == eventNames().wheelEvent)
return eventNames().mousewheelEvent;
return emptyString();
}
+void EventTarget::countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector* listenersVector, EventListenerVector* legacyListenersVector)
+{
+ UseCounter::Feature unprefixedFeature;
+ UseCounter::Feature prefixedFeature;
+ UseCounter::Feature prefixedAndUnprefixedFeature;
+ bool shouldCount = false;
+
+ if (legacyTypeName == eventNames().webkitTransitionEndEvent) {
+ prefixedFeature = UseCounter::PrefixedTransitionEndEvent;
+ unprefixedFeature = UseCounter::UnprefixedTransitionEndEvent;
+ prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedTransitionEndEvent;
+ shouldCount = true;
+ } else if (legacyTypeName == eventNames().webkitAnimationEndEvent) {
+ prefixedFeature = UseCounter::PrefixedAnimationEndEvent;
+ unprefixedFeature = UseCounter::UnprefixedAnimationEndEvent;
+ prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationEndEvent;
+ shouldCount = true;
+ } else if (legacyTypeName == eventNames().webkitAnimationStartEvent) {
+ prefixedFeature = UseCounter::PrefixedAnimationStartEvent;
+ unprefixedFeature = UseCounter::UnprefixedAnimationStartEvent;
+ prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationStartEvent;
+ shouldCount = true;
+ } else if (legacyTypeName == eventNames().webkitAnimationIterationEvent) {
+ prefixedFeature = UseCounter::PrefixedAnimationIterationEvent;
+ unprefixedFeature = UseCounter::UnprefixedAnimationIterationEvent;
+ prefixedAndUnprefixedFeature = UseCounter::PrefixedAndUnprefixedAnimationIterationEvent;
+ shouldCount = true;
+ }
+
+ if (shouldCount) {
+ if (DOMWindow* executingWindow = this->executingWindow()) {
+ if (legacyListenersVector) {
+ if (listenersVector)
+ UseCounter::count(executingWindow, prefixedAndUnprefixedFeature);
+ else
+ UseCounter::count(executingWindow, prefixedFeature);
+ } else if (listenersVector) {
+ UseCounter::count(executingWindow, unprefixedFeature);
+ }
+ }
+ }
+}
+
bool EventTarget::fireEventListeners(Event* event)
{
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
@@ -207,6 +260,9 @@
legacyListenersVector = d->eventListenerMap.find(legacyTypeName);
EventListenerVector* listenersVector = d->eventListenerMap.find(event->type());
+ if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && (event->type() == eventNames().animationiterationEvent || event->type() == eventNames().animationendEvent
+ || event->type() == eventNames().animationstartEvent))
+ listenersVector = 0;
if (listenersVector) {
fireEventListeners(event, d, *listenersVector);
@@ -217,19 +273,7 @@
event->setType(unprefixedTypeName);
}
- if (legacyTypeName == eventNames().webkitTransitionEndEvent) {
- if (DOMWindow* executingWindow = this->executingWindow()) {
- if (legacyListenersVector) {
- if (listenersVector)
- UseCounter::count(executingWindow, UseCounter::PrefixedAndUnprefixedTransitionEndEvent);
- else
- UseCounter::count(executingWindow, UseCounter::PrefixedTransitionEndEvent);
- } else if (listenersVector) {
- UseCounter::count(executingWindow, UseCounter::UnprefixedTransitionEndEvent);
- }
- }
- }
-
+ countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector);
return !event->defaultPrevented();
}
diff --git a/Source/core/dom/EventTarget.h b/Source/core/dom/EventTarget.h
index 267306a..b63c8fb 100644
--- a/Source/core/dom/EventTarget.h
+++ b/Source/core/dom/EventTarget.h
@@ -139,6 +139,7 @@
DOMWindow* executingWindow();
void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
+ void countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector*, EventListenerVector*);
bool clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index b72b25b..43ee0a7 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -490,7 +490,7 @@
if (!document()->contains(node.get()) && !node->inDocument())
changeQueue.append(document()->documentElement());
- node->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+ node->dispatchEvent(Event::createBubble(eventNames().webkitfullscreenchangeEvent));
}
while (!errorQueue.isEmpty()) {
@@ -506,7 +506,7 @@
if (!document()->contains(node.get()) && !node->inDocument())
errorQueue.append(document()->documentElement());
- node->dispatchEvent(Event::create(eventNames().webkitfullscreenerrorEvent, true, false));
+ node->dispatchEvent(Event::createBubble(eventNames().webkitfullscreenerrorEvent));
}
}
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index c4eebe4..75e593c 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -72,6 +72,7 @@
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLStyleElement.h"
#include "core/html/RadioNodeList.h"
@@ -282,7 +283,7 @@
if (display1 != display2 || fl1 != fl2 || colSpan1 != colSpan2
|| (specifiesColumns1 != specifiesColumns2 && doc->settings()->regionBasedColumnsEnabled())
|| (s1 && s2 && !s1->contentDataEquivalent(s2)))
- ch = Detach;
+ ch = Reattach;
else if (!s1 || !s2)
ch = Inherit;
else if (*s1 == *s2)
@@ -312,15 +313,15 @@
// When text-combine is on, we use RenderCombineText, otherwise RenderText.
// https://bugs.webkit.org/show_bug.cgi?id=55069
if ((s1 && s2) && (s1->hasTextCombine() != s2->hasTextCombine()))
- ch = Detach;
+ ch = Reattach;
// We need to reattach the node, so that it is moved to the correct RenderFlowThread.
if ((s1 && s2) && (s1->flowThread() != s2->flowThread()))
- ch = Detach;
+ ch = Reattach;
// When the region thread has changed, we need to prepare a separate render region object.
if ((s1 && s2) && (s1->regionThread() != s2->regionThread()))
- ch = Detach;
+ ch = Reattach;
return ch;
}
@@ -383,7 +384,7 @@
NodeRareData* Node::rareData() const
{
- ASSERT(hasRareData());
+ ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
return static_cast<NodeRareData*>(m_data.m_rareData);
}
@@ -515,18 +516,18 @@
return lastChild();
}
-void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
{
if (isContainerNode())
- toContainerNode(this)->insertBefore(newChild, refChild, es, attachBehavior);
+ toContainerNode(this)->insertBefore(newChild, refChild, es);
else
es.throwDOMException(HierarchyRequestError);
}
-void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& es)
{
if (isContainerNode())
- toContainerNode(this)->replaceChild(newChild, oldChild, es, attachBehavior);
+ toContainerNode(this)->replaceChild(newChild, oldChild, es);
else
es.throwDOMException(HierarchyRequestError);
}
@@ -539,10 +540,10 @@
es.throwDOMException(NotFoundError);
}
-void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& es, AttachBehavior attachBehavior)
+void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& es)
{
if (isContainerNode())
- toContainerNode(this)->appendChild(newChild, es, attachBehavior);
+ toContainerNode(this)->appendChild(newChild, es);
else
es.throwDOMException(HierarchyRequestError);
}
@@ -866,7 +867,7 @@
bool Node::isInert() const
{
- const Element* dialog = document()->activeModalDialog();
+ const HTMLDialogElement* dialog = document()->activeModalDialog();
if (dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this))
return true;
return document()->ownerElement() && document()->ownerElement()->isInert();
@@ -2477,12 +2478,12 @@
void Node::dispatchChangeEvent()
{
- dispatchScopedEvent(Event::create(eventNames().changeEvent, true, false));
+ dispatchScopedEvent(Event::createBubble(eventNames().changeEvent));
}
void Node::dispatchInputEvent()
{
- dispatchScopedEvent(Event::create(eventNames().inputEvent, true, false));
+ dispatchScopedEvent(Event::createBubble(eventNames().inputEvent));
}
void Node::defaultEventHandler(Event* event)
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index bdfdb4c..5831fdd 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -100,6 +100,11 @@
StyleChangeFromRenderer
};
+enum AttachBehavior {
+ DeprecatedAttachNow,
+ AttachLazily,
+};
+
class NodeRareDataBase {
public:
RenderObject* renderer() const { return m_renderer; }
@@ -114,11 +119,6 @@
RenderObject* m_renderer;
};
-enum AttachBehavior {
- DeprecatedAttachNow,
- AttachLazily,
-};
-
class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
friend class Document;
friend class TreeScope;
@@ -166,7 +166,7 @@
static bool isSupported(const String& feature, const String& version);
static void dumpStatistics();
- enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
+ enum StyleChange { NoChange, NoInherit, Inherit, Force, Reattach };
static StyleChange diff(const RenderStyle*, const RenderStyle*, Document*);
virtual ~Node();
@@ -205,10 +205,10 @@
// 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
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+ void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState&);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION, AttachBehavior = AttachLazily);
+ void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
bool hasChildNodes() const { return firstChild(); }
virtual PassRefPtr<Node> cloneNode(bool deep = true) = 0;
diff --git a/Source/core/dom/NodeRenderingContext.cpp b/Source/core/dom/NodeRenderingContext.cpp
index c66ae3c..a59c09e 100644
--- a/Source/core/dom/NodeRenderingContext.cpp
+++ b/Source/core/dom/NodeRenderingContext.cpp
@@ -27,6 +27,7 @@
#include "core/dom/NodeRenderingContext.h"
#include "RuntimeEnabledFeatures.h"
+#include "core/animation/css/CSSAnimations.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/FullscreenElementStack.h"
@@ -215,6 +216,8 @@
if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())
return;
+ // If m_style is already available, this scope shouldn't attempt to trigger animation updates.
+ CSSAnimationUpdateScope cssAnimationUpdateScope(m_style ? 0 : element);
if (!m_style)
m_style = element->styleForRenderer();
ASSERT(m_style);
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index d550bcb..2563ccb 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -28,7 +28,7 @@
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/PseudoElement.h"
-#include "core/dom/shadow/ComposedShadowTreeWalker.h"
+#include "core/dom/shadow/ComposedTreeWalker.h"
namespace WebCore {
@@ -50,14 +50,14 @@
ContainerNode* parent(const Node* node, ParentDetails* details)
{
// FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
- ComposedShadowTreeWalker walker(node, ComposedShadowTreeWalker::CrossUpperBoundary, ComposedShadowTreeWalker::CanStartFromShadowBoundary);
+ ComposedTreeWalker walker(node, ComposedTreeWalker::CrossUpperBoundary, ComposedTreeWalker::CanStartFromShadowBoundary);
ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
return details->outOfComposition() ? 0 : found;
}
Node* nextSibling(const Node* node)
{
- ComposedShadowTreeWalker walker(node);
+ ComposedTreeWalker walker(node);
if (node->isBeforePseudoElement()) {
walker.parent();
walker.firstChild();
@@ -76,7 +76,7 @@
Node* previousSibling(const Node* node)
{
- ComposedShadowTreeWalker walker(node);
+ ComposedTreeWalker walker(node);
if (node->isAfterPseudoElement()) {
walker.parent();
walker.lastChild();
@@ -95,28 +95,28 @@
Node* nextInScope(const Node* node)
{
- ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+ ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
walker.next();
return walker.get();
}
Node* previousInScope(const Node* node)
{
- ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+ ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
walker.previous();
return walker.get();
}
Node* parentInScope(const Node* node)
{
- ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+ ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
walker.parent();
return walker.get();
}
Node* lastChildInScope(const Node* node)
{
- ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
+ ComposedTreeWalker walker = ComposedTreeWalker(node, ComposedTreeWalker::DoNotCrossUpperBoundary);
walker.lastChild();
return walker.get();
}
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index 033c043..a4ede16 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -26,7 +26,7 @@
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
+#include "core/dom/StyleSheetCollections.h"
#include "core/fetch/CSSStyleSheetResource.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
@@ -63,7 +63,7 @@
m_resource->removeClient(this);
if (inDocument())
- document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
}
String ProcessingInstruction::nodeName() const
@@ -133,10 +133,10 @@
return;
m_loading = true;
- document()->styleSheetCollection()->addPendingSheet();
+ document()->styleSheetCollections()->addPendingSheet();
FetchRequest request(ResourceRequest(document()->completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
if (m_isXSL)
- m_resource = document()->fetcher()->requestXSLStyleSheet(request);
+ m_resource = document()->fetcher()->fetchXSLStyleSheet(request);
else
{
String charset = attrs.get("charset");
@@ -144,14 +144,14 @@
charset = document()->charset();
request.setCharset(charset);
- m_resource = document()->fetcher()->requestCSSStyleSheet(request);
+ m_resource = document()->fetcher()->fetchCSSStyleSheet(request);
}
if (m_resource)
m_resource->addClient(this);
else {
// The request may have been denied if (for example) the stylesheet is local and the document is remote.
m_loading = false;
- document()->styleSheetCollection()->removePendingSheet(this);
+ document()->styleSheetCollections()->removePendingSheet(this);
}
}
}
@@ -169,7 +169,7 @@
bool ProcessingInstruction::sheetLoaded()
{
if (!isLoading()) {
- document()->styleSheetCollection()->removePendingSheet(this);
+ document()->styleSheetCollections()->removePendingSheet(this);
return true;
}
return false;
@@ -248,7 +248,7 @@
CharacterData::insertedInto(insertionPoint);
if (!insertionPoint->inDocument())
return InsertionDone;
- document()->styleSheetCollection()->addStyleSheetCandidateNode(this, m_createdByParser);
+ document()->styleSheetCollections()->addStyleSheetCandidateNode(this, m_createdByParser);
checkStyleSheet();
return InsertionDone;
}
@@ -259,7 +259,7 @@
if (!insertionPoint->inDocument())
return;
- document()->styleSheetCollection()->removeStyleSheetCandidateNode(this);
+ document()->styleSheetCollections()->removeStyleSheetCandidateNode(this);
RefPtr<StyleSheet> removedSheet = m_sheet;
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 8d1ad9d..ba27e67 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "core/dom/Range.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ClientRect.h"
@@ -1159,12 +1160,27 @@
return 0;
}
-void Range::checkNodeBA(Node* n, ExceptionState& es) const
+void Range::checkNodeBA(Node* n, ExceptionState& es, const char* methodName) const
{
+ if (!m_start.container()) {
+ es.throwDOMException(InvalidStateError);
+ return;
+ }
+
+ if (!n) {
+ es.throwDOMException(NotFoundError);
+ return;
+ }
+
// 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.
+ if (!n->parentNode()) {
+ es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToExecute(methodName, "Range", "the given Node has no parent."));
+ return;
+ }
+
switch (n->nodeType()) {
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
@@ -1191,11 +1207,11 @@
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
+ case Node::ELEMENT_NODE:
break;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::ELEMENT_NODE:
case Node::ENTITY_NODE:
case Node::NOTATION_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
@@ -1218,17 +1234,7 @@
void Range::setStartAfter(Node* refNode, ExceptionState& es)
{
- if (!m_start.container()) {
- es.throwDOMException(InvalidStateError);
- return;
- }
-
- if (!refNode) {
- es.throwDOMException(NotFoundError);
- return;
- }
-
- checkNodeBA(refNode, es);
+ checkNodeBA(refNode, es, "setStartAfter");
if (es.hadException())
return;
@@ -1237,17 +1243,7 @@
void Range::setEndBefore(Node* refNode, ExceptionState& es)
{
- if (!m_start.container()) {
- es.throwDOMException(InvalidStateError);
- return;
- }
-
- if (!refNode) {
- es.throwDOMException(NotFoundError);
- return;
- }
-
- checkNodeBA(refNode, es);
+ checkNodeBA(refNode, es, "setEndBefore");
if (es.hadException())
return;
@@ -1256,17 +1252,7 @@
void Range::setEndAfter(Node* refNode, ExceptionState& es)
{
- if (!m_start.container()) {
- es.throwDOMException(InvalidStateError);
- return;
- }
-
- if (!refNode) {
- es.throwDOMException(NotFoundError);
- return;
- }
-
- checkNodeBA(refNode, es);
+ checkNodeBA(refNode, es, "setEndAfter");
if (es.hadException())
return;
@@ -1285,6 +1271,11 @@
return;
}
+ if (!refNode->parentNode()) {
+ es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToExecute("selectNode", "Range", "the given Node has no parent."));
+ return;
+ }
+
// 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.
@@ -1329,10 +1320,8 @@
if (m_ownerDocument != refNode->document())
setDocument(refNode->document());
- setStartBefore(refNode, es);
- if (es.hadException())
- return;
- setEndAfter(refNode, es);
+ setStartBefore(refNode);
+ setEndAfter(refNode);
}
void Range::selectNodeContents(Node* refNode, ExceptionState& es)
@@ -1462,17 +1451,7 @@
void Range::setStartBefore(Node* refNode, ExceptionState& es)
{
- if (!m_start.container()) {
- es.throwDOMException(InvalidStateError);
- return;
- }
-
- if (!refNode) {
- es.throwDOMException(NotFoundError);
- return;
- }
-
- checkNodeBA(refNode, es);
+ checkNodeBA(refNode, es, "setStartBefore");
if (es.hadException())
return;
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 0de0a15..5faaf9c 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -101,7 +101,7 @@
void selectNode(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void selectNodeContents(Node*, ExceptionState&);
void surroundContents(PassRefPtr<Node>, ExceptionState&);
- void setStartBefore(Node*, ExceptionState&);
+ void setStartBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
const Position startPosition() const { return m_start.toPosition(); }
const Position endPosition() const { return m_end.toPosition(); }
@@ -156,7 +156,7 @@
void setDocument(Document*);
Node* checkNodeWOffset(Node*, int offset, ExceptionState&) const;
- void checkNodeBA(Node*, ExceptionState&) const;
+ void checkNodeBA(Node*, ExceptionState&, const char* methodName) const;
void checkDeleteExtract(ExceptionState&);
int maxStartOffset() const;
int maxEndOffset() const;
diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp
index 55d6844..30f9de9 100644
--- a/Source/core/dom/ScriptLoader.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -135,7 +135,7 @@
void ScriptLoader::dispatchErrorEvent()
{
- m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+ m_element->dispatchEvent(Event::create(eventNames().errorEvent));
}
void ScriptLoader::dispatchLoadEvent()
@@ -232,7 +232,7 @@
m_characterEncoding = elementDocument->charset();
if (client->hasSourceAttribute()) {
- if (!requestScript(client->sourceAttributeValue()))
+ if (!fetchScript(client->sourceAttributeValue()))
return false;
}
@@ -261,7 +261,7 @@
return true;
}
-bool ScriptLoader::requestScript(const String& sourceUrl)
+bool ScriptLoader::fetchScript(const String& sourceUrl)
{
ASSERT(m_element);
@@ -286,7 +286,7 @@
if (isValidScriptNonce)
request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
- m_resource = elementDocument->fetcher()->requestScript(request);
+ m_resource = elementDocument->fetcher()->fetchScript(request);
m_isExternalScript = true;
}
diff --git a/Source/core/dom/ScriptLoader.h b/Source/core/dom/ScriptLoader.h
index dfa8818..cd180f0 100644
--- a/Source/core/dom/ScriptLoader.h
+++ b/Source/core/dom/ScriptLoader.h
@@ -78,7 +78,7 @@
bool ignoresLoadRequest() const;
bool isScriptForEventSupported() const;
- bool requestScript(const String& sourceUrl);
+ bool fetchScript(const String& sourceUrl);
void stopLoadRequest();
ScriptLoaderClient* client() const;
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index 2c53a05..ff29a77 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -31,8 +31,8 @@
#include "core/css/CSSStyleSheet.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/StyleSheetCollections.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLStyleElement.h"
#include "core/page/Settings.h"
@@ -46,7 +46,7 @@
{
}
-void ShadowTreeStyleSheetCollection::collectStyleSheets(DocumentStyleSheetCollection* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
+void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleSheetCollections* collections, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets)
{
if (document()->settings() && !document()->settings()->authorAndUserStylesEnabled())
return;
@@ -94,7 +94,7 @@
}
}
-bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(DocumentStyleSheetCollection* collections, StyleResolverUpdateMode updateMode)
+bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleSheetCollections* collections, StyleResolverUpdateMode updateMode)
{
Vector<RefPtr<StyleSheet> > styleSheets;
Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.h b/Source/core/dom/ShadowTreeStyleSheetCollection.h
index e398440..2e0a979 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.h
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.h
@@ -33,20 +33,20 @@
namespace WebCore {
class CSSStyleSheet;
-class DocumentStyleSheetCollection;
class ShadowRoot;
class StyleSheet;
class StyleSheetCollection;
+class StyleSheetCollections;
class ShadowTreeStyleSheetCollection FINAL : public StyleSheetCollection {
WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
public:
explicit ShadowTreeStyleSheetCollection(ShadowRoot*);
- bool updateActiveStyleSheets(DocumentStyleSheetCollection*, StyleResolverUpdateMode);
+ bool updateActiveStyleSheets(StyleSheetCollections*, StyleResolverUpdateMode);
private:
- void collectStyleSheets(DocumentStyleSheetCollection*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
+ void collectStyleSheets(StyleSheetCollections*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
};
}
diff --git a/Source/core/dom/StyleElement.cpp b/Source/core/dom/StyleElement.cpp
index 8f31ee4..683a8f2 100644
--- a/Source/core/dom/StyleElement.cpp
+++ b/Source/core/dom/StyleElement.cpp
@@ -25,9 +25,9 @@
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/Element.h"
#include "core/dom/ScriptableDocumentParser.h"
+#include "core/dom/StyleSheetCollections.h"
#include "core/html/HTMLStyleElement.h"
#include "core/page/ContentSecurityPolicy.h"
#include "wtf/text/StringBuilder.h"
@@ -59,7 +59,7 @@
{
ASSERT(document);
ASSERT(element);
- document->styleSheetCollection()->addStyleSheetCandidateNode(element, m_createdByParser);
+ document->styleSheetCollections()->addStyleSheetCandidateNode(element, m_createdByParser);
if (m_createdByParser)
return;
@@ -70,7 +70,7 @@
{
ASSERT(document);
ASSERT(element);
- document->styleSheetCollection()->removeStyleSheetCandidateNode(element, scopingNode);
+ document->styleSheetCollections()->removeStyleSheetCandidateNode(element, scopingNode);
RefPtr<StyleSheet> removedSheet = m_sheet;
@@ -88,7 +88,7 @@
m_sheet->clearOwnerNode();
if (element->inDocument())
- document->styleSheetCollection()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0);
+ document->styleSheetCollections()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0);
}
void StyleElement::childrenChanged(Element* element)
@@ -127,7 +127,7 @@
Document* document = e->document();
if (m_sheet) {
if (m_sheet->isLoading())
- document->styleSheetCollection()->removePendingSheet(e);
+ document->styleSheetCollections()->removePendingSheet(e);
clearSheet();
}
@@ -139,7 +139,7 @@
MediaQueryEvaluator screenEval("screen", true);
MediaQueryEvaluator printEval("print", true);
if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
- document->styleSheetCollection()->addPendingSheet();
+ document->styleSheetCollections()->addPendingSheet();
m_loading = true;
TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
@@ -169,14 +169,14 @@
if (isLoading())
return false;
- document->styleSheetCollection()->removePendingSheet(m_sheet->ownerNode());
+ document->styleSheetCollections()->removePendingSheet(m_sheet->ownerNode());
return true;
}
void StyleElement::startLoadingDynamicSheet(Document* document)
{
ASSERT(document);
- document->styleSheetCollection()->addPendingSheet();
+ document->styleSheetCollections()->addPendingSheet();
}
}
diff --git a/Source/core/dom/StyleSheetCollection.cpp b/Source/core/dom/StyleSheetCollection.cpp
index a665b80..8a2b102 100644
--- a/Source/core/dom/StyleSheetCollection.cpp
+++ b/Source/core/dom/StyleSheetCollection.cpp
@@ -27,27 +27,18 @@
#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/shadow/ShadowRoot.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLLinkElement.h"
+#include "core/dom/StyleSheetCollections.h"
#include "core/html/HTMLStyleElement.h"
#include "core/page/Settings.h"
-#include "core/svg/SVGStyleElement.h"
namespace WebCore {
-using namespace HTMLNames;
-
StyleSheetCollection::StyleSheetCollection(TreeScope* treeScope)
: m_treeScope(treeScope)
, m_hadActiveLoadingStylesheet(false)
@@ -186,142 +177,4 @@
m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
}
-StyleSheetCollectionForDocument::StyleSheetCollectionForDocument(TreeScope* treeScope)
- : StyleSheetCollection(treeScope)
-{
- ASSERT(treeScope->rootNode() == treeScope->rootNode()->document());
-}
-
-void StyleSheetCollectionForDocument::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 && !document()->isHTMLDocument()) {
- // 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() && !pi->isLoading())
- 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);
- }
-}
-
-static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyleSheet> >& sheets, Document* document)
-{
- HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
- if (!seamlessParentIFrame)
- return;
- sheets.append(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
-}
-
-bool StyleSheetCollectionForDocument::updateActiveStyleSheets(DocumentStyleSheetCollection* collections, StyleResolverUpdateMode updateMode)
-{
- Vector<RefPtr<StyleSheet> > styleSheets;
- Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
- activeCSSStyleSheets.append(collections->injectedAuthorStyleSheets());
- activeCSSStyleSheets.append(collections->documentAuthorStyleSheets());
- collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, document());
- collectStyleSheets(collections, styleSheets, activeCSSStyleSheets);
-
- StyleResolverUpdateType styleResolverUpdateType;
- bool requiresFullStyleRecalc;
- analyzeStyleSheetChange(updateMode, activeAuthorStyleSheets(), activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
-
- if (styleResolverUpdateType == Reconstruct) {
- document()->clearStyleResolver();
- } else {
- StyleResolver* styleResolver = document()->styleResolverIfExists();
- ASSERT(styleResolver);
- // FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
- // Need to change "false" to some valid condition.
- styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
- if (styleResolverUpdateType == Reset) {
- resetAllRuleSetsInTreeScope(styleResolver);
- styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
- } else {
- ASSERT(styleResolverUpdateType == Additive);
- styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
- }
- }
- m_scopingNodesForStyleScoped.didRemoveScopingNodes();
- m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
- m_styleSheetsForStyleSheetList.swap(styleSheets);
- updateUsesRemUnits();
-
- return requiresFullStyleRecalc;
-}
-
}
diff --git a/Source/core/dom/StyleSheetCollection.h b/Source/core/dom/StyleSheetCollection.h
index ce41034..5fc6111 100644
--- a/Source/core/dom/StyleSheetCollection.h
+++ b/Source/core/dom/StyleSheetCollection.h
@@ -43,7 +43,7 @@
class ContainerNode;
class CSSStyleSheet;
-class DocumentStyleSheetCollection;
+class StyleSheetCollections;
class Node;
class StyleSheet;
class StyleSheetContents;
@@ -97,18 +97,6 @@
StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
};
-// FIXME: rename this class to DocumentStyleSheetCollection.
-class StyleSheetCollectionForDocument FINAL : public StyleSheetCollection {
- WTF_MAKE_NONCOPYABLE(StyleSheetCollectionForDocument); WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit StyleSheetCollectionForDocument(TreeScope*);
-
- bool updateActiveStyleSheets(DocumentStyleSheetCollection*, StyleResolverUpdateMode);
-
-private:
- void collectStyleSheets(DocumentStyleSheetCollection*, Vector<RefPtr<StyleSheet> >& styleSheets, Vector<RefPtr<CSSStyleSheet> >& activeSheets);
-};
-
}
#endif
diff --git a/Source/core/dom/StyleSheetCollections.cpp b/Source/core/dom/StyleSheetCollections.cpp
new file mode 100644
index 0000000..7a4ae2e
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollections.cpp
@@ -0,0 +1,458 @@
+/*
+ * 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/StyleSheetCollections.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/Element.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/dom/ShadowTreeStyleSheetCollection.h"
+#include "core/dom/shadow/ShadowRoot.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"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+StyleSheetCollections::StyleSheetCollections(Document* document)
+ : m_document(document)
+ , m_pendingStylesheets(0)
+ , m_injectedStyleSheetCacheValid(false)
+ , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+ , m_usesSiblingRules(false)
+ , m_usesSiblingRulesOverride(false)
+ , m_usesFirstLineRules(false)
+ , m_usesFirstLetterRules(false)
+ , m_usesRemUnits(false)
+ , m_documentStyleSheetCollection(document)
+ , m_needsDocumentStyleSheetsUpdate(true)
+{
+}
+
+StyleSheetCollections::~StyleSheetCollections()
+{
+ if (m_pageUserSheet)
+ m_pageUserSheet->clearOwnerNode();
+ for (unsigned i = 0; i < m_injectedUserStyleSheets.size(); ++i)
+ m_injectedUserStyleSheets[i]->clearOwnerNode();
+ for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
+ m_injectedAuthorStyleSheets[i]->clearOwnerNode();
+ for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
+ m_userStyleSheets[i]->clearOwnerNode();
+ for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
+ m_authorStyleSheets[i]->clearOwnerNode();
+}
+
+void StyleSheetCollections::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeScope* treeScope)
+{
+ if (treeScopes.isEmpty()) {
+ treeScopes.add(treeScope);
+ return;
+ }
+ if (treeScopes.contains(treeScope))
+ return;
+
+ TreeScopeSet::iterator begin = treeScopes.begin();
+ TreeScopeSet::iterator end = treeScopes.end();
+ TreeScopeSet::iterator it = end;
+ TreeScope* followingTreeScope = 0;
+ do {
+ --it;
+ TreeScope* n = *it;
+ unsigned short position = n->comparePosition(treeScope);
+ if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
+ treeScopes.insertBefore(followingTreeScope, treeScope);
+ return;
+ }
+ followingTreeScope = n;
+ } while (it != begin);
+
+ treeScopes.insertBefore(followingTreeScope, treeScope);
+}
+
+StyleSheetCollection* StyleSheetCollections::ensureStyleSheetCollectionFor(TreeScope* treeScope)
+{
+ if (treeScope == m_document)
+ return &m_documentStyleSheetCollection;
+
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(treeScope, nullptr);
+ if (result.isNewEntry)
+ result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
+ return result.iterator->value.get();
+}
+
+StyleSheetCollection* StyleSheetCollections::styleSheetCollectionFor(TreeScope* treeScope)
+{
+ if (treeScope == m_document)
+ return &m_documentStyleSheetCollection;
+
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(treeScope);
+ if (it == m_styleSheetCollectionMap.end())
+ return 0;
+ return it->value.get();
+}
+
+const Vector<RefPtr<StyleSheet> >& StyleSheetCollections::styleSheetsForStyleSheetList()
+{
+ return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::activeAuthorStyleSheets() const
+{
+ return m_documentStyleSheetCollection.activeAuthorStyleSheets();
+}
+
+void StyleSheetCollections::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
+{
+ activeAuthorStyleSheets.append(&m_documentStyleSheetCollection.activeAuthorStyleSheets());
+
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
+ for (; it != end; ++it) {
+ const StyleSheetCollection* collection = it->get();
+ activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
+ }
+}
+
+void StyleSheetCollections::combineCSSFeatureFlags(const RuleFeatureSet& features)
+{
+ // 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).
+ m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
+ m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules();
+}
+
+void StyleSheetCollections::resetCSSFeatureFlags(const RuleFeatureSet& features)
+{
+ m_usesSiblingRules = features.usesSiblingRules();
+ m_usesFirstLineRules = features.usesFirstLineRules();
+}
+
+CSSStyleSheet* StyleSheetCollections::pageUserSheet()
+{
+ if (m_pageUserSheet)
+ return m_pageUserSheet.get();
+
+ Page* owningPage = m_document->page();
+ if (!owningPage)
+ return 0;
+
+ String userSheetText = owningPage->userStyleSheet();
+ if (userSheetText.isEmpty())
+ return 0;
+
+ // Parse the sheet and cache it.
+ m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document->settings()->userStyleSheetLocation());
+ m_pageUserSheet->contents()->setIsUserStyleSheet(true);
+ m_pageUserSheet->contents()->parseString(userSheetText);
+ return m_pageUserSheet.get();
+}
+
+void StyleSheetCollections::clearPageUserSheet()
+{
+ if (m_pageUserSheet) {
+ RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
+ m_pageUserSheet = 0;
+ m_document->removedStyleSheet(removedSheet.get());
+ }
+}
+
+void StyleSheetCollections::updatePageUserSheet()
+{
+ clearPageUserSheet();
+ // FIXME: Why is this immediately and not defer?
+ if (StyleSheet* addedSheet = pageUserSheet())
+ m_document->addedStyleSheet(addedSheet, RecalcStyleImmediately);
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedUserStyleSheets() const
+{
+ updateInjectedStyleSheetCache();
+ return m_injectedUserStyleSheets;
+}
+
+const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedAuthorStyleSheets() const
+{
+ updateInjectedStyleSheetCache();
+ return m_injectedAuthorStyleSheets;
+}
+
+void StyleSheetCollections::updateInjectedStyleSheetCache() const
+{
+ if (m_injectedStyleSheetCacheValid)
+ return;
+ m_injectedStyleSheetCacheValid = true;
+ m_injectedUserStyleSheets.clear();
+ m_injectedAuthorStyleSheets.clear();
+
+ Page* owningPage = m_document->page();
+ if (!owningPage)
+ return;
+
+ const PageGroup& pageGroup = owningPage->group();
+ const UserStyleSheetVector& sheets = pageGroup.userStyleSheets();
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ const UserStyleSheet* sheet = sheets[i].get();
+ if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document->ownerElement())
+ continue;
+ if (!UserContentURLPattern::matchesPatterns(m_document->url(), sheet->whitelist(), sheet->blacklist()))
+ continue;
+ RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(m_document), sheet->url());
+ bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
+ if (isUserStyleSheet)
+ m_injectedUserStyleSheets.append(groupSheet);
+ else
+ m_injectedAuthorStyleSheets.append(groupSheet);
+ groupSheet->contents()->setIsUserStyleSheet(isUserStyleSheet);
+ groupSheet->contents()->parseString(sheet->source());
+ }
+}
+
+void StyleSheetCollections::invalidateInjectedStyleSheetCache()
+{
+ m_injectedStyleSheetCacheValid = false;
+ m_needsDocumentStyleSheetsUpdate = true;
+ // FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
+ // and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
+ m_document->styleResolverChanged(RecalcStyleDeferred);
+}
+
+void StyleSheetCollections::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
+{
+ ASSERT(!authorSheet->isUserStyleSheet());
+ m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
+ m_document->addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
+ m_needsDocumentStyleSheetsUpdate = true;
+}
+
+void StyleSheetCollections::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
+{
+ ASSERT(userSheet->isUserStyleSheet());
+ m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
+ m_document->addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmediately);
+ m_needsDocumentStyleSheetsUpdate = true;
+}
+
+// This method is called whenever a top-level stylesheet has finished loading.
+void StyleSheetCollections::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
+{
+ // Make sure we knew this sheet was pending, and that our count isn't out of sync.
+ ASSERT(m_pendingStylesheets > 0);
+
+ m_pendingStylesheets--;
+
+ TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? styleSheetCandidateNode->treeScope() : m_document;
+ if (treeScope == m_document)
+ m_needsDocumentStyleSheetsUpdate = true;
+ else
+ m_dirtyTreeScopes.add(treeScope);
+
+ if (m_pendingStylesheets)
+ return;
+
+ if (notification == RemovePendingSheetNotifyLater) {
+ 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 StyleSheetCollections::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+
+ StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
+ ASSERT(collection);
+ collection->addStyleSheetCandidateNode(node, createdByParser);
+
+ if (treeScope == m_document) {
+ m_needsDocumentStyleSheetsUpdate = true;
+ return;
+ }
+
+ insertTreeScopeInDocumentOrder(m_activeTreeScopes, treeScope);
+ m_dirtyTreeScopes.add(treeScope);
+}
+
+void StyleSheetCollections::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+{
+ TreeScope* treeScope = scopingNode ? scopingNode->treeScope() : m_document;
+ ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+
+ StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
+ ASSERT(collection);
+ collection->removeStyleSheetCandidateNode(node, scopingNode);
+
+ if (treeScope == m_document) {
+ m_needsDocumentStyleSheetsUpdate = true;
+ return;
+ }
+ m_dirtyTreeScopes.add(treeScope);
+ m_activeTreeScopes.remove(treeScope);
+}
+
+void StyleSheetCollections::modifiedStyleSheetCandidateNode(Node* node)
+{
+ if (!node->inDocument())
+ return;
+
+ TreeScope* treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+ if (treeScope == m_document) {
+ m_needsDocumentStyleSheetsUpdate = true;
+ return;
+ }
+ m_dirtyTreeScopes.add(treeScope);
+}
+
+bool StyleSheetCollections::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
+{
+ return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
+}
+
+bool StyleSheetCollections::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
+{
+ if (m_document->inStyleRecalc()) {
+ // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
+ // https://bugs.webkit.org/show_bug.cgi?id=54344
+ // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
+ m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
+ return false;
+
+ }
+ if (!m_document->renderer() || !m_document->attached())
+ return false;
+
+ bool requiresFullStyleRecalc = false;
+ if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate)
+ requiresFullStyleRecalc = m_documentStyleSheetCollection.updateActiveStyleSheets(this, updateMode);
+
+ if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
+ TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
+ HashSet<TreeScope*> treeScopesRemoved;
+
+ for (TreeScopeSet::iterator it = treeScopes.begin(); it != treeScopes.end(); ++it) {
+ TreeScope* treeScope = *it;
+ ASSERT(treeScope != m_document);
+ ShadowTreeStyleSheetCollection* collection = static_cast<ShadowTreeStyleSheetCollection*>(styleSheetCollectionFor(treeScope));
+ ASSERT(collection);
+ collection->updateActiveStyleSheets(this, updateMode);
+ if (!collection->hasStyleSheetCandidateNodes())
+ treeScopesRemoved.add(treeScope);
+ }
+ if (!treeScopesRemoved.isEmpty())
+ for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
+ m_activeTreeScopes.remove(*it);
+ m_dirtyTreeScopes.clear();
+ }
+
+ if (StyleResolver* styleResolver = m_document->styleResolverIfExists()) {
+ styleResolver->finishAppendAuthorStyleSheets();
+ resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
+ }
+
+ m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
+ activeStyleSheetsUpdatedForInspector();
+ m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
+
+ if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
+ m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
+ m_needsDocumentStyleSheetsUpdate = false;
+ }
+
+ return requiresFullStyleRecalc;
+}
+
+void StyleSheetCollections::activeStyleSheetsUpdatedForInspector()
+{
+ if (m_activeTreeScopes.isEmpty()) {
+ InspectorInstrumentation::activeStyleSheetsUpdated(m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+ return;
+ }
+ Vector<RefPtr<StyleSheet> > activeStyleSheets;
+
+ activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+
+ TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
+ TreeScopeSet::iterator end = m_activeTreeScopes.end();
+ for (TreeScopeSet::iterator it = begin; it != end; ++it) {
+ if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
+ activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
+ }
+
+ // FIXME: Inspector needs a vector which has all active stylesheets.
+ // However, creating such a large vector might cause performance regression.
+ // Need to implement some smarter solution.
+ InspectorInstrumentation::activeStyleSheetsUpdated(m_document, activeStyleSheets);
+}
+
+void StyleSheetCollections::didRemoveShadowRoot(ShadowRoot* shadowRoot)
+{
+ m_styleSheetCollectionMap.remove(shadowRoot);
+}
+
+void StyleSheetCollections::appendActiveAuthorStyleSheets(StyleResolver* styleResolver)
+{
+ ASSERT(styleResolver);
+
+ styleResolver->setBuildScopedStyleTreeInDocumentOrder(true);
+ styleResolver->appendAuthorStyleSheets(0, m_documentStyleSheetCollection.activeAuthorStyleSheets());
+
+ TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
+ TreeScopeSet::iterator end = m_activeTreeScopes.end();
+ for (TreeScopeSet::iterator it = begin; it != end; ++it) {
+ if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
+ styleResolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
+ styleResolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
+ }
+ }
+ styleResolver->finishAppendAuthorStyleSheets();
+ styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
+}
+
+}
diff --git a/Source/core/dom/StyleSheetCollections.h b/Source/core/dom/StyleSheetCollections.h
new file mode 100644
index 0000000..e934e51
--- /dev/null
+++ b/Source/core/dom/StyleSheetCollections.h
@@ -0,0 +1,164 @@
+/*
+ * 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 StyleSheetCollections_h
+#define StyleSheetCollections_h
+
+#include "core/dom/Document.h"
+#include "core/dom/DocumentOrderedList.h"
+#include "core/dom/DocumentStyleSheetCollection.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 Node;
+class RuleFeatureSet;
+class ShadowTreeStyleSheetCollection;
+class StyleSheet;
+class StyleSheetCollection;
+class StyleSheetContents;
+class StyleSheetList;
+
+class StyleSheetCollections {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassOwnPtr<StyleSheetCollections> create(Document* document) { return adoptPtr(new StyleSheetCollections(document)); }
+
+ ~StyleSheetCollections();
+
+ const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList();
+ const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
+
+ CSSStyleSheet* pageUserSheet();
+ const Vector<RefPtr<CSSStyleSheet> >& documentUserStyleSheets() const { return m_userStyleSheets; }
+ const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
+ const Vector<RefPtr<CSSStyleSheet> >& injectedUserStyleSheets() const;
+ const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+
+ void addStyleSheetCandidateNode(Node*, bool createdByParser);
+ void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
+ void modifiedStyleSheetCandidateNode(Node*);
+
+ void clearPageUserSheet();
+ void updatePageUserSheet();
+ void invalidateInjectedStyleSheetCache();
+ void updateInjectedStyleSheetCache() const;
+
+ void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
+ void addUserSheet(PassRefPtr<StyleSheetContents> userSheet);
+
+ bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
+
+ bool updateActiveStyleSheets(StyleResolverUpdateMode);
+
+ String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
+ String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
+ void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
+ void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
+
+ void addPendingSheet() { m_pendingStylesheets++; }
+ enum RemovePendingSheetNotificationType {
+ RemovePendingSheetNotifyImmediately,
+ RemovePendingSheetNotifyLater
+ };
+ void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+
+ bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
+
+ bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
+ void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
+ bool usesFirstLineRules() const { return m_usesFirstLineRules; }
+ bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
+ void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
+ bool usesRemUnits() const { return m_usesRemUnits; }
+ void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
+ bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
+
+ void combineCSSFeatureFlags(const RuleFeatureSet&);
+ void resetCSSFeatureFlags(const RuleFeatureSet&);
+
+ void didModifySeamlessParentStyleSheet() { m_needsDocumentStyleSheetsUpdate = true; }
+ void didRemoveShadowRoot(ShadowRoot*);
+ void appendActiveAuthorStyleSheets(StyleResolver*);
+ void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
+
+private:
+ StyleSheetCollections(Document*);
+
+ StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope*);
+ StyleSheetCollection* styleSheetCollectionFor(TreeScope*);
+ void activeStyleSheetsUpdatedForInspector();
+ bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
+
+ typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
+ static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
+
+ Document* m_document;
+
+ // 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
+ // elements and when it is safe to execute scripts.
+ int m_pendingStylesheets;
+
+ RefPtr<CSSStyleSheet> m_pageUserSheet;
+
+ mutable Vector<RefPtr<CSSStyleSheet> > m_injectedUserStyleSheets;
+ mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
+ mutable bool m_injectedStyleSheetCacheValid;
+
+ Vector<RefPtr<CSSStyleSheet> > m_userStyleSheets;
+ Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
+
+ bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
+
+ DocumentStyleSheetCollection m_documentStyleSheetCollection;
+ HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
+
+ TreeScopeSet m_dirtyTreeScopes;
+ TreeScopeSet m_activeTreeScopes;
+ bool m_needsDocumentStyleSheetsUpdate;
+
+ String m_preferredStylesheetSetName;
+ String m_selectedStylesheetSetName;
+
+ bool m_usesSiblingRules;
+ bool m_usesSiblingRulesOverride;
+ bool m_usesFirstLineRules;
+ bool m_usesFirstLetterRules;
+ bool m_usesRemUnits;
+};
+
+}
+
+#endif
+
diff --git a/Source/core/dom/TextLinkColors.cpp b/Source/core/dom/TextLinkColors.cpp
index 59589a5..a48f731 100644
--- a/Source/core/dom/TextLinkColors.cpp
+++ b/Source/core/dom/TextLinkColors.cpp
@@ -91,7 +91,7 @@
if (col->cssValueId == cssValueId)
return col->color;
}
- return RenderTheme::defaultTheme()->systemColor(cssValueId);
+ return RenderTheme::theme().systemColor(cssValueId);
}
StyleColor TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, bool forVisitedLink) const
diff --git a/Source/core/dom/AnimationEvent.cpp b/Source/core/dom/WebKitAnimationEvent.cpp
similarity index 75%
rename from Source/core/dom/AnimationEvent.cpp
rename to Source/core/dom/WebKitAnimationEvent.cpp
index b583c06..777a5a4 100644
--- a/Source/core/dom/AnimationEvent.cpp
+++ b/Source/core/dom/WebKitAnimationEvent.cpp
@@ -24,25 +24,25 @@
*/
#include "config.h"
-#include "core/dom/AnimationEvent.h"
+#include "core/dom/WebKitAnimationEvent.h"
#include "core/dom/EventNames.h"
namespace WebCore {
-AnimationEventInit::AnimationEventInit()
+WebKitAnimationEventInit::WebKitAnimationEventInit()
: animationName()
, elapsedTime(0.0)
{
}
-AnimationEvent::AnimationEvent()
+WebKitAnimationEvent::WebKitAnimationEvent()
: m_elapsedTime(0.0)
{
ScriptWrappable::init(this);
}
-AnimationEvent::AnimationEvent(const AtomicString& type, const AnimationEventInit& initializer)
+WebKitAnimationEvent::WebKitAnimationEvent(const AtomicString& type, const WebKitAnimationEventInit& initializer)
: Event(type, initializer)
, m_animationName(initializer.animationName)
, m_elapsedTime(initializer.elapsedTime)
@@ -50,7 +50,7 @@
ScriptWrappable::init(this);
}
-AnimationEvent::AnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime)
+WebKitAnimationEvent::WebKitAnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime)
: Event(type, true, true)
, m_animationName(animationName)
, m_elapsedTime(elapsedTime)
@@ -58,23 +58,23 @@
ScriptWrappable::init(this);
}
-AnimationEvent::~AnimationEvent()
+WebKitAnimationEvent::~WebKitAnimationEvent()
{
}
-const String& AnimationEvent::animationName() const
+const String& WebKitAnimationEvent::animationName() const
{
return m_animationName;
}
-double AnimationEvent::elapsedTime() const
+double WebKitAnimationEvent::elapsedTime() const
{
return m_elapsedTime;
}
-const AtomicString& AnimationEvent::interfaceName() const
+const AtomicString& WebKitAnimationEvent::interfaceName() const
{
- return eventNames().interfaceForAnimationEvent;
+ return eventNames().interfaceForWebKitAnimationEvent;
}
} // namespace WebCore
diff --git a/Source/core/dom/WebKitAnimationEvent.h b/Source/core/dom/WebKitAnimationEvent.h
new file mode 100644
index 0000000..8f642bf
--- /dev/null
+++ b/Source/core/dom/WebKitAnimationEvent.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, 2008 Apple 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 WebKitAnimationEvent_h
+#define WebKitAnimationEvent_h
+
+#include "core/dom/Event.h"
+
+namespace WebCore {
+
+// FIXME : This class has a WebKit prefix on purpose so we can use the EventAliases system. When the
+// runtime flag of unprefixed animation will be removed we can rename that class and do the same as
+// the CSS Transitions.
+struct WebKitAnimationEventInit : public EventInit {
+ WebKitAnimationEventInit();
+
+ String animationName;
+ double elapsedTime;
+};
+
+class WebKitAnimationEvent : public Event {
+public:
+ static PassRefPtr<WebKitAnimationEvent> create()
+ {
+ return adoptRef(new WebKitAnimationEvent);
+ }
+ static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
+ {
+ return adoptRef(new WebKitAnimationEvent(type, animationName, elapsedTime));
+ }
+ static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const WebKitAnimationEventInit& initializer)
+ {
+ return adoptRef(new WebKitAnimationEvent(type, initializer));
+ }
+
+ virtual ~WebKitAnimationEvent();
+
+ const String& animationName() const;
+ double elapsedTime() const;
+
+ virtual const AtomicString& interfaceName() const;
+
+private:
+ WebKitAnimationEvent();
+ WebKitAnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime);
+ WebKitAnimationEvent(const AtomicString&, const WebKitAnimationEventInit&);
+
+ String m_animationName;
+ double m_elapsedTime;
+};
+
+} // namespace WebCore
+
+#endif // WebKitAnimationEvent_h
diff --git a/Source/core/dom/WebKitAnimationEvent.idl b/Source/core/dom/WebKitAnimationEvent.idl
index e53b4e7..a168306 100644
--- a/Source/core/dom/WebKitAnimationEvent.idl
+++ b/Source/core/dom/WebKitAnimationEvent.idl
@@ -24,8 +24,7 @@
*/
[
- ConstructorTemplate=Event,
- ImplementedAs=AnimationEvent
+ ConstructorTemplate=Event
] interface WebKitAnimationEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString animationName;
[InitializedByEventConstructor] readonly attribute double elapsedTime;
diff --git a/Source/core/dom/WheelEvent.cpp b/Source/core/dom/WheelEvent.cpp
index bcb3d69..f2b71f6 100644
--- a/Source/core/dom/WheelEvent.cpp
+++ b/Source/core/dom/WheelEvent.cpp
@@ -30,14 +30,6 @@
namespace WebCore {
-static inline double wheelTicksToPixels(double ticks)
-{
- // Make sure we use +0 for all zeros.
- if (!ticks)
- return 0;
- return -ticks * WheelEvent::TickMultiplier;
-}
-
WheelEventInit::WheelEventInit()
: deltaX(0)
, deltaY(0)
@@ -60,6 +52,7 @@
WheelEvent::WheelEvent(const AtomicString& type, const WheelEventInit& initializer)
: MouseEvent(type, initializer)
+ , m_wheelDelta(initializer.wheelDeltaX ? initializer.wheelDeltaX : -initializer.deltaX, initializer.wheelDeltaY ? initializer.wheelDeltaY : -initializer.deltaY)
, m_deltaX(initializer.deltaX ? initializer.deltaX : -initializer.wheelDeltaX)
, m_deltaY(initializer.deltaY ? initializer.deltaY : -initializer.wheelDeltaY)
, m_deltaZ(initializer.deltaZ)
@@ -76,10 +69,10 @@
pageLocation.x(), pageLocation.y(),
0, 0,
ctrlKey, altKey, shiftKey, metaKey, 0, 0, 0, false)
- , m_deltaX(wheelTicksToPixels(wheelTicks.x()))
- , m_deltaY(wheelTicksToPixels(wheelTicks.y()))
- , m_deltaZ(0) // FIXME: Not supported.
- , m_rawDelta(roundedIntPoint(rawDelta))
+ , m_wheelDelta(wheelTicks.x() * TickMultiplier, wheelTicks.y() * TickMultiplier)
+ , m_deltaX(-rawDelta.x())
+ , m_deltaY(-rawDelta.y())
+ , m_deltaZ(0)
, m_deltaMode(deltaMode)
, m_directionInvertedFromDevice(directionInvertedFromDevice)
{
@@ -101,9 +94,9 @@
m_shiftKey = shiftKey;
m_metaKey = metaKey;
- m_deltaX = wheelTicksToPixels(rawDeltaX);
- m_deltaY = wheelTicksToPixels(rawDeltaY);
- m_rawDelta = IntPoint(rawDeltaX, rawDeltaY);
+ m_wheelDelta = IntPoint(rawDeltaX * TickMultiplier, rawDeltaY * TickMultiplier);
+ m_deltaX = -rawDeltaX;
+ m_deltaY = -rawDeltaY;
m_deltaMode = DOM_DELTA_PIXEL;
m_directionInvertedFromDevice = false;
diff --git a/Source/core/dom/WheelEvent.h b/Source/core/dom/WheelEvent.h
index 870c9b6..c393f37 100644
--- a/Source/core/dom/WheelEvent.h
+++ b/Source/core/dom/WheelEvent.h
@@ -85,11 +85,11 @@
double deltaY() const { return m_deltaY; } // Positive when scrolling down.
double deltaZ() const { return m_deltaZ; }
int wheelDelta() const { return wheelDeltaY() ? wheelDeltaY() : wheelDeltaX(); } // Deprecated.
- int wheelDeltaX() const { return -m_deltaX; } // Deprecated, negative when scrolling right.
- int wheelDeltaY() const { return -m_deltaY; } // Deprecated, negative when scrolling down.
- int rawDeltaX() const { return m_rawDelta.x(); }
- int rawDeltaY() const { return m_rawDelta.y(); }
+ int wheelDeltaX() const { return m_wheelDelta.x(); } // Deprecated, negative when scrolling right.
+ int wheelDeltaY() const { return m_wheelDelta.y(); } // Deprecated, negative when scrolling down.
unsigned deltaMode() const { return m_deltaMode; }
+ float ticksX() const { return static_cast<float>(m_wheelDelta.x()) / TickMultiplier; }
+ float ticksY() const { return static_cast<float>(m_wheelDelta.y()) / TickMultiplier; }
bool webkitDirectionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
@@ -103,10 +103,10 @@
unsigned, PassRefPtr<AbstractView>, const IntPoint& screenLocation, const IntPoint& pageLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool directionInvertedFromDevice);
+ IntPoint m_wheelDelta;
double m_deltaX;
double m_deltaY;
double m_deltaZ;
- IntPoint m_rawDelta;
unsigned m_deltaMode;
bool m_directionInvertedFromDevice;
};
diff --git a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
index f4b8373..7c54ada 100644
--- a/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
+++ b/Source/core/dom/default/chromium/PlatformMessagePortChannelChromium.h
@@ -31,11 +31,10 @@
#ifndef PlatformMessagePortChannelChromium_h
#define PlatformMessagePortChannelChromium_h
-
#include "core/dom/MessagePortChannel.h"
#include "public/platform/WebMessagePortChannelClient.h"
#include "wtf/PassRefPtr.h"
-#include "wtf/Threading.h"
+#include "wtf/ThreadingPrimitives.h"
namespace WebKit {
class WebMessagePortChannel;
diff --git a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
similarity index 81%
rename from Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
rename to Source/core/dom/shadow/ComposedTreeWalker.cpp
index 80ff995..86f97ed 100644
--- a/Source/core/dom/shadow/ComposedShadowTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -26,7 +26,7 @@
*/
#include "config.h"
-#include "core/dom/shadow/ComposedShadowTreeWalker.h"
+#include "core/dom/shadow/ComposedTreeWalker.h"
#include "core/dom/Element.h"
#include "core/dom/shadow/ElementShadow.h"
@@ -57,7 +57,7 @@
return false;
}
-Node* ComposedShadowTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
+Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
{
ASSERT(node);
if (canCrossUpperBoundary()) {
@@ -70,13 +70,13 @@
return traverseLightChildren(node, direction);
}
-Node* ComposedShadowTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseLightChildren(const Node* node, TraversalDirection direction)
{
ASSERT(node);
return traverseSiblings(direction == TraversalDirectionForward ? node->firstChild() : node->lastChild(), direction);
}
-Node* ComposedShadowTreeWalker::traverseSiblings(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblings(const Node* node, TraversalDirection direction)
{
for (const Node* sibling = node; sibling; sibling = (direction == TraversalDirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
if (Node* found = traverseNode(sibling, direction))
@@ -85,7 +85,7 @@
return 0;
}
-Node* ComposedShadowTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
{
ASSERT(node);
if (!isActiveInsertionPoint(node))
@@ -96,7 +96,7 @@
return traverseLightChildren(node, direction);
}
-Node* ComposedShadowTreeWalker::traverseDistributedNodes(const Node* node, const InsertionPoint* insertionPoint, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseDistributedNodes(const Node* node, const InsertionPoint* insertionPoint, TraversalDirection direction)
{
for (const Node* next = node; next; next = (direction == TraversalDirectionForward ? insertionPoint->nextTo(next) : insertionPoint->previousTo(next))) {
if (Node* found = traverseNode(next, direction))
@@ -105,7 +105,7 @@
return 0;
}
-Node* ComposedShadowTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblingOrBackToInsertionPoint(const Node* node, TraversalDirection direction)
{
ASSERT(node);
@@ -121,7 +121,7 @@
return traverseSiblingOrBackToInsertionPoint(insertionPoint, direction);
}
-Node* ComposedShadowTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseSiblingInCurrentTree(const Node* node, TraversalDirection direction)
{
ASSERT(node);
if (Node* found = traverseSiblings(direction == TraversalDirectionForward ? node->nextSibling() : node->previousSibling(), direction))
@@ -131,7 +131,7 @@
return escapeFallbackContentElement(node, direction);
}
-Node* ComposedShadowTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
+Node* ComposedTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
{
ASSERT(node);
if (node->parentNode() && node->parentNode()->isShadowRoot()) {
@@ -145,7 +145,7 @@
return 0;
}
-inline Node* ComposedShadowTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
+inline Node* ComposedTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
{
ASSERT(node);
if (node->parentNode() && isActiveInsertionPoint(node->parentNode()))
@@ -153,7 +153,7 @@
return 0;
}
-inline Node* ComposedShadowTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
{
ASSERT(node);
if (!node->isInsertionPoint())
@@ -165,7 +165,7 @@
// FIXME: Use an iterative algorithm so that it can be inlined.
// https://bugs.webkit.org/show_bug.cgi?id=90415
-Node* ComposedShadowTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
+Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
{
if (node->isPseudoElement())
return node->parentOrShadowHostNode();
@@ -189,14 +189,14 @@
return traverseParentInCurrentTree(node, details);
}
-inline Node* ComposedShadowTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTraversalDetails* details) const
{
if (Node* parent = node->parentNode())
return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : traverseNodeEscapingFallbackContents(parent, details);
return 0;
}
-Node* ComposedShadowTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
+Node* ComposedTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
{
ASSERT(shadowRoot);
ASSERT(!shadowRoot->insertionPoint());
diff --git a/Source/core/dom/shadow/ComposedShadowTreeWalker.h b/Source/core/dom/shadow/ComposedTreeWalker.h
similarity index 84%
rename from Source/core/dom/shadow/ComposedShadowTreeWalker.h
rename to Source/core/dom/shadow/ComposedTreeWalker.h
index 34c5b01..a75ac9e 100644
--- a/Source/core/dom/shadow/ComposedShadowTreeWalker.h
+++ b/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ComposedShadowTreeWalker_h
-#define ComposedShadowTreeWalker_h
+#ifndef ComposedTreeWalker_h
+#define ComposedTreeWalker_h
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/InsertionPoint.h"
@@ -38,7 +38,7 @@
// FIXME: Make some functions inline to optimise the performance.
// https://bugs.webkit.org/show_bug.cgi?id=82702
-class ComposedShadowTreeWalker {
+class ComposedTreeWalker {
public:
typedef NodeRenderingTraversal::ParentDetails ParentTraversalDetails;
@@ -52,7 +52,7 @@
CannotStartFromShadowBoundary
};
- ComposedShadowTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
+ ComposedTreeWalker(const Node*, Policy = CrossUpperBoundary, StartPolicy = CannotStartFromShadowBoundary);
Node* get() const { return const_cast<Node*>(m_node); }
@@ -70,7 +70,7 @@
Node* traverseParent(const Node*, ParentTraversalDetails* = 0) const;
private:
- ComposedShadowTreeWalker(const Node*, ParentTraversalDetails*);
+ ComposedTreeWalker(const Node*, ParentTraversalDetails*);
enum TraversalDirection {
TraversalDirectionForward,
@@ -126,7 +126,7 @@
Policy m_policy;
};
-inline ComposedShadowTreeWalker::ComposedShadowTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
+inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, Policy policy, StartPolicy startPolicy)
: m_node(node)
, m_policy(policy)
{
@@ -137,28 +137,28 @@
#endif
}
-inline void ComposedShadowTreeWalker::parent()
+inline void ComposedTreeWalker::parent()
{
assertPrecondition();
m_node = traverseParent(m_node);
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::nextSibling()
+inline void ComposedTreeWalker::nextSibling()
{
assertPrecondition();
m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionForward);
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::previousSibling()
+inline void ComposedTreeWalker::previousSibling()
{
assertPrecondition();
m_node = traverseSiblingOrBackToInsertionPoint(m_node, TraversalDirectionBackward);
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::next()
+inline void ComposedTreeWalker::next()
{
assertPrecondition();
if (Node* next = traverseFirstChild(m_node)) {
@@ -175,7 +175,7 @@
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::previous()
+inline void ComposedTreeWalker::previous()
{
assertPrecondition();
if (Node* previous = traversePreviousSibling(m_node)) {
@@ -188,39 +188,39 @@
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::firstChild()
+inline void ComposedTreeWalker::firstChild()
{
assertPrecondition();
m_node = traverseChild(m_node, TraversalDirectionForward);
assertPostcondition();
}
-inline void ComposedShadowTreeWalker::lastChild()
+inline void ComposedTreeWalker::lastChild()
{
assertPrecondition();
m_node = traverseLastChild(m_node);
assertPostcondition();
}
-inline Node* ComposedShadowTreeWalker::traverseNextSibling(const Node* node)
+inline Node* ComposedTreeWalker::traverseNextSibling(const Node* node)
{
ASSERT(node);
return traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionForward);
}
-inline Node* ComposedShadowTreeWalker::traversePreviousSibling(const Node* node)
+inline Node* ComposedTreeWalker::traversePreviousSibling(const Node* node)
{
ASSERT(node);
return traverseSiblingOrBackToInsertionPoint(node, TraversalDirectionBackward);
}
-inline Node* ComposedShadowTreeWalker::traverseFirstChild(const Node* node) const
+inline Node* ComposedTreeWalker::traverseFirstChild(const Node* node) const
{
ASSERT(node);
return traverseChild(node, TraversalDirectionForward);
}
-inline Node* ComposedShadowTreeWalker::traverseLastChild(const Node* node) const
+inline Node* ComposedTreeWalker::traverseLastChild(const Node* node) const
{
ASSERT(node);
return traverseChild(node, TraversalDirectionBackward);
diff --git a/Source/core/dom/shadow/ContentDistribution.cpp b/Source/core/dom/shadow/ContentDistribution.cpp
index 405ce56..8333841 100644
--- a/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/Source/core/dom/shadow/ContentDistribution.cpp
@@ -27,6 +27,8 @@
#include "config.h"
#include "core/dom/shadow/ContentDistribution.h"
+#include "core/dom/shadow/InsertionPoint.h"
+
namespace WebCore {
void ContentDistribution::swap(ContentDistribution& other)
@@ -37,6 +39,7 @@
void ContentDistribution::append(PassRefPtr<Node> node)
{
+ ASSERT(!isActiveInsertionPoint(node.get()));
size_t size = m_nodes.size();
m_indices.set(node.get(), size);
m_nodes.append(node);
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index b6eef01..1224962 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -32,7 +32,6 @@
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ContentDistribution.h"
#include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/shadow/HTMLContentElement.h"
#include "core/html/shadow/HTMLShadowElement.h"
@@ -65,14 +64,12 @@
m_shadowRoots.push(shadowRoot.get());
ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
setNeedsDistributionRecalc();
+ shadowHost->lazyReattachIfAttached();
// addShadowRoot() affects apply-author-styles. However, we know that the youngest shadow root has not had any children yet.
// The youngest shadow root's apply-author-styles is default (false). So we can just set m_applyAuthorStyles false.
m_applyAuthorStyles = false;
- if (shadowHost->attached())
- shadowHost->lazyReattach();
-
InspectorInstrumentation::didPushShadowRoot(shadowHost, shadowRoot.get());
return shadowRoot.get();
@@ -186,7 +183,7 @@
InsertionPoint* insertionPoint = toInsertionPoint(node);
if (insertionPoint->hasDistribution()) {
for (size_t i = 0; i < insertionPoint->size(); ++i)
- populate(insertionPoint->at(i), pool);
+ pool.append(insertionPoint->at(i));
} else {
for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling())
pool.append(fallbackNode);
@@ -208,21 +205,19 @@
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
- if (ScopeContentDistribution* scope = root->scopeDistribution()) {
- const Vector<RefPtr<InsertionPoint> >& insertionPoints = scope->ensureInsertionPointList(root);
- for (size_t i = 0; i < insertionPoints.size(); ++i) {
- InsertionPoint* point = insertionPoints[i].get();
- if (!point->isActive())
- continue;
+ const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->childInsertionPoints();
+ for (size_t i = 0; i < insertionPoints.size(); ++i) {
+ InsertionPoint* point = insertionPoints[i].get();
+ if (!point->isActive())
+ continue;
- if (isHTMLShadowElement(point)) {
- if (!firstActiveShadowInsertionPoint)
- firstActiveShadowInsertionPoint = toHTMLShadowElement(point);
- } else {
- distributeSelectionsTo(point, pool, distributed);
- if (ElementShadow* shadow = shadowOfParentForDistribution(point))
- shadow->setNeedsDistributionRecalc();
- }
+ if (isHTMLShadowElement(point)) {
+ if (!firstActiveShadowInsertionPoint)
+ firstActiveShadowInsertionPoint = toHTMLShadowElement(point);
+ } else {
+ distributeSelectionsTo(point, pool, distributed);
+ if (ElementShadow* shadow = shadowOfParentForDistribution(point))
+ shadow->setNeedsDistributionRecalc();
}
}
@@ -234,13 +229,15 @@
HTMLShadowElement* shadowElement = activeShadowInsertionPoints[i - 1];
ShadowRoot* root = shadowElement->containingShadowRoot();
ASSERT(root);
- if (!shadowElement->shouldSelect()) {
- if (root->olderShadowRoot())
- root->olderShadowRoot()->ensureScopeDistribution()->setInsertionPointAssignedTo(shadowElement);
- } else if (root->olderShadowRoot()) {
+ if (root->olderShadowRoot() && root->olderShadowRoot()->type() == root->type()) {
+ // Only allow reprojecting older shadow roots between the same type to
+ // disallow reprojecting UA elements into author shadows.
distributeNodeChildrenTo(shadowElement, root->olderShadowRoot());
- root->olderShadowRoot()->ensureScopeDistribution()->setInsertionPointAssignedTo(shadowElement);
- } else {
+ root->olderShadowRoot()->setInsertionPoint(shadowElement);
+ } else if (!root->olderShadowRoot()) {
+ // There's assumed to always be a UA shadow that selects all nodes.
+ // We don't actually add it, instead we just distribute the pool to the
+ // <shadow> in the oldest shadow root.
distributeSelectionsTo(shadowElement, pool, distributed);
}
if (ElementShadow* shadow = shadowOfParentForDistribution(shadowElement))
@@ -352,10 +349,8 @@
{
m_nodeToInsertionPoint.clear();
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- if (ScopeContentDistribution* scope = root->scopeDistribution())
- scope->setInsertionPointAssignedTo(0);
- }
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
+ root->setInsertionPoint(0);
}
} // namespace
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index f2447c4..5d01a73 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -35,7 +35,6 @@
#include "core/dom/QualifiedName.h"
#include "core/dom/StaticNodeList.h"
#include "core/dom/shadow/ElementShadow.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
@@ -176,7 +175,7 @@
rootOwner->setNeedsDistributionRecalc();
if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
m_registeredWithShadowRoot = true;
- root->ensureScopeDistribution()->registerInsertionPoint(this);
+ root->addInsertionPoint(this);
rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
rootOwner->willAffectSelector();
@@ -207,7 +206,7 @@
if (m_registeredWithShadowRoot && insertionPoint->treeScope()->rootNode() == root) {
ASSERT(root);
m_registeredWithShadowRoot = false;
- root->ensureScopeDistribution()->unregisterInsertionPoint(this);
+ root->removeInsertionPoint(this);
if (rootOwner) {
rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
diff --git a/Source/core/dom/shadow/ScopeContentDistribution.cpp b/Source/core/dom/shadow/ScopeContentDistribution.cpp
deleted file mode 100644
index b20ee65..0000000
--- a/Source/core/dom/shadow/ScopeContentDistribution.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.
- * * 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/shadow/ScopeContentDistribution.h"
-
-#include "core/dom/ElementTraversal.h"
-#include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-
-namespace WebCore {
-
-ScopeContentDistribution::ScopeContentDistribution()
- : m_insertionPointAssignedTo(0)
- , m_numberOfShadowElementChildren(0)
- , m_numberOfContentElementChildren(0)
- , m_numberOfElementShadowChildren(0)
- , m_insertionPointListIsValid(false)
-{
-}
-
-void ScopeContentDistribution::setInsertionPointAssignedTo(PassRefPtr<InsertionPoint> insertionPoint)
-{
- m_insertionPointAssignedTo = insertionPoint;
-}
-
-void ScopeContentDistribution::invalidateInsertionPointList()
-{
- m_insertionPointListIsValid = false;
- m_insertionPointList.clear();
-}
-
-const Vector<RefPtr<InsertionPoint> >& ScopeContentDistribution::ensureInsertionPointList(ShadowRoot* shadowRoot)
-{
- if (m_insertionPointListIsValid)
- return m_insertionPointList;
-
- m_insertionPointListIsValid = true;
- ASSERT(m_insertionPointList.isEmpty());
-
- if (!shadowRoot->containsInsertionPoints())
- return m_insertionPointList;
-
- for (Element* element = ElementTraversal::firstWithin(shadowRoot); element; element = ElementTraversal::next(element, shadowRoot)) {
- if (element->isInsertionPoint())
- m_insertionPointList.append(toInsertionPoint(element));
- }
-
- return m_insertionPointList;
-}
-
-void ScopeContentDistribution::registerInsertionPoint(InsertionPoint* point)
-{
- if (isHTMLShadowElement(point))
- ++m_numberOfShadowElementChildren;
- else if (isHTMLContentElement(point))
- ++m_numberOfContentElementChildren;
- else
- ASSERT_NOT_REACHED();
-
- invalidateInsertionPointList();
-}
-
-void ScopeContentDistribution::unregisterInsertionPoint(InsertionPoint* point)
-{
- if (isHTMLShadowElement(point))
- --m_numberOfShadowElementChildren;
- else if (isHTMLContentElement(point))
- --m_numberOfContentElementChildren;
- else
- ASSERT_NOT_REACHED();
-
- ASSERT(m_numberOfContentElementChildren >= 0);
- ASSERT(m_numberOfShadowElementChildren >= 0);
-
- invalidateInsertionPointList();
-}
-
-} // namespace WebCore
diff --git a/Source/core/dom/shadow/ScopeContentDistribution.h b/Source/core/dom/shadow/ScopeContentDistribution.h
deleted file mode 100644
index 43ed09f..0000000
--- a/Source/core/dom/shadow/ScopeContentDistribution.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 ScopeContentDistribution_h
-#define ScopeContentDistribution_h
-
-#include "wtf/Forward.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class InsertionPoint;
-class ShadowRoot;
-
-class ScopeContentDistribution {
-public:
- ScopeContentDistribution();
-
- InsertionPoint* insertionPointAssignedTo() const { return m_insertionPointAssignedTo.get(); }
- void setInsertionPointAssignedTo(PassRefPtr<InsertionPoint>);
-
- void registerInsertionPoint(InsertionPoint*);
- void unregisterInsertionPoint(InsertionPoint*);
- bool hasShadowElementChildren() const { return m_numberOfShadowElementChildren > 0; }
- bool hasContentElementChildren() const { return m_numberOfContentElementChildren > 0; }
-
- void registerElementShadow() { ++m_numberOfElementShadowChildren; }
- void unregisterElementShadow() { ASSERT(m_numberOfElementShadowChildren > 0); --m_numberOfElementShadowChildren; }
- unsigned numberOfElementShadowChildren() const { return m_numberOfElementShadowChildren; }
- bool hasElementShadowChildren() const { return m_numberOfElementShadowChildren > 0; }
-
- void invalidateInsertionPointList();
- const Vector<RefPtr<InsertionPoint> >& ensureInsertionPointList(ShadowRoot*);
-
-private:
- RefPtr<InsertionPoint> m_insertionPointAssignedTo;
- unsigned m_numberOfShadowElementChildren;
- unsigned m_numberOfContentElementChildren;
- unsigned m_numberOfElementShadowChildren;
- bool m_insertionPointListIsValid;
- Vector<RefPtr<InsertionPoint> > m_insertionPointList;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index b9f9ce1..6269a5c 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -29,11 +29,12 @@
#include "bindings/v8/ExceptionState.h"
#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/DocumentStyleSheetCollection.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/StyleSheetCollections.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ScopeContentDistribution.h"
+#include "core/dom/shadow/ShadowRootRareData.h"
#include "core/editing/markup.h"
#include "core/platform/HistogramSupport.h"
@@ -62,6 +63,7 @@
, m_resetStyleInheritance(false)
, m_type(type)
, m_registeredWithParentShadowRoot(false)
+ , m_childInsertionPointsIsValid(false)
{
ASSERT(document);
ScriptWrappable::init(this);
@@ -77,7 +79,7 @@
ASSERT(!m_prev);
ASSERT(!m_next);
- documentInternal()->styleSheetCollection()->didRemoveShadowRoot(this);
+ documentInternal()->styleSheetCollections()->didRemoveShadowRoot(this);
// We cannot let ContainerNode destructor call willBeDeletedFrom()
// for this ShadowRoot instance because TreeScope destructor
@@ -270,7 +272,7 @@
return InsertionDone;
if (ShadowRoot* root = host()->containingShadowRoot()) {
- root->ensureScopeDistribution()->registerElementShadow();
+ root->addChildShadowRoot();
m_registeredWithParentShadowRoot = true;
}
@@ -283,9 +285,8 @@
ShadowRoot* root = host()->containingShadowRoot();
if (!root)
root = insertionPoint->containingShadowRoot();
-
- if (root && root->scopeDistribution())
- root->scopeDistribution()->unregisterElementShadow();
+ if (root)
+ root->removeChildShadowRoot();
m_registeredWithParentShadowRoot = false;
}
@@ -314,33 +315,99 @@
setHasScopedHTMLStyleChild(m_numberOfStyles > 0);
}
-ScopeContentDistribution* ShadowRoot::ensureScopeDistribution()
+ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
{
- if (m_scopeDistribution)
- return m_scopeDistribution.get();
+ if (m_shadowRootRareData)
+ return m_shadowRootRareData.get();
- m_scopeDistribution = adoptPtr(new ScopeContentDistribution);
- return m_scopeDistribution.get();
+ m_shadowRootRareData = adoptPtr(new ShadowRootRareData);
+ return m_shadowRootRareData.get();
}
bool ShadowRoot::containsShadowElements() const
{
- return m_scopeDistribution ? m_scopeDistribution->hasShadowElementChildren() : 0;
+ return m_shadowRootRareData ? m_shadowRootRareData->hasShadowElementChildren() : 0;
}
bool ShadowRoot::containsContentElements() const
{
- return m_scopeDistribution ? m_scopeDistribution->hasContentElementChildren() : 0;
+ return m_shadowRootRareData ? m_shadowRootRareData->hasContentElementChildren() : 0;
}
bool ShadowRoot::containsShadowRoots() const
{
- return m_scopeDistribution ? m_scopeDistribution->numberOfElementShadowChildren() : 0;
+ return m_shadowRootRareData ? m_shadowRootRareData->hasShadowRootChildren() : 0;
}
InsertionPoint* ShadowRoot::insertionPoint() const
{
- return m_scopeDistribution ? m_scopeDistribution->insertionPointAssignedTo() : 0;
+ return m_shadowRootRareData ? m_shadowRootRareData->insertionPoint() : 0;
+}
+
+void ShadowRoot::setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint)
+{
+ if (!m_shadowRootRareData && !insertionPoint)
+ return;
+ ensureShadowRootRareData()->setInsertionPoint(insertionPoint);
+}
+
+void ShadowRoot::addInsertionPoint(InsertionPoint* insertionPoint)
+{
+ ensureShadowRootRareData()->addInsertionPoint(insertionPoint);
+ invalidateChildInsertionPoints();
+}
+
+void ShadowRoot::removeInsertionPoint(InsertionPoint* insertionPoint)
+{
+ m_shadowRootRareData->removeInsertionPoint(insertionPoint);
+ invalidateChildInsertionPoints();
+}
+
+void ShadowRoot::addChildShadowRoot()
+{
+ ensureShadowRootRareData()->addChildShadowRoot();
+}
+
+void ShadowRoot::removeChildShadowRoot()
+{
+ // FIXME: Why isn't this an ASSERT?
+ if (!m_shadowRootRareData)
+ return;
+ m_shadowRootRareData->removeChildShadowRoot();
+}
+
+unsigned ShadowRoot::childShadowRootCount() const
+{
+ return m_shadowRootRareData ? m_shadowRootRareData->childShadowRootCount() : 0;
+}
+
+void ShadowRoot::invalidateChildInsertionPoints()
+{
+ m_childInsertionPointsIsValid = false;
+ m_shadowRootRareData->clearChildInsertionPoints();
+}
+
+const Vector<RefPtr<InsertionPoint> >& ShadowRoot::childInsertionPoints()
+{
+ DEFINE_STATIC_LOCAL(const Vector<RefPtr<InsertionPoint> >, emptyList, ());
+
+ if (m_shadowRootRareData && m_childInsertionPointsIsValid)
+ return m_shadowRootRareData->childInsertionPoints();
+
+ m_childInsertionPointsIsValid = true;
+
+ if (!containsInsertionPoints())
+ return emptyList;
+
+ Vector<RefPtr<InsertionPoint> > insertionPoints;
+ for (Element* element = ElementTraversal::firstWithin(this); element; element = ElementTraversal::next(element, this)) {
+ if (element->isInsertionPoint())
+ insertionPoints.append(toInsertionPoint(element));
+ }
+
+ ensureShadowRootRareData()->setChildInsertionPoints(insertionPoints);
+
+ return m_shadowRootRareData->childInsertionPoints();
}
}
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 993fdb2..018f8e8 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -39,7 +39,7 @@
class ElementShadow;
class ExceptionState;
class InsertionPoint;
-class ScopeContentDistribution;
+class ShadowRootRareData;
class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
friend class WTF::DoublyLinkedListNode<ShadowRoot>;
@@ -91,15 +91,20 @@
virtual void registerScopedHTMLStyleChild() OVERRIDE;
virtual void unregisterScopedHTMLStyleChild() OVERRIDE;
- ScopeContentDistribution* scopeDistribution() { return m_scopeDistribution.get(); }
- const ScopeContentDistribution* scopeDistribution() const { return m_scopeDistribution.get(); }
- ScopeContentDistribution* ensureScopeDistribution();
-
bool containsShadowElements() const;
bool containsContentElements() const;
bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); }
bool containsShadowRoots() const;
+
+ // For Internals, don't use this.
+ unsigned childShadowRootCount() const;
+
InsertionPoint* insertionPoint() const;
+ void setInsertionPoint(PassRefPtr<InsertionPoint>);
+
+ void addInsertionPoint(InsertionPoint*);
+ void removeInsertionPoint(InsertionPoint*);
+ const Vector<RefPtr<InsertionPoint> >& childInsertionPoints();
ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
@@ -114,6 +119,12 @@
virtual bool childTypeAllowed(NodeType) const OVERRIDE;
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
+ ShadowRootRareData* ensureShadowRootRareData();
+
+ void addChildShadowRoot();
+ void removeChildShadowRoot();
+ void invalidateChildInsertionPoints();
+
// ShadowRoots should never be cloned.
virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
@@ -123,12 +134,13 @@
ShadowRoot* m_prev;
ShadowRoot* m_next;
- OwnPtr<ScopeContentDistribution> m_scopeDistribution;
- unsigned m_numberOfStyles : 28;
+ OwnPtr<ShadowRootRareData> m_shadowRootRareData;
+ unsigned m_numberOfStyles : 27;
unsigned m_applyAuthorStyles : 1;
unsigned m_resetStyleInheritance : 1;
unsigned m_type : 1;
unsigned m_registeredWithParentShadowRoot : 1;
+ unsigned m_childInsertionPointsIsValid : 1;
};
inline Element* ShadowRoot::activeElement() const
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
new file mode 100644
index 0000000..3a0966d
--- /dev/null
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -0,0 +1,103 @@
+/*
+ * 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 ShadowRootRareData_h
+#define ShadowRootRareData_h
+
+#include "core/dom/shadow/InsertionPoint.h"
+#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/HTMLShadowElement.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class ShadowRootRareData {
+public:
+ ShadowRootRareData()
+ : m_childShadowElementCount(0)
+ , m_childContentElementCount(0)
+ , m_childShadowRootCount(0)
+ {
+ }
+
+ InsertionPoint* insertionPoint() const { return m_insertionPoint.get(); }
+ void setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint) { m_insertionPoint = insertionPoint; }
+
+ void addInsertionPoint(InsertionPoint*);
+ void removeInsertionPoint(InsertionPoint*);
+
+ bool hasShadowElementChildren() const { return m_childShadowElementCount; }
+ bool hasContentElementChildren() const { return m_childContentElementCount; }
+ bool hasShadowRootChildren() const { return m_childShadowRootCount; }
+
+ void addChildShadowRoot() { ++m_childShadowRootCount; }
+ void removeChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
+
+ unsigned childShadowRootCount() const { return m_childShadowRootCount; }
+
+ const Vector<RefPtr<InsertionPoint> >& childInsertionPoints() { return m_childInsertionPoints; }
+ void setChildInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_childInsertionPoints.swap(list); }
+ void clearChildInsertionPoints() { m_childInsertionPoints.clear(); }
+
+private:
+ RefPtr<InsertionPoint> m_insertionPoint;
+ unsigned m_childShadowElementCount;
+ unsigned m_childContentElementCount;
+ unsigned m_childShadowRootCount;
+ Vector<RefPtr<InsertionPoint> > m_childInsertionPoints;
+};
+
+inline void ShadowRootRareData::addInsertionPoint(InsertionPoint* point)
+{
+ if (isHTMLShadowElement(point))
+ ++m_childShadowElementCount;
+ else if (isHTMLContentElement(point))
+ ++m_childContentElementCount;
+ else
+ ASSERT_NOT_REACHED();
+}
+
+inline void ShadowRootRareData::removeInsertionPoint(InsertionPoint* point)
+{
+ if (isHTMLShadowElement(point))
+ --m_childShadowElementCount;
+ else if (isHTMLContentElement(point))
+ --m_childContentElementCount;
+ else
+ ASSERT_NOT_REACHED();
+
+ ASSERT(m_childContentElementCount >= 0);
+ ASSERT(m_childShadowElementCount >= 0);
+}
+
+} // namespace WebCore
+
+#endif