Merge from Chromium at DEPS revision r207203
This commit was generated by merge_to_master.py.
Change-Id: Ia8a6c2a997232c94108d8937f8c2556f42be1c37
diff --git a/Source/core/dom/Attr.cpp b/Source/core/dom/Attr.cpp
index 5f99182..7aaf56c 100644
--- a/Source/core/dom/Attr.cpp
+++ b/Source/core/dom/Attr.cpp
@@ -185,16 +185,6 @@
return qualifiedName().matches(document()->idAttributeName());
}
-CSSStyleDeclaration* Attr::style()
-{
- // This function only exists to support the Obj-C bindings.
- if (!m_element || !m_element->isStyledElement())
- return 0;
- m_style = MutableStylePropertySet::create();
- static_cast<StyledElement*>(m_element)->collectStyleForPresentationAttribute(qualifiedName(), value(), m_style.get());
- return m_style->ensureCSSStyleDeclaration();
-}
-
const AtomicString& Attr::value() const
{
if (m_element)
diff --git a/Source/core/dom/Attr.h b/Source/core/dom/Attr.h
index 5bc6de2..9bff433 100644
--- a/Source/core/dom/Attr.h
+++ b/Source/core/dom/Attr.h
@@ -96,7 +96,6 @@
QualifiedName m_name;
AtomicString m_standaloneValue;
- RefPtr<MutableStylePropertySet> m_style;
unsigned m_ignoreChildrenChanged : 31;
bool m_specified : 1;
};
diff --git a/Source/core/dom/CharacterData.cpp b/Source/core/dom/CharacterData.cpp
index 5ca927e..9fda297 100644
--- a/Source/core/dom/CharacterData.cpp
+++ b/Source/core/dom/CharacterData.cpp
@@ -46,7 +46,7 @@
m_data = AtomicString(m_data);
}
-void CharacterData::setData(const String& data, ExceptionCode&)
+void CharacterData::setData(const String& data)
{
const String& nonNullData = !data.isNull() ? data : emptyString();
if (m_data == nonNullData)
@@ -117,7 +117,7 @@
info.addMember(m_data, "data");
}
-void CharacterData::appendData(const String& data, ExceptionCode&)
+void CharacterData::appendData(const String& data)
{
String newStr = m_data;
newStr.append(data);
@@ -194,9 +194,9 @@
return m_data.containsOnlyWhitespace();
}
-void CharacterData::setNodeValue(const String& nodeValue, ExceptionCode& ec)
+void CharacterData::setNodeValue(const String& nodeValue, ExceptionCode&)
{
- setData(nodeValue, ec);
+ setData(nodeValue);
}
void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfReplacedData, unsigned oldLength, unsigned newLength)
diff --git a/Source/core/dom/CharacterData.h b/Source/core/dom/CharacterData.h
index 30f938b..f8862ba 100644
--- a/Source/core/dom/CharacterData.h
+++ b/Source/core/dom/CharacterData.h
@@ -32,10 +32,10 @@
public:
void atomize();
String data() const { return m_data; }
- void setData(const String&, ExceptionCode&);
+ void setData(const String&);
unsigned length() const { return m_data.length(); }
String substringData(unsigned offset, unsigned count, ExceptionCode&);
- void appendData(const String&, ExceptionCode&);
+ void appendData(const String&);
void insertData(unsigned offset, const String&, ExceptionCode&);
void deleteData(unsigned offset, unsigned count, ExceptionCode&);
void replaceData(unsigned offset, unsigned count, const String&, ExceptionCode&);
diff --git a/Source/core/dom/CharacterData.idl b/Source/core/dom/CharacterData.idl
index 6491b8e..9d8ee85 100644
--- a/Source/core/dom/CharacterData.idl
+++ b/Source/core/dom/CharacterData.idl
@@ -19,13 +19,13 @@
interface CharacterData : Node {
- [TreatNullAs=NullString, SetterRaisesException] attribute DOMString data;
+ [TreatNullAs=NullString] attribute DOMString data;
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null, RaisesException] DOMString substringData([IsIndex,Default=Undefined] optional unsigned long offset, [IsIndex,Default=Undefined] optional unsigned long length);
- [RaisesException] void appendData([Default=Undefined] optional DOMString data);
+ void appendData([Default=Undefined] optional DOMString data);
[RaisesException] void insertData([IsIndex,Default=Undefined] optional unsigned long offset,
[Default=Undefined] optional DOMString data);
diff --git a/Source/core/dom/Comment.idl b/Source/core/dom/Comment.idl
index 3a46dd7..d928c6e 100644
--- a/Source/core/dom/Comment.idl
+++ b/Source/core/dom/Comment.idl
@@ -19,7 +19,7 @@
[
Constructor([Default=NullString] optional DOMString data),
- CallWith=ScriptExecutionContext
+ ConstructorCallWith=ScriptExecutionContext
] interface Comment : CharacterData {
};
diff --git a/Source/core/dom/CompositionEvent.idl b/Source/core/dom/CompositionEvent.idl
index 61bfad0..4f1a5b0 100644
--- a/Source/core/dom/CompositionEvent.idl
+++ b/Source/core/dom/CompositionEvent.idl
@@ -32,7 +32,7 @@
void initCompositionEvent([Default=Undefined] optional DOMString typeArg,
[Default=Undefined] optional boolean canBubbleArg,
[Default=Undefined] optional boolean cancelableArg,
- [Default=Undefined] optional DOMWindow viewArg,
+ [Default=Undefined] optional Window viewArg,
[Default=Undefined] optional DOMString dataArg);
};
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 44ddbc0..33bf98d 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -27,12 +27,15 @@
#include "core/dom/ContainerNodeAlgorithms.h"
#include "core/dom/EventNames.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/FullscreenController.h"
#include "core/dom/MutationEvent.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
#include "core/html/HTMLCollection.h"
#include "core/page/Page.h"
+#include "core/rendering/InlineTextBox.h"
+#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderWidget.h"
#include <wtf/CurrentTime.h>
@@ -50,9 +53,7 @@
typedef Vector<CallbackInfo> NodeCallbackQueue;
static NodeCallbackQueue* s_postAttachCallbackQueue;
-static NodeCallbackQueue* s_insertionCallbackQueue;
-static size_t s_insertionDepth;
static size_t s_attachDepth;
ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
@@ -468,7 +469,8 @@
document()->removeFocusedNodeOfSubtree(child.get());
- document()->removeFullScreenElementOfSubtree(child.get());
+ if (FullscreenController* fullscreen = FullscreenController::fromIfExists(document()))
+ fullscreen->removeFullScreenElementOfSubtree(child.get());
// Events fired when blurring currently focused node might have moved this
// child into a different parent.
@@ -559,7 +561,8 @@
// exclude this node when looking for removed focusedNode since only children will be removed
document()->removeFocusedNodeOfSubtree(this, true);
- document()->removeFullScreenElementOfSubtree(this, true);
+ if (FullscreenController* fullscreen = FullscreenController::fromIfExists(document()))
+ fullscreen->removeFullScreenElementOfSubtree(this, true);
// Do any prep work needed before actually starting to detach
// and remove... e.g. stop loading frames, fire unload events.
@@ -578,7 +581,7 @@
}
childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
-
+
for (size_t i = 0; i < removedChildren.size(); ++i)
ChildNodeRemovalNotifier(this).notify(removedChildren[i].get());
}
@@ -685,29 +688,6 @@
--s_attachDepth;
}
-void ContainerNode::suspendInsertionCallbacks()
-{
- ++s_insertionDepth;
-}
-
-void ContainerNode::resumeInsertionCallbacks()
-{
- if (s_insertionDepth == 1 && s_insertionCallbackQueue)
- dispatchInsertionCallbacks();
- --s_insertionDepth;
-}
-
-void ContainerNode::queueInsertionCallback(NodeCallback callback, Node* node)
-{
- if (!s_insertionDepth) {
- (*callback)(node);
- return;
- }
- if (!s_insertionCallbackQueue)
- s_insertionCallbackQueue = new NodeCallbackQueue;
- s_insertionCallbackQueue->append(CallbackInfo(callback, node));
-}
-
void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node)
{
if (!s_postAttachCallbackQueue)
@@ -731,17 +711,17 @@
s_postAttachCallbackQueue->clear();
}
-void ContainerNode::attach()
+void ContainerNode::attach(const AttachContext& context)
{
attachChildren();
- Node::attach();
+ Node::attach(context);
}
-void ContainerNode::detach()
+void ContainerNode::detach(const AttachContext& context)
{
detachChildren();
clearChildNeedsStyleRecalc();
- Node::detach();
+ Node::detach(context);
}
void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int childCountDelta)
@@ -760,6 +740,138 @@
}
+bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
+{
+ if (!renderer())
+ return false;
+ // What is this code really trying to do?
+ RenderObject* o = renderer();
+ RenderObject* p = o;
+
+ if (!o->isInline() || o->isReplaced()) {
+ point = o->localToAbsolute(FloatPoint(), UseTransforms);
+ return true;
+ }
+
+ // find the next text/image child, to get a position
+ while (o) {
+ p = o;
+ if (o->firstChild()) {
+ o = o->firstChild();
+ } else if (o->nextSibling()) {
+ o = o->nextSibling();
+ } else {
+ RenderObject* next = 0;
+ while (!next && o->parent()) {
+ o = o->parent();
+ next = o->nextSibling();
+ }
+ o = next;
+
+ if (!o)
+ break;
+ }
+ ASSERT(o);
+
+ if (!o->isInline() || o->isReplaced()) {
+ point = o->localToAbsolute(FloatPoint(), UseTransforms);
+ return true;
+ }
+
+ if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
+ // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
+ } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
+ point = FloatPoint();
+ if (o->isText() && toRenderText(o)->firstTextBox()) {
+ point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop());
+ } else if (o->isBox()) {
+ RenderBox* box = toRenderBox(o);
+ point.moveBy(box->location());
+ }
+ point = o->container()->localToAbsolute(point, UseTransforms);
+ return true;
+ }
+ }
+
+ // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
+ // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
+ if (!o && document()->view()) {
+ point = FloatPoint(0, document()->view()->contentsHeight());
+ return true;
+ }
+ return false;
+}
+
+bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
+{
+ if (!renderer())
+ return false;
+
+ RenderObject* o = renderer();
+ if (!o->isInline() || o->isReplaced()) {
+ RenderBox* box = toRenderBox(o);
+ point = o->localToAbsolute(LayoutPoint(box->size()), UseTransforms);
+ return true;
+ }
+
+ // find the last text/image child, to get a position
+ while (o) {
+ if (o->lastChild()) {
+ o = o->lastChild();
+ } else if (o->previousSibling()) {
+ o = o->previousSibling();
+ } else {
+ RenderObject* prev = 0;
+ while (!prev) {
+ o = o->parent();
+ if (!o)
+ return false;
+ prev = o->previousSibling();
+ }
+ o = prev;
+ }
+ ASSERT(o);
+ if (o->isText() || o->isReplaced()) {
+ point = FloatPoint();
+ if (o->isText()) {
+ RenderText* text = toRenderText(o);
+ IntRect linesBox = text->linesBoundingBox();
+ if (!linesBox.maxX() && !linesBox.maxY())
+ continue;
+ point.moveBy(linesBox.maxXMaxYCorner());
+ } else {
+ RenderBox* box = toRenderBox(o);
+ point.moveBy(box->frameRect().maxXMaxYCorner());
+ }
+ point = o->container()->localToAbsolute(point, UseTransforms);
+ return true;
+ }
+ }
+ return true;
+}
+
+// FIXME: This override is only needed for inline anchors without an
+// InlineBox and it does not belong in ContainerNode as it reaches into
+// the render and line box trees.
+// https://code.google.com/p/chromium/issues/detail?id=248354
+LayoutRect ContainerNode::boundingBox() const
+{
+ FloatPoint upperLeft, lowerRight;
+ bool foundUpperLeft = getUpperLeftCorner(upperLeft);
+ bool foundLowerRight = getLowerRightCorner(lowerRight);
+
+ // If we've found one corner, but not the other,
+ // then we should just return a point at the corner that we did find.
+ if (foundUpperLeft != foundLowerRight) {
+ if (foundUpperLeft)
+ lowerRight = upperLeft;
+ else
+ upperLeft = lowerRight;
+ }
+
+ return enclosingLayoutRect(FloatRect(upperLeft, lowerRight.expandedTo(upperLeft) - upperLeft));
+}
+
void ContainerNode::setFocus(bool received)
{
if (focused() == received)
@@ -793,6 +905,18 @@
Node::setHovered(over);
+ if (!renderer()) {
+ // When setting hover to false, the style needs to be recalc'd even when
+ // there's no renderer (imagine setting display:none in the :hover class,
+ // if a nil renderer would prevent this element from recalculating its
+ // style, it would never go back to its normal style and remain
+ // stuck in its hovered style).
+ if (!over)
+ setNeedsStyleRecalc();
+
+ return;
+ }
+
// note that we need to recalc the style
// FIXME: Move to Element
if (renderer()) {
@@ -909,15 +1033,6 @@
}
}
-void ContainerNode::dispatchInsertionCallbacks()
-{
- for (size_t i = s_insertionCallbackQueue->size(); i; --i) {
- const CallbackInfo& info = (*s_insertionCallbackQueue)[i - 1];
- info.first(info.second.get());
- }
- s_insertionCallbackQueue->clear();
-}
-
static void updateTreeAfterInsertion(ContainerNode* parent, Node* child, AttachBehavior attachBehavior)
{
ASSERT(parent->refCount());
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index b5409b4..e25b308 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -37,7 +37,7 @@
typedef void (*NodeCallback)(Node*);
-namespace Private {
+namespace Private {
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer*);
};
@@ -80,7 +80,6 @@
class ContainerNode : public Node {
friend class PostAttachCallbackDisabler;
- friend class InsertionCallbackDeferer;
public:
virtual ~ContainerNode();
@@ -114,8 +113,9 @@
void cloneChildNodes(ContainerNode* clone);
- virtual void attach() OVERRIDE;
- virtual void detach() OVERRIDE;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual LayoutRect boundingBox() const OVERRIDE;
virtual void setFocus(bool) OVERRIDE;
virtual void setActive(bool active = true, bool pause = false) OVERRIDE;
virtual void setHovered(bool = true) OVERRIDE;
@@ -141,8 +141,6 @@
protected:
ContainerNode(TreeScope*, ConstructionType = CreateContainer);
- static void queueInsertionCallback(NodeCallback, Node*);
- static bool insertionCallbacksAreSuspended();
static void queuePostAttachCallback(NodeCallback, Node*);
static bool postAttachCallbacksAreSuspended();
@@ -165,10 +163,8 @@
void suspendPostAttachCallbacks();
void resumePostAttachCallbacks();
- static void dispatchInsertionCallbacks();
-
- static void suspendInsertionCallbacks();
- static void resumeInsertionCallbacks();
+ bool getUpperLeftCorner(FloatPoint&) const;
+ bool getLowerRightCorner(FloatPoint&) const;
Node* m_firstChild;
Node* m_lastChild;
@@ -267,14 +263,6 @@
return highest;
}
-inline bool Node::needsShadowTreeWalker() const
-{
- if (getFlag(NeedsShadowTreeWalkerFlag))
- return true;
- ContainerNode* parent = parentOrShadowHostNode();
- return parent && parent->getFlag(NeedsShadowTreeWalkerFlag);
-}
-
// This constant controls how much buffer is initially allocated
// for a Node Vector that is used to store child Nodes of a given Node.
// FIXME: Optimize the value.
@@ -293,7 +281,7 @@
WTF_MAKE_FAST_ALLOCATED;
public:
explicit ChildNodesLazySnapshot(Node* parentNode)
- : m_currentNode(parentNode->lastChild())
+ : m_currentNode(parentNode->firstChild())
, m_currentIndex(0)
{
m_nextSnapshot = latestSnapshot;
@@ -305,13 +293,13 @@
latestSnapshot = m_nextSnapshot;
}
- // Returns 0 if there is no previous Node.
- PassRefPtr<Node> previousNode()
+ // Returns 0 if there is no next Node.
+ PassRefPtr<Node> nextNode()
{
if (LIKELY(!hasSnapshot())) {
RefPtr<Node> node = m_currentNode;
if (node)
- m_currentNode = node->previousSibling();
+ m_currentNode = node->nextSibling();
return node.release();
}
Vector<RefPtr<Node> >& nodeVector = *m_childNodes;
@@ -328,7 +316,7 @@
Node* node = m_currentNode.get();
while (node) {
m_childNodes->append(node);
- node = node->previousSibling();
+ node = node->nextSibling();
}
}
@@ -353,22 +341,6 @@
ChildNodesLazySnapshot* m_nextSnapshot;
};
-// Used to ensure Radio Buttons resolve their checked state in document
-// order when a subtree of them is inserted. This is necessary because
-// we resolve style in reverse document order.
-class InsertionCallbackDeferer {
-public:
- InsertionCallbackDeferer()
- {
- ContainerNode::suspendInsertionCallbacks();
- }
-
- ~InsertionCallbackDeferer()
- {
- ContainerNode::resumeInsertionCallbacks();
- }
-};
-
class PostAttachCallbackDisabler {
public:
PostAttachCallbackDisabler(ContainerNode* node)
diff --git a/Source/core/dom/ContainerNodeAlgorithms.cpp b/Source/core/dom/ContainerNodeAlgorithms.cpp
index e06aedc..59d65ed 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.cpp
+++ b/Source/core/dom/ContainerNodeAlgorithms.cpp
@@ -35,7 +35,7 @@
void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode* node)
{
ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.previousNode()) {
+ while (RefPtr<Node> child = snapshot.nextNode()) {
// If we have been removed from the document during this loop, then
// we don't want to tell the rest of our children that they've been
// inserted into the document because they haven't.
@@ -69,7 +69,7 @@
void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode* node)
{
ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.previousNode()) {
+ while (RefPtr<Node> child = snapshot.nextNode()) {
// If we have been added to the document during this loop, then we
// don't want to tell the rest of our children that they've been
// removed from the document because they haven't.
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index d591b77..5e09a6b 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -219,15 +219,14 @@
RefPtr<Document> protectDocument(node->document());
RefPtr<Node> protectNode(node);
- InsertionCallbackDeferer insertionCallbackDeferer;
if (m_insertionPoint->inDocument())
notifyNodeInsertedIntoDocument(node);
else if (node->isContainerNode())
notifyNodeInsertedIntoTree(toContainerNode(node));
- for (size_t i = m_postInsertionNotificationTargets.size(); i; --i)
- m_postInsertionNotificationTargets[i - 1]->didNotifySubtreeInsertions(m_insertionPoint);
+ for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i)
+ m_postInsertionNotificationTargets[i]->didNotifySubtreeInsertions(m_insertionPoint);
}
diff --git a/Source/core/dom/CustomElementConstructor.cpp b/Source/core/dom/CustomElementConstructor.cpp
deleted file mode 100644
index ff02ea7..0000000
--- a/Source/core/dom/CustomElementConstructor.cpp
+++ /dev/null
@@ -1,67 +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.
- */
-
-#include "config.h"
-
-#include "core/dom/CustomElementConstructor.h"
-
-#include "core/dom/CustomElementRegistry.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-
-namespace WebCore {
-
-PassRefPtr<CustomElementConstructor> CustomElementConstructor::create(Document* document, const QualifiedName& tag, const AtomicString& typeExtension) {
- return adoptRef(new CustomElementConstructor(document, tag, typeExtension));
-}
-
-CustomElementConstructor::CustomElementConstructor(Document* document, const QualifiedName& tag, const AtomicString& typeExtension)
- : ContextDestructionObserver(document)
- , m_tag(tag)
- , m_typeExtension(typeExtension)
-{
-}
-
-Document* CustomElementConstructor::document() const {
- return toDocument(m_scriptExecutionContext);
-}
-
-PassRefPtr<Element> CustomElementConstructor::createElement(ExceptionCode& ec) {
- if (!document())
- return 0;
- RefPtr<Element> result;
- {
- CustomElementRegistry::CallbackDeliveryScope deliveryScope;
- result = document()->createElementNS(m_tag.namespaceURI(), m_tag.localName(), m_typeExtension, ec);
- }
- return result.release();
-}
-
-}
diff --git a/Source/core/dom/CustomElementConstructor.h b/Source/core/dom/CustomElementConstructor.h
deleted file mode 100644
index 5a006c0..0000000
--- a/Source/core/dom/CustomElementConstructor.h
+++ /dev/null
@@ -1,64 +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 CustomElementConstructor_h
-#define CustomElementConstructor_h
-
-#include "core/dom/ContextDestructionObserver.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/dom/QualifiedName.h"
-#include <wtf/Forward.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class Document;
-class Element;
-
-class CustomElementConstructor: public RefCounted<CustomElementConstructor>, public ContextDestructionObserver
-{
-public:
- static PassRefPtr<CustomElementConstructor> create(Document* document, const QualifiedName& tagName, const AtomicString& typeExtension);
- virtual ~CustomElementConstructor() {}
-
- PassRefPtr<Element> createElement(ExceptionCode&);
-
-private:
- explicit CustomElementConstructor(Document* document, const QualifiedName& tag, const AtomicString& typeExtension);
- Document* document() const;
-
- QualifiedName m_tag;
- AtomicString m_typeExtension;
-};
-
-}
-
-#endif // CustomElementConstructor_h
diff --git a/Source/core/dom/CustomElementConstructor.idl b/Source/core/dom/CustomElementConstructor.idl
deleted file mode 100644
index 4b6d84f..0000000
--- a/Source/core/dom/CustomElementConstructor.idl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-[
- NoInterfaceObject,
- EnabledAtRuntime=customDOMElements,
- WrapAsFunction,
- CustomLegacyCall
-] interface CustomElementConstructor {
-};
diff --git a/Source/core/dom/CustomElementDefinition.cpp b/Source/core/dom/CustomElementDefinition.cpp
index 48326b7..70666dc 100644
--- a/Source/core/dom/CustomElementDefinition.cpp
+++ b/Source/core/dom/CustomElementDefinition.cpp
@@ -38,19 +38,13 @@
namespace WebCore {
-PassRefPtr<CustomElementDefinition> CustomElementDefinition::create(ScriptState* state, const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, const ScriptValue& prototype)
+PassRefPtr<CustomElementDefinition> CustomElementDefinition::create(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI)
{
- ASSERT(CustomElementHelpers::isValidPrototypeParameter(prototype, state));
- ASSERT(name == type || QualifiedName(nullAtom, name, namespaceURI) == *CustomElementHelpers::findLocalName(prototype));
- ASSERT(namespaceURI == HTMLNames::xhtmlNamespaceURI || namespaceURI == SVGNames::svgNamespaceURI);
-
- RefPtr<CustomElementDefinition> created = adoptRef(new CustomElementDefinition(type, name, namespaceURI, prototype));
- return created.release();
+ return adoptRef(new CustomElementDefinition(type, name, namespaceURI));
}
-CustomElementDefinition::CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, const ScriptValue& prototype)
- : m_prototype(prototype)
- , m_type(type)
+CustomElementDefinition::CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI)
+ : m_type(type)
, m_tag(QualifiedName(nullAtom, name, namespaceURI))
{
}
diff --git a/Source/core/dom/CustomElementDefinition.h b/Source/core/dom/CustomElementDefinition.h
index a947239..ac5fe2d 100644
--- a/Source/core/dom/CustomElementDefinition.h
+++ b/Source/core/dom/CustomElementDefinition.h
@@ -43,7 +43,7 @@
class CustomElementDefinition : public RefCounted<CustomElementDefinition> {
public:
- static PassRefPtr<CustomElementDefinition> create(ScriptState*, const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, const ScriptValue& prototype);
+ static PassRefPtr<CustomElementDefinition> create(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI);
virtual ~CustomElementDefinition() {}
@@ -72,12 +72,8 @@
CustomElementKind kind() const { return isTypeExtension() ? TypeExtension : CustomTag; }
bool isTypeExtension() const { return type() != name(); }
- const ScriptValue& prototype() { return m_prototype; }
-
private:
- CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI, const ScriptValue& prototype);
-
- ScriptValue m_prototype;
+ CustomElementDefinition(const AtomicString& type, const AtomicString& name, const AtomicString& namespaceURI);
AtomicString m_type;
QualifiedName m_tag;
diff --git a/Source/core/dom/CustomElementRegistry.cpp b/Source/core/dom/CustomElementRegistry.cpp
index c812306..3bad3ba 100644
--- a/Source/core/dom/CustomElementRegistry.cpp
+++ b/Source/core/dom/CustomElementRegistry.cpp
@@ -99,17 +99,17 @@
return Document::isValidName(name.string());
}
-PassRefPtr<CustomElementConstructor> CustomElementRegistry::registerElement(ScriptState* state, const AtomicString& userSuppliedName, const Dictionary& options, ExceptionCode& ec)
+ScriptValue CustomElementRegistry::registerElement(ScriptState* state, const AtomicString& userSuppliedName, const Dictionary& options, ExceptionCode& ec)
{
RefPtr<CustomElementRegistry> protect(this);
if (!CustomElementHelpers::isFeatureAllowed(state))
- return 0;
+ return ScriptValue();
AtomicString name = userSuppliedName.lower();
if (!isValidName(name)) {
ec = INVALID_CHARACTER_ERR;
- return 0;
+ return ScriptValue();
}
ScriptValue prototypeValue;
@@ -120,24 +120,24 @@
// behavior. The spec should be fixed before WebKit implements
// it. https://www.w3.org/Bugs/Public/show_bug.cgi?id=20801
ec = INVALID_STATE_ERR;
- return 0;
+ return ScriptValue();
}
AtomicString namespaceURI;
if (!CustomElementHelpers::isValidPrototypeParameter(prototypeValue, state, namespaceURI)) {
ec = INVALID_STATE_ERR;
- return 0;
+ return ScriptValue();
}
if (namespaceURI.isNull()) {
ec = NAMESPACE_ERR;
- return 0;
+ return ScriptValue();
}
AtomicString type = name;
if (m_definitions.contains(type)) {
ec = INVALID_STATE_ERR;
- return 0;
+ return ScriptValue();
}
const QualifiedName* prototypeTagName = CustomElementHelpers::findLocalName(prototypeValue);
@@ -147,28 +147,31 @@
// A script execution could happen in isValidPrototypeParameter(), which kills the document.
if (!document()) {
ec = INVALID_STATE_ERR;
- return 0;
+ return ScriptValue();
}
- RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create(state, type, name, namespaceURI, prototypeValue);
+ ASSERT(name == type || QualifiedName(nullAtom, name, namespaceURI) == *CustomElementHelpers::findLocalName(prototypeValue));
+ ASSERT(namespaceURI == HTMLNames::xhtmlNamespaceURI || namespaceURI == SVGNames::svgNamespaceURI);
- RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::create(document(), definition->tagQName(), definition->isTypeExtension() ? definition->type() : nullAtom);
- if (!CustomElementHelpers::initializeConstructorWrapper(constructor.get(), prototypeValue, state)) {
+ RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create(type, name, namespaceURI);
+ ScriptValue constructor = CustomElementHelpers::createConstructor(state, prototypeValue, document(), definition->namespaceURI(), definition->name(), definition->isTypeExtension() ? definition->type() : nullAtom);
+ if (constructor.hasNoValue()) {
ec = INVALID_STATE_ERR;
- return 0;
+ return ScriptValue();
}
+ ASSERT(constructor.isFunction());
m_definitions.add(definition->type(), definition);
// Upgrade elements that were waiting for this definition.
CustomElementUpgradeCandidateMap::ElementSet upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition.get());
- CustomElementHelpers::upgradeWrappers(document(), upgradeCandidates, definition->prototype());
+ CustomElementHelpers::didRegisterDefinition(definition.get(), document(), upgradeCandidates, prototypeValue);
for (CustomElementUpgradeCandidateMap::ElementSet::iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it) {
(*it)->setNeedsStyleRecalc(); // :unresolved has changed
activate(CustomElementInvocation(*it));
}
- return constructor.release();
+ return constructor;
}
bool CustomElementRegistry::isUnresolved(Element* element) const
diff --git a/Source/core/dom/CustomElementRegistry.h b/Source/core/dom/CustomElementRegistry.h
index 9ae6c86..532f623 100644
--- a/Source/core/dom/CustomElementRegistry.h
+++ b/Source/core/dom/CustomElementRegistry.h
@@ -31,9 +31,8 @@
#ifndef CustomElementRegistry_h
#define CustomElementRegistry_h
-#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/ScriptValue.h"
#include "core/dom/ContextDestructionObserver.h"
-#include "core/dom/CustomElementConstructor.h"
#include "core/dom/CustomElementUpgradeCandidateMap.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/QualifiedName.h"
@@ -52,6 +51,7 @@
class Dictionary;
class Document;
class Element;
+class ScriptState;
class CustomElementInvocation {
public:
@@ -78,7 +78,7 @@
explicit CustomElementRegistry(Document*);
~CustomElementRegistry();
- PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&);
+ ScriptValue registerElement(ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&);
bool isUnresolved(Element*) const;
PassRefPtr<CustomElementDefinition> findFor(Element*) const;
diff --git a/Source/core/dom/DOMError.cpp b/Source/core/dom/DOMError.cpp
index 38f6781..a8f316c 100644
--- a/Source/core/dom/DOMError.cpp
+++ b/Source/core/dom/DOMError.cpp
@@ -36,4 +36,11 @@
ScriptWrappable::init(this);
}
+DOMError::DOMError(const String& name, const String& message)
+ : m_name(name)
+ , m_message(message)
+{
+ ScriptWrappable::init(this);
+}
+
} // namespace WebCore
diff --git a/Source/core/dom/DOMError.h b/Source/core/dom/DOMError.h
index ae23e74..b74b7f0 100644
--- a/Source/core/dom/DOMError.h
+++ b/Source/core/dom/DOMError.h
@@ -39,13 +39,20 @@
{
return adoptRef(new DOMError(name));
}
+ static PassRefPtr<DOMError> create(const String& name, const String& message)
+ {
+ return adoptRef(new DOMError(name, message));
+ }
const String& name() const { return m_name; }
+ const String& message() const { return m_message; }
private:
explicit DOMError(const String& name);
+ explicit DOMError(const String& name, const String& message);
const String m_name;
+ const String m_message;
};
} // namespace WebCore
diff --git a/Source/core/dom/DOMError.idl b/Source/core/dom/DOMError.idl
index 5cded18..83522fa 100644
--- a/Source/core/dom/DOMError.idl
+++ b/Source/core/dom/DOMError.idl
@@ -29,5 +29,6 @@
NoInterfaceObject
] interface DOMError {
readonly attribute DOMString name;
+ readonly attribute DOMString message;
};
diff --git a/Source/core/dom/DOMCoreException.idl b/Source/core/dom/DOMException.idl
similarity index 98%
rename from Source/core/dom/DOMCoreException.idl
rename to Source/core/dom/DOMException.idl
index 3df6046..d4e9520 100644
--- a/Source/core/dom/DOMCoreException.idl
+++ b/Source/core/dom/DOMException.idl
@@ -28,8 +28,8 @@
[
DoNotCheckConstants,
- InterfaceName=DOMException
-] exception DOMCoreException {
+ ImplementedAs=DOMCoreException
+] exception DOMException {
readonly attribute unsigned short code;
readonly attribute DOMString name;
diff --git a/Source/core/dom/DOMExceptions.in b/Source/core/dom/DOMExceptions.in
index 0c33a88..433d0ba 100644
--- a/Source/core/dom/DOMExceptions.in
+++ b/Source/core/dom/DOMExceptions.in
@@ -1,8 +1,7 @@
namespace=DOMException
-core/dom/DOMCoreException
-core/dom/EventException
+core/dom/DOMException implementedAs=DOMCoreException
core/fileapi/FileException
-modules/webdatabase/SQLException
core/svg/SVGException
core/xml/XPathException
+modules/webdatabase/SQLException
diff --git a/Source/core/dom/DOMStringMap.cpp b/Source/core/dom/DOMStringMap.cpp
index b15e419..21415cd 100644
--- a/Source/core/dom/DOMStringMap.cpp
+++ b/Source/core/dom/DOMStringMap.cpp
@@ -32,4 +32,9 @@
{
}
+bool DOMStringMap::namedPropertyQuery(const AtomicString& name, ExceptionCode& ec)
+{
+ return contains(name);
+}
+
} // namespace WebCore
diff --git a/Source/core/dom/DOMStringMap.h b/Source/core/dom/DOMStringMap.h
index f5748a5..90a6019 100644
--- a/Source/core/dom/DOMStringMap.h
+++ b/Source/core/dom/DOMStringMap.h
@@ -69,6 +69,7 @@
{
getNames(names);
}
+ bool namedPropertyQuery(const AtomicString&, ExceptionCode&);
virtual Element* element() = 0;
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 063c4fd..6f0e65b 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -28,16 +28,6 @@
#include "config.h"
#include "core/dom/Document.h"
-#include <wtf/CurrentTime.h>
-#include <wtf/HashFunctions.h>
-#include <wtf/MainThread.h>
-#include <wtf/MemoryInstrumentationHashCountedSet.h>
-#include <wtf/MemoryInstrumentationHashMap.h>
-#include <wtf/MemoryInstrumentationHashSet.h>
-#include <wtf/MemoryInstrumentationVector.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/text/StringBuffer.h>
#include "CSSValueKeywords.h"
#include "HTMLElementFactory.h"
#include "HTMLNames.h"
@@ -66,12 +56,12 @@
#include "core/dom/CDATASection.h"
#include "core/dom/Comment.h"
#include "core/dom/ContextFeatures.h"
-#include "core/dom/CustomElementConstructor.h"
#include "core/dom/CustomElementRegistry.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/DOMNamedFlowCollection.h"
#include "core/dom/DocumentEventQueue.h"
#include "core/dom/DocumentFragment.h"
+#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/DocumentSharedObjectPool.h"
#include "core/dom/DocumentStyleSheetCollection.h"
@@ -89,6 +79,7 @@
#include "core/dom/NodeFilter.h"
#include "core/dom/NodeIterator.h"
#include "core/dom/NodeRareData.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/NodeWithIndex.h"
#include "core/dom/PageTransitionEvent.h"
@@ -127,6 +118,7 @@
#include "core/html/HTMLLinkElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/html/HTMLNameCollection.h"
+#include "core/html/HTMLScriptElement.h"
#include "core/html/HTMLStyleElement.h"
#include "core/html/HTMLTitleElement.h"
#include "core/html/PluginDocument.h"
@@ -165,6 +157,7 @@
#include "core/page/PointerLockController.h"
#include "core/page/Settings.h"
#include "core/page/UserContentURLPattern.h"
+#include "core/page/ValidationMessageClient.h"
#include "core/page/animation/AnimationController.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/platform/DateComponents.h"
@@ -181,7 +174,6 @@
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderArena.h"
-#include "core/rendering/RenderFullScreen.h"
#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderNamedFlowThread.h"
#include "core/rendering/RenderTextControl.h"
@@ -203,6 +195,17 @@
#include "weborigin/SchemeRegistry.h"
#include "weborigin/SecurityOrigin.h"
#include "weborigin/SecurityPolicy.h"
+#include "wtf/CurrentTime.h"
+#include "wtf/HashFunctions.h"
+#include "wtf/MainThread.h"
+#include "wtf/MemoryInstrumentationHashCountedSet.h"
+#include "wtf/MemoryInstrumentationHashMap.h"
+#include "wtf/MemoryInstrumentationHashSet.h"
+#include "wtf/MemoryInstrumentationVector.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/StdLibExtras.h"
+#include "wtf/UnusedParam.h"
+#include "wtf/text/StringBuffer.h"
using namespace std;
using namespace WTF;
@@ -388,6 +391,8 @@
document->didRunCheckFocusedNodeTask();
if (!document->focusedNode())
return;
+ if (document->childNeedsStyleRecalc())
+ return;
if (document->focusedNode()->renderer() && document->focusedNode()->renderer()->needsLayout())
return;
if (!document->focusedNode()->isFocusable())
@@ -449,7 +454,6 @@
, m_designMode(inherit)
, m_hasAnnotatedRegions(false)
, m_annotatedRegionsDirty(false)
- , m_createRenderers(true)
, m_accessKeyMapValid(false)
, m_useSecureKeyboardEntryWhenActive(false)
, m_documentClasses(documentClasses)
@@ -460,10 +464,7 @@
, m_eventQueue(DocumentEventQueue::create(this))
, m_weakFactory(this)
, m_idAttributeName(idAttr)
- , m_areKeysEnabledInFullScreen(0)
- , m_fullScreenRenderer(0)
- , m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
- , m_isAnimatingFullScreen(false)
+ , m_hasFullscreenController(false)
, m_loadEventDelayCount(0)
, m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
, m_referrerPolicy(ReferrerPolicyDefault)
@@ -620,8 +621,6 @@
m_documentElement = 0;
m_contextFeatures = ContextFeatures::defaultSwitch();
m_userActionElements.documentDidRemoveLastRef();
- m_fullScreenElement = 0;
- m_fullScreenElementStack.clear();
detachParser();
@@ -643,6 +642,9 @@
if (m_scriptedAnimationController)
m_scriptedAnimationController->clearDocumentPointer();
m_scriptedAnimationController.clear();
+
+ if (m_lifecycleNotifier)
+ m_lifecycleNotifier->notifyDocumentWasDisposed();
}
Element* Document::getElementById(const AtomicString& id) const
@@ -828,16 +830,16 @@
return element;
}
-PassRefPtr<CustomElementConstructor> Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionCode& ec)
+ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionCode& ec)
{
return registerElement(state, name, Dictionary(), ec);
}
-PassRefPtr<CustomElementConstructor> Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionCode& ec)
+ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionCode& ec)
{
if (!isHTMLDocument() && !isXHTMLDocument()) {
ec = NOT_SUPPORTED_ERR;
- return 0;
+ return ScriptValue();
}
return ensureCustomElementRegistry()->registerElement(state, name, options, ec);
@@ -1112,11 +1114,6 @@
return RuntimeEnabledFeatures::cssCompositingEnabled();
}
-bool Document::cssGridLayoutEnabled() const
-{
- return settings() && settings()->cssGridLayoutEnabled();
-}
-
PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
{
if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderer())
@@ -1537,24 +1534,83 @@
return Range::create(this);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionCode& ec)
{
+ // FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
if (!root) {
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return NodeIterator::create(root, whatToShow, filter, expandEntityReferences);
+ return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionCode& ec)
{
if (!root) {
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return TreeWalker::create(root, whatToShow, filter, expandEntityReferences);
+ // FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
+ // NodeFilter.
+ return NodeIterator::create(root, whatToShow, PassRefPtr<NodeFilter>());
+}
+
+PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionCode& ec)
+{
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ // FIXME: Ditto.
+ return NodeIterator::create(root, whatToShow, filter);
+}
+
+PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+{
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ // FIXME: Warn if |expandEntityReferences| is specified. This optional argument is deprecated in DOM4.
+ UNUSED_PARAM(expandEntityReferences);
+ return NodeIterator::create(root, whatToShow, filter);
+}
+
+PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionCode& ec)
+{
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
+}
+
+PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionCode& ec)
+{
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
+}
+
+PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionCode& ec)
+{
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return TreeWalker::create(root, whatToShow, filter);
+}
+
+PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
+{
+ UNUSED_PARAM(expandEntityReferences);
+ if (!root) {
+ ec = NOT_SUPPORTED_ERR;
+ return 0;
+ }
+ return TreeWalker::create(root, whatToShow, filter);
}
void Document::scheduleForcedStyleRecalc()
@@ -1669,7 +1725,7 @@
renderer()->setStyle(documentStyle.release());
}
- for (Node* n = lastChild(); n; n = n->previousSibling()) {
+ for (Node* n = firstChild(); n; n = n->nextSibling()) {
if (!n->isElementNode())
continue;
Element* element = toElement(n);
@@ -1867,13 +1923,13 @@
m_styleResolver.clear();
}
-void Document::attach()
+void Document::attach(const AttachContext& context)
{
ASSERT(!attached());
ASSERT(!m_axObjectCache || this != topDocument());
if (!m_renderArena)
- m_renderArena = adoptPtr(new RenderArena);
+ m_renderArena = RenderArena::create();
// Create the rendering tree
setRenderer(new (m_renderArena.get()) RenderView(this));
@@ -1881,23 +1937,24 @@
recalcStyle(Force);
- ContainerNode::attach();
+ ContainerNode::attach(context);
}
-void Document::detach()
+void Document::detach(const AttachContext& context)
{
ASSERT(attached());
- if (page())
+ if (page()) {
page()->pointerLockController()->documentDetached(this);
+ if (ValidationMessageClient* client = page()->validationMessageClient())
+ client->documentDetached(*this);
+ }
if (this == topDocument())
clearAXObjectCache();
stopActiveDOMObjects();
m_eventQueue->close();
- m_fullScreenChangeEventTargetQueue.clear();
- m_fullScreenErrorEventTargetQueue.clear();
// FIXME: consider using ActiveDOMObject.
if (m_scriptedAnimationController)
@@ -1920,14 +1977,11 @@
// indicate destruction mode, i.e. attached() but renderer == 0
setRenderer(0);
- if (m_fullScreenRenderer)
- setFullScreenRenderer(0);
-
m_hoverNode = 0;
m_focusedNode = 0;
m_activeElement = 0;
- ContainerNode::detach();
+ ContainerNode::detach(context);
unscheduleStyleRecalc();
@@ -1947,6 +2001,9 @@
if (m_mediaQueryMatcher)
m_mediaQueryMatcher->documentDestroyed();
+
+ if (m_lifecycleNotifier)
+ m_lifecycleNotifier->notifyDocumentWasDetached();
}
void Document::prepareForDestruction()
@@ -2302,13 +2359,15 @@
// AX object to send the notification to. getOrCreate will make sure that an valid AX object
// exists in the cache (we ignore the return value because we don't need it here). This is
// only safe to call when a layout is not in progress, so it can not be used in postNotification.
- axObjectCache()->getOrCreate(renderObject);
- if (this == topDocument())
- axObjectCache()->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
- else {
- // AXLoadComplete can only be posted on the top document, so if it's a document
- // in an iframe that just finished loading, post AXLayoutComplete instead.
- axObjectCache()->postNotification(renderObject, AXObjectCache::AXLayoutComplete, true);
+ if (AXObjectCache* cache = axObjectCache()) {
+ cache->getOrCreate(renderObject);
+ if (this == topDocument()) {
+ cache->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
+ } else {
+ // AXLoadComplete can only be posted on the top document, so if it's a document
+ // in an iframe that just finished loading, post AXLayoutComplete instead.
+ cache->postNotification(renderObject, AXObjectCache::AXLayoutComplete, true);
+ }
}
}
@@ -3105,12 +3164,14 @@
void Document::hoveredNodeDetached(Node* node)
{
- if (!m_hoverNode || (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != m_hoverNode->parentNode())))
+ if (!m_hoverNode)
return;
- m_hoverNode = node->parentNode();
- while (m_hoverNode && !m_hoverNode->renderer())
- m_hoverNode = m_hoverNode->parentNode();
+ NodeRenderingTraversal::ParentDetails details;
+ if (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != NodeRenderingTraversal::parent(m_hoverNode.get(), &details)))
+ return;
+
+ for (m_hoverNode = NodeRenderingTraversal::parent(node, &details); m_hoverNode && !m_hoverNode->renderer(); m_hoverNode = NodeRenderingTraversal::parent(m_hoverNode.get(), &details)) { }
// If the mouse cursor is not visible, do not clear existing
// hover effects on the ancestors of |node| and do not invoke
@@ -3124,12 +3185,17 @@
void Document::activeChainNodeDetached(Node* node)
{
- if (!m_activeElement || (node != m_activeElement && (!m_activeElement->isTextNode() || node != m_activeElement->parentNode())))
+ if (!m_activeElement)
return;
- m_activeElement = node->parentElement();
- while (m_activeElement && !m_activeElement->renderer())
- m_activeElement = m_activeElement->parentElement();
+ NodeRenderingTraversal::ParentDetails details;
+ if (node != m_activeElement && (!m_activeElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeElement.get(), &details)))
+ return;
+
+ Node* activeNode = NodeRenderingTraversal::parent(node, &details);
+ for (; activeNode && activeNode->isElementNode() && !activeNode->renderer(); activeNode = NodeRenderingTraversal::parent(activeNode, &details)) { }
+
+ m_activeElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
}
const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const
@@ -3443,20 +3509,20 @@
// FIXME: This should update markers for spelling and grammar checking.
}
-void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
{
DOMWindow* domWindow = this->domWindow();
if (!domWindow)
return;
- domWindow->setAttributeEventListener(eventType, listener);
+ domWindow->setAttributeEventListener(eventType, listener, isolatedWorld);
}
-EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
+EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
{
DOMWindow* domWindow = this->domWindow();
if (!domWindow)
return 0;
- return domWindow->getAttributeEventListener(eventType);
+ return domWindow->getAttributeEventListener(eventType, isolatedWorld);
}
void Document::dispatchWindowEvent(PassRefPtr<Event> event, PassRefPtr<EventTarget> target)
@@ -3835,16 +3901,6 @@
renderView()->setIsInWindow(false);
}
-void Document::setShouldCreateRenderers(bool f)
-{
- m_createRenderers = f;
-}
-
-bool Document::shouldCreateRenderers()
-{
- return m_createRenderers;
-}
-
// Support for Javascript execCommand, and related methods
static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
@@ -3920,6 +3976,18 @@
return KURL();
}
+void Document::pushCurrentScript(PassRefPtr<HTMLScriptElement> newCurrentScript)
+{
+ ASSERT(newCurrentScript);
+ m_currentScriptStack.append(newCurrentScript);
+}
+
+void Document::popCurrentScript()
+{
+ ASSERT(!m_currentScriptStack.isEmpty());
+ m_currentScriptStack.removeLast();
+}
+
void Document::applyXSLTransform(ProcessingInstruction* pi)
{
UseCounter::count(this, UseCounter::XSLProcessingInstruction);
@@ -4601,446 +4669,6 @@
dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
}
-bool Document::fullScreenIsAllowedForElement(Element* element) const
-{
- ASSERT(element);
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document()->ownerElement());
-}
-
-void Document::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
-{
- // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
- // for full screen mode, and do not have the concept of a full screen element stack.
- bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
-
- do {
- if (!element)
- element = documentElement();
-
- // 1. If any of the following conditions are true, terminate these steps and queue a task to fire
- // an event named fullscreenerror with its bubbles attribute set to true on the context object's
- // node document:
-
- // The context object is not in a document.
- if (!element->inDocument())
- break;
-
- // The context object's node document, or an ancestor browsing context's document does not have
- // the fullscreen enabled flag set.
- if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenIsAllowedForElement(element))
- break;
-
- // The context object's node document fullscreen element stack is not empty and its top element
- // is not an ancestor of the context object. (NOTE: Ignore this requirement if the request was
- // made via the legacy Mozilla-style API.)
- if (!m_fullScreenElementStack.isEmpty() && !inLegacyMozillaMode) {
- Element* lastElementOnStack = m_fullScreenElementStack.last().get();
- if (lastElementOnStack == element || !lastElementOnStack->contains(element))
- break;
- }
-
- // A descendant browsing context's document has a non-empty fullscreen element stack.
- bool descendentHasNonEmptyStack = false;
- for (Frame* descendant = frame() ? frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
- if (descendant->document()->webkitFullscreenElement()) {
- descendentHasNonEmptyStack = true;
- break;
- }
- }
- if (descendentHasNonEmptyStack && !inLegacyMozillaMode)
- break;
-
- // This algorithm is not allowed to show a pop-up:
- // An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
- // - an activation behavior is currently being processed whose click event was trusted, or
- // - the event listener for a trusted click event is being handled.
- if (!ScriptController::processingUserGesture())
- break;
-
- // There is a previously-established user preference, security risk, or platform limitation.
- if (!page() || !page()->settings()->fullScreenEnabled())
- break;
-
- // 2. Let doc be element's node document. (i.e. "this")
- Document* currentDoc = this;
-
- // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc.
- Deque<Document*> docs;
-
- do {
- docs.prepend(currentDoc);
- currentDoc = currentDoc->ownerElement() ? currentDoc->ownerElement()->document() : 0;
- } while (currentDoc);
-
- // 4. For each document in docs, run these substeps:
- Deque<Document*>::iterator current = docs.begin(), following = docs.begin();
-
- do {
- ++following;
-
- // 1. Let following document be the document after document in docs, or null if there is no
- // such document.
- Document* currentDoc = *current;
- Document* followingDoc = following != docs.end() ? *following : 0;
-
- // 2. If following document is null, push context object on document's fullscreen element
- // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
- // set to true on the document.
- if (!followingDoc) {
- currentDoc->pushFullscreenElementStack(element);
- addDocumentToFullScreenChangeEventQueue(currentDoc);
- continue;
- }
-
- // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
- // is not following document's browsing context container,
- Element* topElement = currentDoc->webkitFullscreenElement();
- if (!topElement || topElement != followingDoc->ownerElement()) {
- // ...push following document's browsing context container on document's fullscreen element
- // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
- // set to true on document.
- currentDoc->pushFullscreenElementStack(followingDoc->ownerElement());
- addDocumentToFullScreenChangeEventQueue(currentDoc);
- continue;
- }
-
- // 4. Otherwise, do nothing for this document. It stays the same.
- } while (++current != docs.end());
-
- // 5. Return, and run the remaining steps asynchronously.
- // 6. Optionally, perform some animation.
- m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
- page()->chrome().client()->enterFullScreenForElement(element);
-
- // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
- return;
- } while (0);
-
- m_fullScreenErrorEventTargetQueue.append(element ? element : documentElement());
- m_fullScreenChangeDelayTimer.startOneShot(0);
-}
-
-void Document::webkitCancelFullScreen()
-{
- // The Mozilla "cancelFullScreen()" API behaves like the W3C "fully exit fullscreen" behavior, which
- // is defined as:
- // "To fully exit fullscreen act as if the exitFullscreen() method was invoked on the top-level browsing
- // context's document and subsequently empty that document's fullscreen element stack."
- if (!topDocument()->webkitFullscreenElement())
- return;
-
- // To achieve that aim, remove all the elements from the top document's stack except for the first before
- // calling webkitExitFullscreen():
- Vector<RefPtr<Element> > replacementFullscreenElementStack;
- replacementFullscreenElementStack.append(topDocument()->webkitFullscreenElement());
- topDocument()->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
-
- topDocument()->webkitExitFullscreen();
-}
-
-void Document::webkitExitFullscreen()
-{
- // The exitFullscreen() method must run these steps:
-
- // 1. Let doc be the context object. (i.e. "this")
- Document* currentDoc = this;
-
- // 2. If doc's fullscreen element stack is empty, terminate these steps.
- if (m_fullScreenElementStack.isEmpty())
- return;
-
- // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
- // element stack (if any), ordered so that the child of the doc is last and the document furthest
- // away from the doc is first.
- Deque<RefPtr<Document> > descendants;
- for (Frame* descendant = frame() ? frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
- if (descendant->document()->webkitFullscreenElement())
- descendants.prepend(descendant->document());
- }
-
- // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
- // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
- for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
- (*i)->clearFullscreenElementStack();
- addDocumentToFullScreenChangeEventQueue(i->get());
- }
-
- // 5. While doc is not null, run these substeps:
- Element* newTop = 0;
- while (currentDoc) {
- // 1. Pop the top element of doc's fullscreen element stack.
- currentDoc->popFullscreenElementStack();
-
- // If doc's fullscreen element stack is non-empty and the element now at the top is either
- // not in a document or its node document is not doc, repeat this substep.
- newTop = currentDoc->webkitFullscreenElement();
- if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
- continue;
-
- // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
- // on doc.
- addDocumentToFullScreenChangeEventQueue(currentDoc);
-
- // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
- // container, set doc to that browsing context container's node document.
- if (!newTop && currentDoc->ownerElement()) {
- currentDoc = currentDoc->ownerElement()->document();
- continue;
- }
-
- // 4. Otherwise, set doc to null.
- currentDoc = 0;
- }
-
- // 6. Return, and run the remaining steps asynchronously.
- // 7. Optionally, perform some animation.
-
- if (!page())
- return;
-
- // Only exit out of full screen window mode if there are no remaining elements in the
- // full screen stack.
- if (!newTop) {
- page()->chrome().client()->exitFullScreenForElement(m_fullScreenElement.get());
- return;
- }
-
- // Otherwise, notify the chrome of the new full screen element.
- page()->chrome().client()->enterFullScreenForElement(newTop);
-}
-
-bool Document::webkitFullscreenEnabled() const
-{
- // 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
- // browsing context's documents have their fullscreen enabled flag set, or false otherwise.
-
- // Top-level browsing contexts are implied to have their allowFullScreen attribute set.
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, ownerElement());
-}
-
-void Document::webkitWillEnterFullScreenForElement(Element* element)
-{
- if (!attached())
- return;
-
- ASSERT(element);
-
- // Protect against being called after the document has been removed from the page.
- if (!page())
- return;
-
- ASSERT(page()->settings()->fullScreenEnabled());
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->unwrapRenderer();
-
- m_fullScreenElement = element;
-
-#if USE(NATIVE_FULLSCREEN_VIDEO)
- if (element && element->isMediaElement())
- return;
-#endif
-
- // Create a placeholder block for a the full-screen element, to keep the page from reflowing
- // when the element is removed from the normal flow. Only do this for a RenderBox, as only
- // a box will have a frameRect. The placeholder will be created in setFullScreenRenderer()
- // during layout.
- RenderObject* renderer = m_fullScreenElement->renderer();
- bool shouldCreatePlaceholder = renderer && renderer->isBox();
- if (shouldCreatePlaceholder) {
- m_savedPlaceholderFrameRect = toRenderBox(renderer)->frameRect();
- m_savedPlaceholderRenderStyle = RenderStyle::clone(renderer->style());
- }
-
- if (m_fullScreenElement != documentElement())
- RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() : 0, this);
-
- m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
-
- recalcStyle(Force);
-}
-
-void Document::webkitDidEnterFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!attached())
- return;
-
- m_fullScreenElement->didBecomeFullscreenElement();
-
- m_fullScreenChangeDelayTimer.startOneShot(0);
-}
-
-void Document::webkitWillExitFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!attached())
- return;
-
- m_fullScreenElement->willStopBeingFullscreenElement();
-}
-
-void Document::webkitDidExitFullScreenForElement(Element*)
-{
- if (!m_fullScreenElement)
- return;
-
- if (!attached())
- return;
-
- m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
-
- m_areKeysEnabledInFullScreen = false;
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->unwrapRenderer();
-
- m_fullScreenElement = 0;
- scheduleForcedStyleRecalc();
-
- // When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
- // means that the events will be queued there. So if we have no events here, start the timer on
- // the exiting document.
- Document* exitingDocument = this;
- if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
- exitingDocument = topDocument();
- exitingDocument->m_fullScreenChangeDelayTimer.startOneShot(0);
-}
-
-void Document::setFullScreenRenderer(RenderFullScreen* renderer)
-{
- if (renderer == m_fullScreenRenderer)
- return;
-
- if (renderer && m_savedPlaceholderRenderStyle)
- renderer->createPlaceholder(m_savedPlaceholderRenderStyle.release(), m_savedPlaceholderFrameRect);
- else if (renderer && m_fullScreenRenderer && m_fullScreenRenderer->placeholder()) {
- RenderBlock* placeholder = m_fullScreenRenderer->placeholder();
- renderer->createPlaceholder(RenderStyle::clone(placeholder->style()), placeholder->frameRect());
- }
-
- if (m_fullScreenRenderer)
- m_fullScreenRenderer->destroy();
- ASSERT(!m_fullScreenRenderer);
-
- m_fullScreenRenderer = renderer;
-}
-
-void Document::fullScreenRendererDestroyed()
-{
- m_fullScreenRenderer = 0;
-}
-
-void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
-{
- // Since we dispatch events in this function, it's possible that the
- // document will be detached and GC'd. We protect it here to make sure we
- // can finish the function successfully.
- RefPtr<Document> protectDocument(this);
- Deque<RefPtr<Node> > changeQueue;
- m_fullScreenChangeEventTargetQueue.swap(changeQueue);
- Deque<RefPtr<Node> > errorQueue;
- m_fullScreenErrorEventTargetQueue.swap(errorQueue);
-
- while (!changeQueue.isEmpty()) {
- RefPtr<Node> node = changeQueue.takeFirst();
- if (!node)
- node = documentElement();
- // The dispatchEvent below may have blown away our documentElement.
- if (!node)
- continue;
-
- // If the element was removed from our tree, also message the documentElement. Since we may
- // have a document hierarchy, check that node isn't in another document.
- if (!contains(node.get()) && !node->inDocument())
- changeQueue.append(documentElement());
-
- node->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
- }
-
- while (!errorQueue.isEmpty()) {
- RefPtr<Node> node = errorQueue.takeFirst();
- if (!node)
- node = documentElement();
- // The dispatchEvent below may have blown away our documentElement.
- if (!node)
- continue;
-
- // If the element was removed from our tree, also message the documentElement. Since we may
- // have a document hierarchy, check that node isn't in another document.
- if (!contains(node.get()) && !node->inDocument())
- errorQueue.append(documentElement());
-
- node->dispatchEvent(Event::create(eventNames().webkitfullscreenerrorEvent, true, false));
- }
-}
-
-void Document::fullScreenElementRemoved()
-{
- m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
- webkitCancelFullScreen();
-}
-
-void Document::removeFullScreenElementOfSubtree(Node* node, bool amongChildrenOnly)
-{
- if (!m_fullScreenElement)
- return;
-
- bool elementInSubtree = false;
- if (amongChildrenOnly)
- elementInSubtree = m_fullScreenElement->isDescendantOf(node);
- else
- elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement->isDescendantOf(node);
-
- if (elementInSubtree)
- fullScreenElementRemoved();
-}
-
-void Document::setAnimatingFullScreen(bool flag)
-{
- if (m_isAnimatingFullScreen == flag)
- return;
- m_isAnimatingFullScreen = flag;
-
- if (m_fullScreenElement && m_fullScreenElement->isDescendantOf(this)) {
- m_fullScreenElement->setNeedsStyleRecalc();
- scheduleForcedStyleRecalc();
- }
-}
-
-void Document::clearFullscreenElementStack()
-{
- m_fullScreenElementStack.clear();
-}
-
-void Document::popFullscreenElementStack()
-{
- if (m_fullScreenElementStack.isEmpty())
- return;
-
- m_fullScreenElementStack.removeLast();
-}
-
-void Document::pushFullscreenElementStack(Element* element)
-{
- m_fullScreenElementStack.append(element);
-}
-
-void Document::addDocumentToFullScreenChangeEventQueue(Document* doc)
-{
- ASSERT(doc);
- Node* target = doc->webkitFullscreenElement();
- if (!target)
- target = doc->webkitCurrentFullScreenElement();
- if (!target)
- target = doc;
- m_fullScreenChangeEventTargetQueue.append(target);
-}
-
void Document::addToTopLayer(Element* element)
{
if (element->isInTopLayer())
@@ -5269,14 +4897,12 @@
return view()->visibleContentRect(ScrollableArea::IncludeScrollbars).size();
}
-#if ENABLE(CSS_DEVICE_ADAPTATION)
IntSize Document::initialViewportSize() const
{
if (!view())
return IntSize();
- return view()->initialViewportSize();
+ return view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
}
-#endif
Node* eventTargetNodeForDocument(Document* doc)
{
@@ -5423,6 +5049,14 @@
Vector<RefPtr<Node>, 32> nodesToAddToChain;
if (oldHoverObj != newHoverObj) {
+ // If the old hovered node is not nil but it's renderer is, it was probably detached as part of the :hover style
+ // (for instance by setting display:none in the :hover pseudo-class). In this case, the old hovered element
+ // must be updated, to ensure it's normal style is re-applied.
+ if (oldHoverNode && !oldHoverObj) {
+ if (!mustBeInActiveChain || oldHoverNode->inActiveChain())
+ nodesToRemoveFromChain.append(oldHoverNode);
+ }
+
// The old hover path only needs to be cleared up to (and not including) the common ancestor;
for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
@@ -5513,13 +5147,6 @@
info.addMember(m_renderer, "renderer");
info.addMember(m_weakFactory, "weakFactory");
info.addMember(m_idAttributeName, "idAttributeName");
- info.addMember(m_fullScreenElement, "fullScreenElement");
- info.addMember(m_fullScreenElementStack, "fullScreenElementStack");
- info.addMember(m_fullScreenRenderer, "fullScreenRenderer");
- info.addMember(m_fullScreenChangeDelayTimer, "fullScreenChangeDelayTimer");
- info.addMember(m_fullScreenChangeEventTargetQueue, "fullScreenChangeEventTargetQueue");
- info.addMember(m_fullScreenErrorEventTargetQueue, "fullScreenErrorEventTargetQueue");
- info.addMember(m_savedPlaceholderRenderStyle, "savedPlaceholderRenderStyle");
info.addMember(m_topLayerElements, "topLayerElements");
info.addMember(m_loadEventDelayTimer, "loadEventDelayTimer");
info.addMember(m_viewportArguments, "viewportArguments");
@@ -5599,4 +5226,11 @@
m_associatedFormControls.clear();
}
+void Document::addLifecycleObserver(DocumentLifecycleObserver* observer)
+{
+ if (!m_lifecycleNotifier)
+ m_lifecycleNotifier = DocumentLifecycleNotifier::create();
+ m_lifecycleNotifier->addObserver(observer);
+}
+
} // namespace WebCore
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index 3d53802..8c28505 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -28,6 +28,7 @@
#ifndef Document_h
#define Document_h
+#include "bindings/v8/ScriptValue.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/DOMTimeStamp.h"
#include "core/dom/DocumentEventQueue.h"
@@ -72,7 +73,6 @@
class CharacterData;
class Comment;
class ContextFeatures;
-class CustomElementConstructor;
class CustomElementRegistry;
class DOMImplementation;
class DOMNamedFlowCollection;
@@ -82,6 +82,8 @@
class Database;
class DatabaseThread;
class DocumentFragment;
+class DocumentLifecycleNotifier;
+class DocumentLifecycleObserver;
class DocumentLoader;
class DocumentMarkerController;
class DocumentParser;
@@ -108,6 +110,7 @@
class HTMLIFrameElement;
class HTMLMapElement;
class HTMLNameCollection;
+class HTMLScriptElement;
class HitTestRequest;
class HitTestResult;
class IntPoint;
@@ -130,7 +133,6 @@
class Range;
class RegisteredEventListener;
class RenderArena;
-class RenderFullScreen;
class RenderView;
class RequestAnimationFrameCallback;
class SVGDocumentExtensions;
@@ -325,8 +327,6 @@
bool regionBasedColumnsEnabled() const;
- bool cssGridLayoutEnabled() const;
-
/**
* Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by
* the boundaries of a node.
@@ -467,11 +467,15 @@
PassRefPtr<Range> createRange();
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
+ PassRefPtr<NodeIterator> createNodeIterator(Node* root, ExceptionCode&);
+ PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, ExceptionCode&);
+ PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionCode&);
+ PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow,
- PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
+ PassRefPtr<TreeWalker> createTreeWalker(Node* root, ExceptionCode&);
+ PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, ExceptionCode&);
+ PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionCode&);
+ PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences, ExceptionCode&);
// Special support for editing
PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
@@ -496,8 +500,8 @@
CachedResourceLoader* cachedResourceLoader() { return m_cachedResourceLoader.get(); }
- virtual void attach();
- virtual void detach();
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
void prepareForDestruction();
// Override ScriptExecutionContext methods to do additional work
@@ -700,8 +704,8 @@
DOMWindow* defaultView() const { return domWindow(); }
// Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
- void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
- EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
+ void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
+ EventListener* getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);
@@ -850,6 +854,10 @@
ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
+ HTMLScriptElement* currentScript() const { return !m_currentScriptStack.isEmpty() ? m_currentScriptStack.last().get() : 0; }
+ void pushCurrentScript(PassRefPtr<HTMLScriptElement>);
+ void popCurrentScript();
+
void applyXSLTransform(ProcessingInstruction* pi);
PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
@@ -906,9 +914,6 @@
void documentWillBecomeInactive();
- void setShouldCreateRenderers(bool);
- bool shouldCreateRenderers();
-
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
@@ -962,39 +967,9 @@
virtual DocumentEventQueue* eventQueue() const { return m_eventQueue.get(); }
const QualifiedName& idAttributeName() const { return m_idAttributeName; }
-
- bool webkitIsFullScreen() const { return m_fullScreenElement.get(); }
- bool webkitFullScreenKeyboardInputAllowed() const { return m_fullScreenElement.get() && m_areKeysEnabledInFullScreen; }
- Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
-
- enum FullScreenCheckType {
- EnforceIFrameAllowFullScreenRequirement,
- ExemptIFrameAllowFullScreenRequirement,
- };
- void requestFullScreenForElement(Element*, unsigned short flags, FullScreenCheckType);
- void webkitCancelFullScreen();
-
- void webkitWillEnterFullScreenForElement(Element*);
- void webkitDidEnterFullScreenForElement(Element*);
- void webkitWillExitFullScreenForElement(Element*);
- void webkitDidExitFullScreenForElement(Element*);
-
- void setFullScreenRenderer(RenderFullScreen*);
- RenderFullScreen* fullScreenRenderer() const { return m_fullScreenRenderer; }
- void fullScreenRendererDestroyed();
-
- void fullScreenChangeDelayTimerFired(Timer<Document>*);
- bool fullScreenIsAllowedForElement(Element*) const;
- void fullScreenElementRemoved();
- void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
- bool isAnimatingFullScreen() const { return m_isAnimatingFullScreen; }
- void setAnimatingFullScreen(bool);
-
- // W3C API
- bool webkitFullscreenEnabled() const;
- Element* webkitFullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; }
- void webkitExitFullscreen();
+ bool hasFullscreenController() const { return m_hasFullscreenController; }
+ void setHasFullscreenController() { m_hasFullscreenController = true; }
void webkitExitPointerLock();
Element* webkitPointerLockElement() const;
@@ -1039,10 +1014,7 @@
void resumeScheduledTasks();
IntSize viewportSize() const;
-
-#if ENABLE(CSS_DEVICE_ADAPTATION)
IntSize initialViewportSize() const;
-#endif
Prerenderer* prerenderer() { return m_prerenderer.get(); }
@@ -1050,8 +1022,8 @@
PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionCode&);
PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionCode&);
- PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionCode&);
- PassRefPtr<CustomElementConstructor> registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&);
+ ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionCode&);
+ ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionCode&);
CustomElementRegistry* registry() const { return m_registry.get(); }
CustomElementRegistry* ensureCustomElementRegistry();
@@ -1105,6 +1077,8 @@
PassRefPtr<FontLoader> fontloader();
+ void addLifecycleObserver(DocumentLifecycleObserver*);
+
protected:
Document(Frame*, const KURL&, DocumentClassFlags = DefaultDocumentClass);
@@ -1169,11 +1143,6 @@
PassRefPtr<HTMLCollection> ensureCachedCollection(CollectionType);
- void clearFullscreenElementStack();
- void popFullscreenElementStack();
- void pushFullscreenElementStack(Element*);
- void addDocumentToFullScreenChangeEventQueue(Document*);
-
// Note that dispatching a window load event may cause the DOMWindow to be detached from
// the Frame, so callers should take a reference to the DOMWindow (which owns us) to
// prevent the Document from getting blown away from underneath them.
@@ -1295,7 +1264,7 @@
bool m_titleSetExplicitly;
RefPtr<Element> m_titleElement;
- OwnPtr<RenderArena> m_renderArena;
+ RefPtr<RenderArena> m_renderArena;
OwnPtr<AXObjectCache> m_axObjectCache;
OwnPtr<DocumentMarkerController> m_markers;
@@ -1317,6 +1286,8 @@
OwnPtr<ScriptRunner> m_scriptRunner;
+ Vector<RefPtr<HTMLScriptElement> > m_currentScriptStack;
+
OwnPtr<TransformSource> m_transformSource;
RefPtr<Document> m_transformSourceDocument;
@@ -1344,7 +1315,6 @@
HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
- bool m_createRenderers;
Vector<IconURL> m_iconURLs;
HashMap<StringImpl*, Element*, CaseFoldingHash> m_elementsByAccessKey;
@@ -1367,16 +1337,7 @@
QualifiedName m_idAttributeName;
- bool m_areKeysEnabledInFullScreen;
- RefPtr<Element> m_fullScreenElement;
- Vector<RefPtr<Element> > m_fullScreenElementStack;
- RenderFullScreen* m_fullScreenRenderer;
- Timer<Document> m_fullScreenChangeDelayTimer;
- Deque<RefPtr<Node> > m_fullScreenChangeEventTargetQueue;
- Deque<RefPtr<Node> > m_fullScreenErrorEventTargetQueue;
- bool m_isAnimatingFullScreen;
- LayoutRect m_savedPlaceholderFrameRect;
- RefPtr<RenderStyle> m_savedPlaceholderRenderStyle;
+ bool m_hasFullscreenController; // For early return in FullscreenController::fromIfExists()
Vector<RefPtr<Element> > m_topLayerElements;
@@ -1440,6 +1401,7 @@
Timer<Document> m_didAssociateFormControlsTimer;
HashSet<RefPtr<Element> > m_associatedFormControls;
+ OwnPtr<DocumentLifecycleNotifier> m_lifecycleNotifier;
};
inline void Document::notifyRemovePendingSheetIfNeeded()
diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl
index abee356..6d7fb1b 100644
--- a/Source/core/dom/Document.idl
+++ b/Source/core/dom/Document.idl
@@ -18,6 +18,8 @@
* Boston, MA 02110-1301, USA.
*/
+callback CustomElementConstructor = Element ();
+
[
CustomToV8
] interface Document : Node {
@@ -65,24 +67,26 @@
[RaisesException] Event createEvent([Default=Undefined] optional DOMString eventType);
- // DOM Level 2 Tranversal and Range (DocumentRange interface)
+ // DOM Level 2 Traversal and Range (DocumentRange interface)
Range createRange();
- // DOM Level 2 Tranversal and Range (DocumentTraversal interface)
-
- [RaisesException] NodeIterator createNodeIterator([Default=Undefined] optional Node root,
- [Default=Undefined] optional unsigned long whatToShow,
- [Default=Undefined] optional NodeFilter filter,
- [Default=Undefined] optional boolean expandEntityReferences);
- [RaisesException] TreeWalker createTreeWalker([Default=Undefined] optional Node root,
- [Default=Undefined] optional unsigned long whatToShow,
- [Default=Undefined] optional NodeFilter filter,
- [Default=Undefined] optional boolean expandEntityReferences);
+ // DOM Level 2 Traversal and Range (DocumentTraversal interface)
+ // In DOM4, the fourth argument |expandEntityReferences| is removed.
+ // Historically, this argument was never implemented and has been ignored.
+ // We still receive the argument to keep compatibility, but don't do anything if it's specified.
+ [RaisesException] NodeIterator createNodeIterator(Node root,
+ optional unsigned long whatToShow,
+ optional NodeFilter filter,
+ optional boolean expandEntityReferences);
+ [RaisesException] TreeWalker createTreeWalker(Node root,
+ optional unsigned long whatToShow,
+ optional NodeFilter filter,
+ optional boolean expandEntityReferences);
// DOM Level 2 Abstract Views (DocumentView interface)
- readonly attribute DOMWindow defaultView;
+ readonly attribute Window defaultView;
// DOM Level 2 Style (DocumentStyle interface)
@@ -169,21 +173,10 @@
[RaisesException] Element querySelector(DOMString selectors);
[RaisesException] NodeList querySelectorAll(DOMString selectors);
- // Mozilla version
- [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitIsFullScreen;
- [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
- [EnabledAtRuntime=fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
- [EnabledAtRuntime=fullscreen] void webkitCancelFullScreen();
-
- // W3C version
- [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullscreenEnabled;
- [EnabledAtRuntime=fullscreen] readonly attribute Element webkitFullscreenElement;
- [EnabledAtRuntime=fullscreen] void webkitExitFullscreen();
-
void webkitExitPointerLock();
readonly attribute Element webkitPointerLockElement;
- [EnabledAtRuntime=cssRegions] DOMNamedFlowCollection webkitGetNamedFlows();
+ [EnabledAtRuntime=cssRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
[EnabledAtRuntime=fontLoadEvents] readonly attribute FontLoader fontloader;
@@ -263,7 +256,7 @@
[NotEnumerable] attribute EventListener onwebkitpointerlockerror;
[NotEnumerable, EnabledAtRuntime=experimentalContentSecurityPolicyFeatures] attribute EventListener onsecuritypolicyviolation;
- [EnabledAtRuntime=touch] Touch createTouch([Default=Undefined] optional DOMWindow window,
+ [EnabledAtRuntime=touch] Touch createTouch([Default=Undefined] optional Window window,
[Default=Undefined] optional EventTarget target,
[Default=Undefined] optional long identifier,
[Default=Undefined] optional long pageX,
@@ -276,7 +269,8 @@
[Default=Undefined] optional float webkitForce);
[EnabledAtRuntime=touch, Custom, RaisesException] TouchList createTouchList();
- [EnabledAtRuntime=customDOMElements, ImplementedAs=registerElement, CallWith=ScriptState, DeliverCustomElementCallbacks, RaisesException] CustomElementConstructor webkitRegister(DOMString name, optional Dictionary options);
+ [DeprecateAs=PrefixedDocumentRegister, EnabledAtRuntime=customDOMElements, ImplementedAs=registerElement, CallWith=ScriptState, DeliverCustomElementCallbacks, RaisesException] CustomElementConstructor webkitRegister(DOMString name, optional Dictionary options);
+ [EnabledAtRuntime=customDOMElements, ImplementedAs=registerElement, CallWith=ScriptState, DeliverCustomElementCallbacks, RaisesException] CustomElementConstructor register(DOMString name, optional Dictionary options);
[DeliverCustomElementCallbacks, PerWorldBindings, ActivityLog=AccessForIsolatedWorlds, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
[DeliverCustomElementCallbacks, PerWorldBindings, ActivityLog=AccessForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
[TreatNullAs=NullString] DOMString typeExtension);
@@ -288,10 +282,6 @@
// Security Policy API: http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-interfaces
[EnabledAtRuntime=experimentalContentSecurityPolicyFeatures] readonly attribute SecurityPolicy securityPolicy;
- // ParentNode interface API
- readonly attribute HTMLCollection children;
- readonly attribute Element firstElementChild;
- readonly attribute Element lastElementChild;
- readonly attribute unsigned long childElementCount;
+ readonly attribute HTMLScriptElement currentScript;
};
diff --git a/Source/core/dom/DocumentFragment.idl b/Source/core/dom/DocumentFragment.idl
index f02cf18..6cd787a 100644
--- a/Source/core/dom/DocumentFragment.idl
+++ b/Source/core/dom/DocumentFragment.idl
@@ -19,16 +19,10 @@
[
Constructor,
- CallWith=ScriptExecutionContext
+ ConstructorCallWith=ScriptExecutionContext
] interface DocumentFragment : Node {
// NodeSelector - Selector API
[RaisesException] Element querySelector(DOMString selectors);
[RaisesException] NodeList querySelectorAll(DOMString selectors);
-
- // ParentNode interface API
- readonly attribute HTMLCollection children;
- readonly attribute Element firstElementChild;
- readonly attribute Element lastElementChild;
- readonly attribute unsigned long childElementCount;
};
diff --git a/Source/core/dom/DocumentFullscreen.cpp b/Source/core/dom/DocumentFullscreen.cpp
new file mode 100644
index 0000000..472682c
--- /dev/null
+++ b/Source/core/dom/DocumentFullscreen.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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/DocumentFullscreen.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/FullscreenController.h"
+
+namespace WebCore {
+
+bool DocumentFullscreen::webkitIsFullScreen(Document* document)
+{
+ if (FullscreenController* controller = FullscreenController::fromIfExists(document))
+ return controller->webkitIsFullScreen();
+ return false;
+}
+
+bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document* document)
+{
+ if (FullscreenController* controller = FullscreenController::fromIfExists(document))
+ return controller->webkitFullScreenKeyboardInputAllowed();
+ return false;
+}
+
+Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document* document)
+{
+ if (FullscreenController* controller = FullscreenController::fromIfExists(document))
+ return controller->webkitCurrentFullScreenElement();
+ return 0;
+}
+
+void DocumentFullscreen::webkitCancelFullScreen(Document* document)
+{
+ FullscreenController::from(document)->webkitCancelFullScreen();
+}
+
+bool DocumentFullscreen::webkitFullscreenEnabled(Document* document)
+{
+ return FullscreenController::webkitFullscreenEnabled(document);
+}
+
+Element* DocumentFullscreen::webkitFullscreenElement(Document* document)
+{
+ if (FullscreenController* controller = FullscreenController::fromIfExists(document))
+ return controller->webkitFullscreenElement();
+ return 0;
+}
+
+void DocumentFullscreen::webkitExitFullscreen(Document* document)
+{
+ FullscreenController::from(document)->webkitExitFullscreen();
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/DocumentFullscreen.h b/Source/core/dom/DocumentFullscreen.h
new file mode 100644
index 0000000..ff5338d
--- /dev/null
+++ b/Source/core/dom/DocumentFullscreen.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 DocumentFullscreen_h
+#define DocumentFullscreen_h
+
+namespace WebCore {
+
+class Document;
+class Element;
+
+class DocumentFullscreen {
+public:
+ static bool webkitIsFullScreen(Document*);
+ static bool webkitFullScreenKeyboardInputAllowed(Document*);
+ static Element* webkitCurrentFullScreenElement(Document*);
+ static void webkitCancelFullScreen(Document*);
+
+ static bool webkitFullscreenEnabled(Document*);
+ static Element* webkitFullscreenElement(Document*);
+ static void webkitExitFullscreen(Document*);
+};
+
+} // namespace WebCore
+
+#endif // DocumentFullscreen_h
diff --git a/Source/core/dom/DocumentFullscreen.idl b/Source/core/dom/DocumentFullscreen.idl
new file mode 100644
index 0000000..854492e
--- /dev/null
+++ b/Source/core/dom/DocumentFullscreen.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006, 2007, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+partial interface Document {
+ // Mozilla version
+ [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitIsFullScreen;
+ [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
+ [EnabledAtRuntime=fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
+ [EnabledAtRuntime=fullscreen] void webkitCancelFullScreen();
+
+ // W3C version
+ [EnabledAtRuntime=fullscreen] readonly attribute boolean webkitFullscreenEnabled;
+ [EnabledAtRuntime=fullscreen] readonly attribute Element webkitFullscreenElement;
+ [EnabledAtRuntime=fullscreen] void webkitExitFullscreen();
+};
diff --git a/Source/core/dom/DocumentLifecycleObserver.cpp b/Source/core/dom/DocumentLifecycleObserver.cpp
new file mode 100644
index 0000000..2a231ac
--- /dev/null
+++ b/Source/core/dom/DocumentLifecycleObserver.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
+ */
+
+
+#include "config.h"
+#include "core/dom/DocumentLifecycleObserver.h"
+
+#include "core/dom/Document.h"
+
+namespace WebCore {
+
+DocumentLifecycleObserver::DocumentLifecycleObserver(Document* document)
+ : ContextDestructionObserver(document)
+{
+ document->addLifecycleObserver(this);
+}
+
+PassOwnPtr<DocumentLifecycleNotifier> DocumentLifecycleNotifier::create()
+{
+ return adoptPtr(new DocumentLifecycleNotifier());
+}
+
+void DocumentLifecycleNotifier::addObserver(DocumentLifecycleObserver* observer)
+{
+ ASSERT(!m_iterating);
+ ASSERT(!m_observers.contains(observer));
+ m_observers.append(observer);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/DocumentLifecycleObserver.h b/Source/core/dom/DocumentLifecycleObserver.h
new file mode 100644
index 0000000..d6d0263
--- /dev/null
+++ b/Source/core/dom/DocumentLifecycleObserver.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2013 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 DocumentLifecycleObserver_h
+#define DocumentLifecycleObserver_h
+
+#include "core/dom/ContextDestructionObserver.h"
+#include "wtf/Assertions.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Document;
+
+class DocumentLifecycleObserver : public ContextDestructionObserver {
+public:
+ explicit DocumentLifecycleObserver(Document*);
+ virtual ~DocumentLifecycleObserver() { }
+ virtual void documentWasDetached() { }
+ virtual void documentWasDisposed() { }
+};
+
+class DocumentLifecycleNotifier {
+public:
+ static PassOwnPtr<DocumentLifecycleNotifier> create();
+
+ void notifyDocumentWasDetached();
+ void notifyDocumentWasDisposed();
+
+ void addObserver(DocumentLifecycleObserver*);
+
+private:
+#if ASSERT_DISABLED
+ DocumentLifecycleNotifier() { }
+ void startIteration() { }
+ void endIteration() { }
+#else
+ DocumentLifecycleNotifier() : m_iterating(false) { }
+ void startIteration() { m_iterating = true; }
+ void endIteration() { m_iterating = false; }
+ bool m_iterating;
+#endif
+
+ Vector<DocumentLifecycleObserver*> m_observers; // Use Vector instead of HashSet for faster iteration
+};
+
+inline void DocumentLifecycleNotifier::notifyDocumentWasDetached()
+{
+ startIteration();
+ for (size_t i = 0; i < m_observers.size(); ++i)
+ m_observers[i]->documentWasDetached();
+ endIteration();
+}
+
+inline void DocumentLifecycleNotifier::notifyDocumentWasDisposed()
+{
+ startIteration();
+ for (size_t i = 0; i < m_observers.size(); ++i)
+ m_observers[i]->documentWasDisposed();
+ endIteration();
+}
+
+} // namespace WebCore
+
+#endif // DocumentLifecycleObserver_h
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 16e663c..bf2c5fc 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -41,6 +41,7 @@
#include "core/dom/DocumentSharedObjectPool.h"
#include "core/dom/ElementRareData.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/FullscreenController.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/NamedNodeMap.h"
@@ -238,6 +239,38 @@
return hasRareData() ? elementRareData()->tabIndex() : 0;
}
+bool Element::rendererIsFocusable() const
+{
+ // Elements in canvas fallback content are not rendered, but they are allowed to be
+ // focusable as long as their canvas is displayed and visible.
+ if (isInCanvasSubtree()) {
+ const Element* e = this;
+ while (e && !e->hasLocalName(canvasTag))
+ e = e->parentElement();
+ ASSERT(e);
+ return e->renderer() && e->renderer()->style()->visibility() == VISIBLE;
+ }
+
+ // FIXME: These asserts should be in Node::isFocusable, but there are some
+ // callsites like Document::setFocusedNode that would currently fail on
+ // them. See crbug.com/251163
+ if (renderer()) {
+ ASSERT(!renderer()->needsLayout());
+ } else {
+ // We can't just use needsStyleRecalc() because if the node is in a
+ // display:none tree it might say it needs style recalc but the whole
+ // document is actually up to date.
+ ASSERT(!document()->childNeedsStyleRecalc());
+ }
+
+ // FIXME: Even if we are not visible, we might have a child that is visible.
+ // Hyatt wants to fix that some day with a "has visible content" flag or the like.
+ if (!renderer() || renderer()->style()->visibility() != VISIBLE)
+ return false;
+
+ return true;
+}
+
DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
@@ -550,7 +583,7 @@
Element* element = offsetParent();
if (!element || !element->isInShadowTree())
return element;
- return element->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? 0 : element;
+ return element->containingShadowRoot()->shouldExposeToBindings() ? element : 0;
}
Element* Element::offsetParent()
@@ -1258,18 +1291,18 @@
document()->accessSVGExtensions()->removeElementFromPendingResources(this);
}
-void Element::createRendererIfNeeded()
+void Element::createRendererIfNeeded(const AttachContext& context)
{
- NodeRenderingContext(this).createRendererForElementIfNeeded();
+ NodeRenderingContext(this, context).createRendererForElementIfNeeded();
}
-void Element::attach()
+void Element::attach(const AttachContext& context)
{
PostAttachCallbackDisabler callbackDisabler(this);
StyleResolverParentPusher parentPusher(this);
WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
- createRendererIfNeeded();
+ createRendererIfNeeded(context);
if (parentElement() && parentElement()->isInCanvasSubtree())
setIsInCanvasSubtree(true);
@@ -1283,7 +1316,7 @@
} else if (firstChild())
parentPusher.push();
- ContainerNode::attach();
+ ContainerNode::attach(context);
createPseudoElementIfNeeded(AFTER);
@@ -1303,7 +1336,7 @@
document()->renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
}
-void Element::detach()
+void Element::detach(const AttachContext& context)
{
WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
unregisterNamedFlowContentNode();
@@ -1321,7 +1354,7 @@
detachChildrenIfNeeded();
shadow->detach();
}
- ContainerNode::detach();
+ ContainerNode::detach(context);
}
bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
@@ -1362,22 +1395,22 @@
return false;
}
-PassRefPtr<RenderStyle> Element::styleForRenderer(int childIndex)
+PassRefPtr<RenderStyle> Element::styleForRenderer()
{
if (hasCustomStyleCallbacks()) {
if (RefPtr<RenderStyle> style = customStyleForRenderer())
return style.release();
}
- return originalStyleForRenderer(childIndex);
+ return originalStyleForRenderer();
}
-PassRefPtr<RenderStyle> Element::originalStyleForRenderer(int childIndex)
+PassRefPtr<RenderStyle> Element::originalStyleForRenderer()
{
- return document()->styleResolver()->styleForElement(this, childIndex);
+ return document()->styleResolver()->styleForElement(this);
}
-void Element::recalcStyle(StyleChange change, int childIndex)
+void Element::recalcStyle(StyleChange change)
{
ASSERT(document()->inStyleRecalc());
@@ -1401,12 +1434,18 @@
// FIXME: This still recalcs style twice when changing display types, but saves
// us from recalcing twice when going from none -> anything else which is more
// common, especially during lazy attach.
- newStyle = styleForRenderer(childIndex);
+ 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) {
- // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
- reattach();
+ AttachContext reattachContext;
+ reattachContext.resolvedStyle = newStyle.get();
+ reattach(reattachContext);
+
// attach recalculates the style for all children. No need to do it twice.
clearNeedsStyleRecalc();
clearChildNeedsStyleRecalc();
@@ -1457,9 +1496,7 @@
// without doing way too much re-resolution.
bool forceCheckOfNextElementSibling = false;
bool forceCheckOfAnyElementSibling = false;
- int indexForChild = 0;
for (Node *n = firstChild(); n; n = n->nextSibling()) {
- ++indexForChild;
if (n->isTextNode()) {
toText(n)->recalcTextStyle(change);
continue;
@@ -1470,20 +1507,12 @@
bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
element->setNeedsStyleRecalc();
- forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
- forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
- }
- // FIXME: Reversing the loop we call recalcStyle avoids an N^2 walk through the DOM to find the next renderer
- // to insert before. The logic in NodeRenderingContext should be improved to make this unnecessary.
- for (Node *n = lastChild(); n; n = n->previousSibling()) {
- if (!n->isElementNode())
- continue;
- Element* element = toElement(n);
if (shouldRecalcStyle(change, element)) {
parentPusher.push();
- element->recalcStyle(change, indexForChild);
+ element->recalcStyle(change);
}
- --indexForChild;
+ forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
+ forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
}
if (shouldRecalcStyle(change, this))
@@ -2292,7 +2321,7 @@
// when RenderObject::isChildAllowed on our parent returns false for the
// PseudoElement's renderer for each style recalc.
if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
- setPseudoElement(pseudoId, 0);
+ elementRareData()->setPseudoElement(pseudoId, 0);
} else if (change >= Inherit || needsStyleRecalc())
createPseudoElementIfNeeded(pseudoId);
}
@@ -2311,12 +2340,7 @@
ASSERT(!isPseudoElement());
RefPtr<PseudoElement> element = PseudoElement::create(this, pseudoId);
element->attach();
- setPseudoElement(pseudoId, element.release());
-}
-
-bool Element::hasPseudoElements() const
-{
- return hasRareData() && elementRareData()->hasPseudoElements();
+ ensureElementRareData()->setPseudoElement(pseudoId, element.release());
}
PseudoElement* Element::pseudoElement(PseudoId pseudoId) const
@@ -2324,12 +2348,6 @@
return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
}
-void Element::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
-{
- ensureElementRareData()->setPseudoElement(pseudoId, element);
- resetNeedsShadowTreeWalker();
-}
-
RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
{
if (PseudoElement* element = pseudoElement(pseudoId))
@@ -2439,12 +2457,12 @@
void Element::webkitRequestFullscreen()
{
- document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenController::from(document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenController::EnforceIFrameAllowFullScreenRequirement);
}
void Element::webkitRequestFullScreen(unsigned short flags)
{
- document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenController::from(document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenController::EnforceIFrameAllowFullScreenRequirement);
}
bool Element::containsFullScreenElement() const
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 669782c..fed0c42 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -406,17 +406,18 @@
virtual void copyNonAttributePropertiesFromElement(const Element&) { }
- virtual void attach();
- virtual void detach();
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual bool rendererIsNeeded(const NodeRenderingContext&);
- void recalcStyle(StyleChange = NoChange, int childIndex = 0);
+ void recalcStyle(StyleChange = NoChange);
void didAffectSelector(AffectedSelectorMask);
ElementShadow* shadow() const;
ElementShadow* ensureShadow();
PassRefPtr<ShadowRoot> createShadowRoot(ExceptionCode&);
ShadowRoot* shadowRoot() const;
+ void ensureDistribution();
bool hasAuthorShadowRoot() const { return shadowRoot(); }
@@ -494,11 +495,8 @@
virtual void finishParsingChildren();
virtual void beginParsingChildren() OVERRIDE FINAL;
- bool hasPseudoElements() const;
PseudoElement* pseudoElement(PseudoId) const;
RenderObject* pseudoElementRenderer(PseudoId) const;
- bool childNeedsShadowWalker() const;
- void didShadowTreeAwareChildrenChange();
virtual bool matchesReadOnlyPseudoClass() const;
virtual bool matchesReadWritePseudoClass() const;
@@ -576,8 +574,8 @@
bool isSpellCheckingEnabled() const;
- PassRefPtr<RenderStyle> styleForRenderer(int childIndex = 0);
- PassRefPtr<RenderStyle> originalStyleForRenderer(int childIndex = 0);
+ PassRefPtr<RenderStyle> styleForRenderer();
+ PassRefPtr<RenderStyle> originalStyleForRenderer();
RenderRegion* renderRegion() const;
const AtomicString& webkitRegionOverset() const;
@@ -623,6 +621,7 @@
void setTabIndexExplicitly(short);
virtual bool supportsFocus() const OVERRIDE;
virtual short tabIndex() const OVERRIDE;
+ virtual bool rendererIsFocusable() const OVERRIDE;
PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
HTMLCollection* cachedHTMLCollection(CollectionType);
@@ -635,7 +634,6 @@
private:
void updatePseudoElement(PseudoId, StyleChange);
void createPseudoElementIfNeeded(PseudoId);
- void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
virtual bool areAuthorShadowsAllowed() const { return true; }
virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
@@ -715,7 +713,7 @@
void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
void detachAttrNodeAtIndex(Attr*, size_t index);
- void createRendererIfNeeded();
+ void createRendererIfNeeded(const AttachContext&);
bool isJavaScriptURLAttribute(const Attribute&) const;
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index bec455c..55f592f 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -100,12 +100,6 @@
// WebKit extension, pending specification.
[RaisesException] boolean webkitMatchesSelector([Default=Undefined] optional DOMString selectors);
- // ParentNode interface API
- [PerWorldBindings] readonly attribute HTMLCollection children;
- [PerWorldBindings] readonly attribute Element firstElementChild;
- [PerWorldBindings] readonly attribute Element lastElementChild;
- [PerWorldBindings] readonly attribute unsigned long childElementCount;
-
// ShadowAware API
[Reflect=pseudo, ImplementedAs=pseudo, PerWorldBindings] attribute DOMString webkitPseudo;
[ImplementedAs=createShadowRoot, RaisesException] ShadowRoot webkitCreateShadowRoot();
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index 649515f..89bee36 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -46,7 +46,6 @@
void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
PseudoElement* pseudoElement(PseudoId) const;
- bool hasPseudoElements() const { return m_generatedBefore || m_generatedAfter; }
void resetComputedStyle();
void resetDynamicRestyleObservations();
diff --git a/Source/core/dom/EventDispatcher.cpp b/Source/core/dom/EventDispatcher.cpp
index 51e7cc1..c84ede2 100644
--- a/Source/core/dom/EventDispatcher.cpp
+++ b/Source/core/dom/EventDispatcher.cpp
@@ -62,7 +62,7 @@
ASSERT(m_event.get());
ASSERT(!m_event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
m_view = node->document()->view();
- EventRetargeter::calculateEventPath(m_node.get(), m_event.get());
+ EventRetargeter::ensureEventPath(m_node.get(), m_event.get());
}
void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
diff --git a/Source/core/dom/EventException.cpp b/Source/core/dom/EventException.cpp
deleted file mode 100644
index 6e9241b..0000000
--- a/Source/core/dom/EventException.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 GOOGLE AND ITS 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 APPLE OR ITS 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/EventException.h"
-
-namespace WebCore {
-
-static struct EventExceptionNameDescription {
- const char* const name;
- const char* const description;
-} eventExceptions[] = {
- { "UNSPECIFIED_EVENT_TYPE_ERR", "The Event's type was not specified by initializing the event before the method was called." },
- { "DISPATCH_REQUEST_ERR", "The Event object is already being dispatched." }
-};
-
-bool EventException::initializeDescription(ExceptionCode ec, ExceptionCodeDescription* description)
-{
- if (ec < EventExceptionOffset || ec > EventExceptionMax)
- return false;
-
- description->typeName = "DOM Events";
- description->code = ec - EventExceptionOffset;
- description->type = EventExceptionType;
-
- size_t tableSize = WTF_ARRAY_LENGTH(eventExceptions);
- size_t tableIndex = ec - UNSPECIFIED_EVENT_TYPE_ERR;
-
- description->name = tableIndex < tableSize ? eventExceptions[tableIndex].name : 0;
- description->description = tableIndex < tableSize ? eventExceptions[tableIndex].description : 0;
-
- return true;
-}
-
-} // namespace WebCore
diff --git a/Source/core/dom/EventException.h b/Source/core/dom/EventException.h
deleted file mode 100644
index cc7c917..0000000
--- a/Source/core/dom/EventException.h
+++ /dev/null
@@ -1,64 +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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 EventException_h
-#define EventException_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/ExceptionBase.h"
-
-namespace WebCore {
-
-class EventException : public ExceptionBase, public ScriptWrappable {
-public:
- static PassRefPtr<EventException> create(const ExceptionCodeDescription& description)
- {
- return adoptRef(new EventException(description));
- }
-
- static const int EventExceptionOffset = 100;
- static const int EventExceptionMax = 199;
-
- enum EventExceptionCode {
- UNSPECIFIED_EVENT_TYPE_ERR = EventExceptionOffset,
- DISPATCH_REQUEST_ERR
- };
-
- static bool initializeDescription(ExceptionCode, ExceptionCodeDescription*);
-
-private:
- explicit EventException(const ExceptionCodeDescription& description)
- : ExceptionBase(description)
- {
- ScriptWrappable::init(this);
- }
-};
-
-} // namespace WebCore
-
-#endif // EventException_h
diff --git a/Source/core/dom/EventException.idl b/Source/core/dom/EventException.idl
deleted file mode 100644
index 7d05830..0000000
--- a/Source/core/dom/EventException.idl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.
- */
-
-// Introduced in DOM Level 2:
-[
- DoNotCheckConstants
-] exception EventException {
-
- readonly attribute unsigned short code;
- readonly attribute DOMString name;
- readonly attribute DOMString message;
-
- // Override in a Mozilla compatible format
- [NotEnumerable] DOMString toString();
-
- // EventExceptionCode
- const unsigned short UNSPECIFIED_EVENT_TYPE_ERR = 0;
- const unsigned short DISPATCH_REQUEST_ERR = 1;
-};
-
diff --git a/Source/core/dom/EventListener.h b/Source/core/dom/EventListener.h
index 1708a73..a1add8c 100644
--- a/Source/core/dom/EventListener.h
+++ b/Source/core/dom/EventListener.h
@@ -25,8 +25,9 @@
namespace WebCore {
- class ScriptExecutionContext;
+ class DOMWrapperWorld;
class Event;
+ class ScriptExecutionContext;
class EventListener : public RefCounted<EventListener> {
public:
@@ -45,6 +46,7 @@
virtual bool operator==(const EventListener&) = 0;
virtual void handleEvent(ScriptExecutionContext*, Event*) = 0;
virtual bool wasCreatedFromMarkup() const { return false; }
+ virtual DOMWrapperWorld* world() const { return 0; }
bool isAttribute() const { return virtualisAttribute(); }
Type type() const { return m_type; }
diff --git a/Source/core/dom/EventNames.h b/Source/core/dom/EventNames.h
index a436fee..9438b10 100644
--- a/Source/core/dom/EventNames.h
+++ b/Source/core/dom/EventNames.h
@@ -164,6 +164,14 @@
macro(enter) \
macro(exit) \
\
+ macro(addsourcebuffer) \
+ macro(removesourcebuffer) \
+ macro(sourceopen) \
+ macro(sourceended) \
+ macro(sourceclose) \
+ macro(update) \
+ macro(updateend) \
+ macro(updatestart) \
macro(webkitaddsourcebuffer) \
macro(webkitremovesourcebuffer) \
macro(webkitsourceopen) \
diff --git a/Source/core/dom/EventNames.in b/Source/core/dom/EventNames.in
index 3d08e2d..25a9ac3 100644
--- a/Source/core/dom/EventNames.in
+++ b/Source/core/dom/EventNames.in
@@ -1,62 +1,64 @@
namespace="Event"
-Event
-Events interfaceName=Event
-HTMLEvents interfaceName=Event
+core/css/CSSFontFaceLoadEvent
+core/dom/AutocompleteErrorEvent
core/dom/BeforeLoadEvent
-modules/websockets/CloseEvent
-CompositionEvent
-CustomEvent
-ErrorEvent
-FocusEvent
-HashChangeEvent
-KeyboardEvent
-KeyboardEvents interfaceName=KeyboardEvent
-MessageEvent
-MouseEvent
-MouseEvents interfaceName=MouseEvent
-MutationEvent
-MutationEvents interfaceName=MutationEvent
-OverflowEvent
-PageTransitionEvent
-PopStateEvent
-ProgressEvent
-ResourceProgressEvent
-TextEvent
-TransitionEvent
-UIEvent
-UIEvents interfaceName=UIEvent
-WebKitAnimationEvent interfaceName=AnimationEvent
-WebKitTransitionEvent interfaceName=TransitionEvent
-WheelEvent
+core/dom/CompositionEvent
+core/dom/CustomEvent
+core/dom/DeviceOrientationEvent
+core/dom/ErrorEvent
+core/dom/Event
+core/dom/FocusEvent
+core/dom/HashChangeEvent
+core/dom/KeyboardEvent
+core/dom/MessageEvent
+core/dom/MouseEvent
+core/dom/MutationEvent
+core/dom/OverflowEvent
+core/dom/PageTransitionEvent
+core/dom/PopStateEvent
+core/dom/ProgressEvent
+core/dom/ResourceProgressEvent
+core/dom/SecurityPolicyViolationEvent
+core/dom/TextEvent
+core/dom/TouchEvent runtimeConditional=touchEnabled
+core/dom/TransitionEvent
+core/dom/UIEvent
+core/dom/WebKitAnimationEvent implementedAs=AnimationEvent
+core/dom/WebKitTransitionEvent implementedAs=TransitionEvent
+core/dom/WheelEvent
+core/html/MediaKeyEvent
+core/html/canvas/WebGLContextEvent
+core/html/track/TrackEvent
+core/page/SpeechInputEvent conditional=INPUT_SPEECH
+core/storage/StorageEvent
+core/svg/SVGEvents implementedAs=Event
+core/svg/SVGZoomEvent
core/xml/XMLHttpRequestProgressEvent
-modules/webaudio/AudioProcessingEvent conditional=WEB_AUDIO
-modules/webaudio/OfflineAudioCompletionEvent conditional=WEB_AUDIO
+modules/device_orientation/DeviceMotionEvent
+modules/encryptedmedia/MediaKeyMessageEvent conditional=ENCRYPTED_MEDIA_V2
+modules/encryptedmedia/MediaKeyNeededEvent conditional=ENCRYPTED_MEDIA_V2
+modules/indexeddb/IDBVersionChangeEvent
modules/mediastream/MediaStreamEvent
modules/mediastream/MediaStreamTrackEvent
-modules/mediastream/RTCIceCandidateEvent
-modules/mediastream/RTCDataChannelEvent
modules/mediastream/RTCDTMFToneChangeEvent
-core/page/SpeechInputEvent conditional=INPUT_SPEECH
+modules/mediastream/RTCDataChannelEvent
+modules/mediastream/RTCIceCandidateEvent
modules/speech/SpeechRecognitionError
modules/speech/SpeechRecognitionEvent
modules/speech/SpeechSynthesisEvent
-core/html/canvas/WebGLContextEvent
-core/storage/StorageEvent
-core/svg/SVGEvents interfaceName=Event
-core/svg/SVGZoomEvent
-core/svg/SVGZoomEvents interfaceName=SVGZoomEvent
-modules/indexeddb/IDBVersionChangeEvent
-TouchEvent runtimeConditional=touchEnabled
-modules/device_orientation/DeviceMotionEvent
-core/dom/DeviceOrientationEvent
-OrientationEvent interfaceName=Event, conditional=ORIENTATION_EVENTS
-core/html/MediaKeyEvent
-modules/encryptedmedia/MediaKeyMessageEvent conditional=ENCRYPTED_MEDIA_V2
-modules/encryptedmedia/MediaKeyNeededEvent conditional=ENCRYPTED_MEDIA_V2
-core/html/track/TrackEvent
-core/dom/AutocompleteErrorEvent
-core/css/CSSFontFaceLoadEvent
-SecurityPolicyViolationEvent
+modules/webaudio/AudioProcessingEvent conditional=WEB_AUDIO
+modules/webaudio/OfflineAudioCompletionEvent conditional=WEB_AUDIO
modules/webmidi/MIDIConnectionEvent
modules/webmidi/MIDIMessageEvent
+modules/websockets/CloseEvent
+
+# Aliases
+Events implementedAs=Event
+HTMLEvents implementedAs=Event
+KeyboardEvents implementedAs=KeyboardEvent
+MouseEvents implementedAs=MouseEvent
+MutationEvents implementedAs=MutationEvent
+OrientationEvent implementedAs=Event, conditional=ORIENTATION_EVENTS
+SVGZoomEvents implementedAs=SVGZoomEvent
+UIEvents implementedAs=UIEvent
diff --git a/Source/core/dom/EventPathWalker.cpp b/Source/core/dom/EventPathWalker.cpp
index b29af07..a3b9760 100644
--- a/Source/core/dom/EventPathWalker.cpp
+++ b/Source/core/dom/EventPathWalker.cpp
@@ -53,7 +53,7 @@
ASSERT(m_node);
ASSERT(m_distributedNode);
if (ElementShadow* shadow = shadowOfParent(m_node)) {
- ContentDistributor::ensureDistribution(shadow->youngestShadowRoot());
+ shadow->host()->ensureDistribution();
if (InsertionPoint* insertionPoint = shadow->distributor().findInsertionPointFor(m_distributedNode)) {
m_node = insertionPoint;
m_isVisitingInsertionPointInReprojection = true;
diff --git a/Source/core/dom/EventRetargeter.cpp b/Source/core/dom/EventRetargeter.cpp
index 502a570..415a3fc 100644
--- a/Source/core/dom/EventRetargeter.cpp
+++ b/Source/core/dom/EventRetargeter.cpp
@@ -25,6 +25,7 @@
#include "core/dom/EventContext.h"
#include "core/dom/EventPathWalker.h"
#include "core/dom/FocusEvent.h"
+#include "core/dom/FullscreenController.h"
#include "core/dom/MouseEvent.h"
#include "core/dom/Touch.h"
#include "core/dom/TouchEvent.h"
@@ -46,7 +47,7 @@
{
// Video-only full screen is a mode where we use the shadow DOM as an implementation
// detail that should not be detectable by the web content.
- if (Element* element = target->toNode()->document()->webkitCurrentFullScreenElement()) {
+ if (Element* element = FullscreenController::currentFullScreenElementFrom(target->toNode()->document())) {
// FIXME: We assume that if the full screen element is a media element that it's
// the video-only full screen. Both here and elsewhere. But that is probably wrong.
if (element->isMediaElement() && shadowRoot && shadowRoot->host() == element)
@@ -72,6 +73,12 @@
return RetargetEvent;
}
+void EventRetargeter::ensureEventPath(Node* node, Event* event)
+{
+ calculateEventPath(node, event);
+ calculateAdjustedEventPathForEachNode(event->eventPath());
+}
+
void EventRetargeter::calculateEventPath(Node* node, Event* event)
{
EventPath& eventPath = event->eventPath();
@@ -94,18 +101,20 @@
else
eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
if (!inDocument)
- return;
+ break;
if (!node->isShadowRoot())
continue;
if (determineDispatchBehavior(event, toShadowRoot(node), targetStack.last()) == StayInsideShadowDOM)
- return;
+ break;
if (!isSVGElement) {
ASSERT(!targetStack.isEmpty());
targetStack.removeLast();
}
}
+}
- // Calculates eventPath for each node for Event.path() API.
+void EventRetargeter::calculateAdjustedEventPathForEachNode(EventPath& eventPath)
+{
if (!RuntimeEnabledFeatures::experimentalShadowDOMEnabled())
return;
TreeScope* lastScope = 0;
diff --git a/Source/core/dom/EventRetargeter.h b/Source/core/dom/EventRetargeter.h
index f602a47..76cfd9e 100644
--- a/Source/core/dom/EventRetargeter.h
+++ b/Source/core/dom/EventRetargeter.h
@@ -46,7 +46,7 @@
class EventRetargeter {
public:
- static void calculateEventPath(Node*, Event*);
+ static void ensureEventPath(Node*, Event*);
static void adjustForMouseEvent(Node*, MouseEvent&);
static void adjustForFocusEvent(Node*, FocusEvent&);
typedef Vector<RefPtr<TouchList> > EventPathTouchLists;
@@ -60,6 +60,9 @@
StopAtBoundaryIfNeeded,
DoesNotStopAtBoundary
};
+ static void calculateEventPath(Node*, Event*);
+ static void calculateAdjustedEventPathForEachNode(EventPath&);
+
static void adjustForRelatedTarget(const Node*, EventTarget* relatedTarget, EventPath&);
static void calculateAdjustedNodes(const Node*, const Node* relatedNode, EventWithRelatedTargetDispatchBehavior, EventPath&, AdjustedNodes&);
static void buildRelatedNodeMap(const Node*, RelatedNodeMap&);
diff --git a/Source/core/dom/EventSender.h b/Source/core/dom/EventSender.h
index c0ee7c5..40d8175 100644
--- a/Source/core/dom/EventSender.h
+++ b/Source/core/dom/EventSender.h
@@ -97,8 +97,6 @@
m_timer.stop();
- m_dispatchSoonList.checkConsistency();
-
m_dispatchingList.swap(m_dispatchSoonList);
size_t size = m_dispatchingList.size();
for (size_t i = 0; i < size; ++i) {
diff --git a/Source/core/dom/EventTarget.cpp b/Source/core/dom/EventTarget.cpp
index 68615b4..c06d6dd 100644
--- a/Source/core/dom/EventTarget.cpp
+++ b/Source/core/dom/EventTarget.cpp
@@ -32,9 +32,10 @@
#include "config.h"
#include "core/dom/EventTarget.h"
+#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "core/dom/Event.h"
-#include "core/dom/EventException.h"
+#include "core/dom/ExceptionCode.h"
#include "core/inspector/InspectorInstrumentation.h"
#include <wtf/MainThread.h>
#include <wtf/StdLibExtras.h>
@@ -103,27 +104,38 @@
return true;
}
-bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
{
- clearAttributeEventListener(eventType);
+ clearAttributeEventListener(eventType, isolatedWorld);
if (!listener)
return false;
return addEventListener(eventType, listener, false);
}
-EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
+EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
{
const EventListenerVector& entry = getEventListeners(eventType);
for (size_t i = 0; i < entry.size(); ++i) {
- if (entry[i].listener->isAttribute())
- return entry[i].listener.get();
+ EventListener* listener = entry[i].listener.get();
+ if (listener->isAttribute()) {
+ DOMWrapperWorld* listenerWorld = listener->world();
+ // Worker listener
+ if (!listenerWorld) {
+ ASSERT(!isolatedWorld);
+ return listener;
+ }
+ if (listenerWorld->isMainWorld() && !isolatedWorld)
+ return listener;
+ if (listenerWorld == isolatedWorld)
+ return listener;
+ }
}
return 0;
}
-bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
+bool EventTarget::clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
{
- EventListener* listener = getAttributeEventListener(eventType);
+ EventListener* listener = getAttributeEventListener(eventType, isolatedWorld);
if (!listener)
return false;
return removeEventListener(eventType, listener, false);
@@ -131,13 +143,8 @@
bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
{
- if (!event || event->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return false;
- }
-
- if (event->isBeingDispatched()) {
- ec = EventException::DISPATCH_REQUEST_ERR;
+ if (!event || event->type().isEmpty() || event->isBeingDispatched()) {
+ ec = INVALID_STATE_ERR;
return false;
}
diff --git a/Source/core/dom/EventTarget.h b/Source/core/dom/EventTarget.h
index 80033f7..58837f0 100644
--- a/Source/core/dom/EventTarget.h
+++ b/Source/core/dom/EventTarget.h
@@ -68,8 +68,6 @@
class SharedWorkerContext;
class TextTrack;
class TextTrackCue;
- class WebKitMediaSource;
- class WebKitSourceBufferList;
class WebSocket;
class Worker;
class XMLHttpRequest;
@@ -120,9 +118,8 @@
virtual void uncaughtExceptionInEventHandler();
// Used for legacy "onEvent" attribute APIs.
- bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
- bool clearAttributeEventListener(const AtomicString& eventType);
- EventListener* getAttributeEventListener(const AtomicString& eventType);
+ bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
+ EventListener* getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld = 0);
bool hasEventListeners();
bool hasEventListeners(const AtomicString& eventType);
@@ -143,34 +140,36 @@
void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
+ bool clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
+
friend class EventListenerIterator;
};
// FIXME: These macros should be split into separate DEFINE and DECLARE
// macros to avoid causing so many header includes.
#define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+ EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(eventNames().attribute##Event, isolatedWorld); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld = 0) { setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
#define DECLARE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(attribute) \
- virtual EventListener* on##attribute(); \
- virtual void setOn##attribute(PassRefPtr<EventListener> listener); \
+ virtual EventListener* on##attribute(DOMWrapperWorld* isolatedWorld); \
+ virtual void setOn##attribute(PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld); \
#define DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(type, attribute) \
- EventListener* type::on##attribute() { return getAttributeEventListener(eventNames().attribute##Event); } \
- void type::setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().attribute##Event, listener); } \
+ EventListener* type::on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(eventNames().attribute##Event, isolatedWorld); } \
+ void type::setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
#define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute() { return document()->getWindowAttributeEventListener(eventNames().attribute##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener); } \
+ EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return document()->getWindowAttributeEventListener(eventNames().attribute##Event, isolatedWorld); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { document()->setWindowAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
#define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
- EventListener* on##attribute() { return getAttributeEventListener(eventNames().eventName##Event); } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(eventNames().eventName##Event, listener); } \
+ EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(eventNames().eventName##Event, isolatedWorld); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(eventNames().eventName##Event, listener, isolatedWorld); } \
#define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
- EventListener* on##attribute() { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event) : 0; } \
- void setOn##attribute(PassRefPtr<EventListener> listener) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener); } \
+ EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return recipient ? recipient->getAttributeEventListener(eventNames().attribute##Event, isolatedWorld) : 0; } \
+ void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { if (recipient) recipient->setAttributeEventListener(eventNames().attribute##Event, listener, isolatedWorld); } \
inline bool EventTarget::isFiringEventListeners()
{
diff --git a/Source/core/dom/EventTargetFactory.in b/Source/core/dom/EventTargetFactory.in
index 7c60c24..5ebf267 100644
--- a/Source/core/dom/EventTargetFactory.in
+++ b/Source/core/dom/EventTargetFactory.in
@@ -3,15 +3,16 @@
core/css/FontLoader
core/dom/MessagePort
core/dom/Node
+core/dom/WebKitNamedFlow implementedAs=NamedFlow
core/fileapi/FileReader
core/html/MediaController
core/html/track/TextTrack
core/html/track/TextTrackCue
core/html/track/TextTrackList
core/loader/appcache/DOMApplicationCache
-core/page/DOMWindow
core/page/EventSource
core/page/Performance
+core/page/Window implementedAs=DOMWindow
core/svg/SVGElementInstance
core/workers/DedicatedWorkerContext
core/workers/SharedWorker
@@ -25,12 +26,15 @@
modules/indexeddb/IDBOpenDBRequest
modules/indexeddb/IDBRequest
modules/indexeddb/IDBTransaction
+modules/mediasource/MediaSource
+modules/mediasource/SourceBuffer
+modules/mediasource/SourceBufferList
modules/mediasource/WebKitMediaSource
modules/mediasource/WebKitSourceBufferList
modules/mediastream/MediaStream
modules/mediastream/MediaStreamTrack
-modules/mediastream/RTCDataChannel
modules/mediastream/RTCDTMFSender
+modules/mediastream/RTCDataChannel
modules/mediastream/RTCPeerConnection
modules/notifications/Notification conditional=NOTIFICATIONS
modules/speech/SpeechRecognition
@@ -41,4 +45,3 @@
modules/webmidi/MIDIInput
modules/webmidi/MIDIPort
modules/websockets/WebSocket
-WebKitNamedFlow interfaceName=NamedFlow
diff --git a/Source/core/dom/ExceptionBase.cpp b/Source/core/dom/ExceptionBase.cpp
index fcfd7ef..9276fd7 100644
--- a/Source/core/dom/ExceptionBase.cpp
+++ b/Source/core/dom/ExceptionBase.cpp
@@ -36,18 +36,17 @@
ExceptionBase::ExceptionBase(const ExceptionCodeDescription& description)
: m_code(description.code)
- , m_name(description.name)
, m_description(description.description)
{
if (description.name)
- m_message = m_name + ": " + description.typeName + " Exception " + String::number(description.code);
+ m_name = description.name;
else
- m_message = String(description.typeName) + " Exception " + String::number(description.code);
+ m_name = description.typeName;
}
String ExceptionBase::toString() const
{
- return "Error: " + m_message;
+ return m_name + ": " + message();
}
} // namespace WebCore
diff --git a/Source/core/dom/ExceptionBase.h b/Source/core/dom/ExceptionBase.h
index d8850ae..d500f1e 100644
--- a/Source/core/dom/ExceptionBase.h
+++ b/Source/core/dom/ExceptionBase.h
@@ -41,7 +41,7 @@
public:
unsigned short code() const { return m_code; }
String name() const { return m_name; }
- String message() const { return m_message; }
+ String message() const { return description(); }
String description() const { return m_description; }
String toString() const;
@@ -52,7 +52,6 @@
private:
unsigned short m_code;
String m_name;
- String m_message;
String m_description;
};
diff --git a/Source/core/dom/FullscreenController.cpp b/Source/core/dom/FullscreenController.cpp
new file mode 100644
index 0000000..b01d12b
--- /dev/null
+++ b/Source/core/dom/FullscreenController.cpp
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/FullscreenController.h"
+
+#include "HTMLNames.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/Event.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Frame.h"
+#include "core/page/Page.h"
+#include "core/page/Settings.h"
+#include "core/rendering/RenderFullScreen.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner)
+{
+ if (!owner)
+ return true;
+ do {
+ if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
+ return false;
+ } while ((owner = owner->document()->ownerElement()));
+ return true;
+}
+
+const char* FullscreenController::supplementName()
+{
+ return "FullscreenController";
+}
+
+FullscreenController* FullscreenController::from(Document* document)
+{
+ FullscreenController* controller = fromIfExists(document);
+ if (!controller) {
+ controller = new FullscreenController(document);
+ Supplement<ScriptExecutionContext>::provideTo(document, supplementName(), adoptPtr(controller));
+ }
+
+ return controller;
+}
+
+FullscreenController* FullscreenController::fromIfExistsSlow(Document* document)
+{
+ return static_cast<FullscreenController*>(Supplement<ScriptExecutionContext>::from(document, supplementName()));
+}
+
+Element* FullscreenController::fullscreenElementFrom(Document* document)
+{
+ if (FullscreenController* found = fromIfExists(document))
+ return found->webkitFullscreenElement();
+ return 0;
+}
+
+Element* FullscreenController::currentFullScreenElementFrom(Document* document)
+{
+ if (FullscreenController* found = fromIfExists(document))
+ return found->webkitCurrentFullScreenElement();
+ return 0;
+}
+
+bool FullscreenController::isFullScreen(Document* document)
+{
+ if (FullscreenController* found = fromIfExists(document))
+ return found->webkitIsFullScreen();
+ return false;
+}
+
+bool FullscreenController::isAnimatingFullScreen(Document* document)
+{
+ if (FullscreenController* found = fromIfExists(document))
+ return found->isAnimatingFullScreen();
+ return false;
+}
+
+FullscreenController::FullscreenController(Document* document)
+ : DocumentLifecycleObserver(document)
+ , m_areKeysEnabledInFullScreen(false)
+ , m_isAnimatingFullScreen(false)
+ , m_fullScreenRenderer(0)
+ , m_fullScreenChangeDelayTimer(this, &FullscreenController::fullScreenChangeDelayTimerFired)
+{
+ document->setHasFullscreenController();
+}
+
+FullscreenController::~FullscreenController()
+{
+}
+
+inline Document* FullscreenController::document()
+{
+ return toDocument(scriptExecutionContext());
+}
+
+void FullscreenController::documentWasDetached()
+{
+ m_fullScreenChangeEventTargetQueue.clear();
+ m_fullScreenErrorEventTargetQueue.clear();
+
+ if (m_fullScreenRenderer)
+ setFullScreenRenderer(0);
+}
+
+void FullscreenController::documentWasDisposed()
+{
+ m_fullScreenElement = 0;
+ m_fullScreenElementStack.clear();
+}
+
+bool FullscreenController::fullScreenIsAllowedForElement(Element* element) const
+{
+ ASSERT(element);
+ return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document()->ownerElement());
+}
+
+void FullscreenController::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
+{
+ // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
+ // for full screen mode, and do not have the concept of a full screen element stack.
+ bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
+
+ do {
+ if (!element)
+ element = document()->documentElement();
+
+ // 1. If any of the following conditions are true, terminate these steps and queue a task to fire
+ // an event named fullscreenerror with its bubbles attribute set to true on the context object's
+ // node document:
+
+ // The context object is not in a document.
+ if (!element->inDocument())
+ break;
+
+ // The context object's node document, or an ancestor browsing context's document does not have
+ // the fullscreen enabled flag set.
+ if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenIsAllowedForElement(element))
+ break;
+
+ // The context object's node document fullscreen element stack is not empty and its top element
+ // is not an ancestor of the context object. (NOTE: Ignore this requirement if the request was
+ // made via the legacy Mozilla-style API.)
+ if (!m_fullScreenElementStack.isEmpty() && !inLegacyMozillaMode) {
+ Element* lastElementOnStack = m_fullScreenElementStack.last().get();
+ if (lastElementOnStack == element || !lastElementOnStack->contains(element))
+ break;
+ }
+
+ // A descendant browsing context's document has a non-empty fullscreen element stack.
+ bool descendentHasNonEmptyStack = false;
+ for (Frame* descendant = document()->frame() ? document()->frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
+ if (fullscreenElementFrom(descendant->document())) {
+ descendentHasNonEmptyStack = true;
+ break;
+ }
+ }
+ if (descendentHasNonEmptyStack && !inLegacyMozillaMode)
+ break;
+
+ // This algorithm is not allowed to show a pop-up:
+ // An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
+ // - an activation behavior is currently being processed whose click event was trusted, or
+ // - the event listener for a trusted click event is being handled.
+ if (!ScriptController::processingUserGesture())
+ break;
+
+ // There is a previously-established user preference, security risk, or platform limitation.
+ if (!document()->page() || !document()->page()->settings()->fullScreenEnabled())
+ break;
+
+ // 2. Let doc be element's node document. (i.e. "this")
+ Document* currentDoc = document();
+
+ // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc.
+ Deque<Document*> docs;
+
+ do {
+ docs.prepend(currentDoc);
+ currentDoc = currentDoc->ownerElement() ? currentDoc->ownerElement()->document() : 0;
+ } while (currentDoc);
+
+ // 4. For each document in docs, run these substeps:
+ Deque<Document*>::iterator current = docs.begin(), following = docs.begin();
+
+ do {
+ ++following;
+
+ // 1. Let following document be the document after document in docs, or null if there is no
+ // such document.
+ Document* currentDoc = *current;
+ Document* followingDoc = following != docs.end() ? *following : 0;
+
+ // 2. If following document is null, push context object on document's fullscreen element
+ // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
+ // set to true on the document.
+ if (!followingDoc) {
+ from(currentDoc)->pushFullscreenElementStack(element);
+ addDocumentToFullScreenChangeEventQueue(currentDoc);
+ continue;
+ }
+
+ // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
+ // is not following document's browsing context container,
+ Element* topElement = fullscreenElementFrom(currentDoc);
+ if (!topElement || topElement != followingDoc->ownerElement()) {
+ // ...push following document's browsing context container on document's fullscreen element
+ // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
+ // set to true on document.
+ from(currentDoc)->pushFullscreenElementStack(followingDoc->ownerElement());
+ addDocumentToFullScreenChangeEventQueue(currentDoc);
+ continue;
+ }
+
+ // 4. Otherwise, do nothing for this document. It stays the same.
+ } while (++current != docs.end());
+
+ // 5. Return, and run the remaining steps asynchronously.
+ // 6. Optionally, perform some animation.
+ m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
+ document()->page()->chrome().client()->enterFullScreenForElement(element);
+
+ // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
+ return;
+ } while (0);
+
+ m_fullScreenErrorEventTargetQueue.append(element ? element : document()->documentElement());
+ m_fullScreenChangeDelayTimer.startOneShot(0);
+}
+
+void FullscreenController::webkitCancelFullScreen()
+{
+ // The Mozilla "cancelFullScreen()" API behaves like the W3C "fully exit fullscreen" behavior, which
+ // is defined as:
+ // "To fully exit fullscreen act as if the exitFullscreen() method was invoked on the top-level browsing
+ // context's document and subsequently empty that document's fullscreen element stack."
+ if (!fullscreenElementFrom(document()->topDocument()))
+ return;
+
+ // To achieve that aim, remove all the elements from the top document's stack except for the first before
+ // calling webkitExitFullscreen():
+ Vector<RefPtr<Element> > replacementFullscreenElementStack;
+ replacementFullscreenElementStack.append(fullscreenElementFrom(document()->topDocument()));
+ FullscreenController* topController = from(document()->topDocument());
+ topController->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
+ topController->webkitExitFullscreen();
+}
+
+void FullscreenController::webkitExitFullscreen()
+{
+ // The exitFullscreen() method must run these steps:
+
+ // 1. Let doc be the context object. (i.e. "this")
+ Document* currentDoc = document();
+
+ // 2. If doc's fullscreen element stack is empty, terminate these steps.
+ if (m_fullScreenElementStack.isEmpty())
+ return;
+
+ // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
+ // element stack (if any), ordered so that the child of the doc is last and the document furthest
+ // away from the doc is first.
+ Deque<RefPtr<Document> > descendants;
+ for (Frame* descendant = document()->frame() ? document()->frame()->tree()->traverseNext() : 0; descendant; descendant = descendant->tree()->traverseNext()) {
+ if (fullscreenElementFrom(descendant->document()))
+ descendants.prepend(descendant->document());
+ }
+
+ // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
+ // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
+ for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
+ from(i->get())->clearFullscreenElementStack();
+ addDocumentToFullScreenChangeEventQueue(i->get());
+ }
+
+ // 5. While doc is not null, run these substeps:
+ Element* newTop = 0;
+ while (currentDoc) {
+ // 1. Pop the top element of doc's fullscreen element stack.
+ from(currentDoc)->popFullscreenElementStack();
+
+ // If doc's fullscreen element stack is non-empty and the element now at the top is either
+ // not in a document or its node document is not doc, repeat this substep.
+ newTop = fullscreenElementFrom(currentDoc);
+ if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
+ continue;
+
+ // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
+ // on doc.
+ addDocumentToFullScreenChangeEventQueue(currentDoc);
+
+ // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
+ // container, set doc to that browsing context container's node document.
+ if (!newTop && currentDoc->ownerElement()) {
+ currentDoc = currentDoc->ownerElement()->document();
+ continue;
+ }
+
+ // 4. Otherwise, set doc to null.
+ currentDoc = 0;
+ }
+
+ // 6. Return, and run the remaining steps asynchronously.
+ // 7. Optionally, perform some animation.
+
+ if (!document()->page())
+ return;
+
+ // Only exit out of full screen window mode if there are no remaining elements in the
+ // full screen stack.
+ if (!newTop) {
+ document()->page()->chrome().client()->exitFullScreenForElement(m_fullScreenElement.get());
+ return;
+ }
+
+ // Otherwise, notify the chrome of the new full screen element.
+ document()->page()->chrome().client()->enterFullScreenForElement(newTop);
+}
+
+bool FullscreenController::webkitFullscreenEnabled(Document* document)
+{
+ // 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
+ // browsing context's documents have their fullscreen enabled flag set, or false otherwise.
+
+ // Top-level browsing contexts are implied to have their allowFullScreen attribute set.
+ return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, document->ownerElement());
+
+}
+
+void FullscreenController::webkitWillEnterFullScreenForElement(Element* element)
+{
+ if (!document()->attached())
+ return;
+
+ ASSERT(element);
+
+ // Protect against being called after the document has been removed from the page.
+ if (!document()->page())
+ return;
+
+ ASSERT(document()->page()->settings()->fullScreenEnabled());
+
+ if (m_fullScreenRenderer)
+ m_fullScreenRenderer->unwrapRenderer();
+
+ m_fullScreenElement = element;
+
+#if USE(NATIVE_FULLSCREEN_VIDEO)
+ if (element && element->isMediaElement())
+ return;
+#endif
+
+ // Create a placeholder block for a the full-screen element, to keep the page from reflowing
+ // when the element is removed from the normal flow. Only do this for a RenderBox, as only
+ // a box will have a frameRect. The placeholder will be created in setFullScreenRenderer()
+ // during layout.
+ RenderObject* renderer = m_fullScreenElement->renderer();
+ bool shouldCreatePlaceholder = renderer && renderer->isBox();
+ if (shouldCreatePlaceholder) {
+ m_savedPlaceholderFrameRect = toRenderBox(renderer)->frameRect();
+ m_savedPlaceholderRenderStyle = RenderStyle::clone(renderer->style());
+ }
+
+ if (m_fullScreenElement != document()->documentElement())
+ RenderFullScreen::wrapRenderer(renderer, renderer ? renderer->parent() : 0, document());
+
+ m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
+
+ document()->recalcStyle(Node::Force);
+}
+
+void FullscreenController::webkitDidEnterFullScreenForElement(Element*)
+{
+ if (!m_fullScreenElement)
+ return;
+
+ if (!document()->attached())
+ return;
+
+ m_fullScreenElement->didBecomeFullscreenElement();
+
+ m_fullScreenChangeDelayTimer.startOneShot(0);
+}
+
+void FullscreenController::webkitWillExitFullScreenForElement(Element*)
+{
+ if (!m_fullScreenElement)
+ return;
+
+ if (!document()->attached())
+ return;
+
+ m_fullScreenElement->willStopBeingFullscreenElement();
+}
+
+void FullscreenController::webkitDidExitFullScreenForElement(Element*)
+{
+ if (!m_fullScreenElement)
+ return;
+
+ if (!document()->attached())
+ return;
+
+ m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
+
+ m_areKeysEnabledInFullScreen = false;
+
+ if (m_fullScreenRenderer)
+ m_fullScreenRenderer->unwrapRenderer();
+
+ m_fullScreenElement = 0;
+ document()->scheduleForcedStyleRecalc();
+
+ // When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
+ // means that the events will be queued there. So if we have no events here, start the timer on
+ // the exiting document.
+ Document* exitingDocument = document();
+ if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
+ exitingDocument = document()->topDocument();
+ from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0);
+}
+
+void FullscreenController::setFullScreenRenderer(RenderFullScreen* renderer)
+{
+ if (renderer == m_fullScreenRenderer)
+ return;
+
+ if (renderer && m_savedPlaceholderRenderStyle) {
+ renderer->createPlaceholder(m_savedPlaceholderRenderStyle.release(), m_savedPlaceholderFrameRect);
+ } else if (renderer && m_fullScreenRenderer && m_fullScreenRenderer->placeholder()) {
+ RenderBlock* placeholder = m_fullScreenRenderer->placeholder();
+ renderer->createPlaceholder(RenderStyle::clone(placeholder->style()), placeholder->frameRect());
+ }
+
+ if (m_fullScreenRenderer)
+ m_fullScreenRenderer->destroy();
+ ASSERT(!m_fullScreenRenderer);
+
+ m_fullScreenRenderer = renderer;
+}
+
+void FullscreenController::fullScreenRendererDestroyed()
+{
+ m_fullScreenRenderer = 0;
+}
+
+void FullscreenController::fullScreenChangeDelayTimerFired(Timer<FullscreenController>*)
+{
+ // Since we dispatch events in this function, it's possible that the
+ // document will be detached and GC'd. We protect it here to make sure we
+ // can finish the function successfully.
+ RefPtr<Document> protectDocument(document());
+ Deque<RefPtr<Node> > changeQueue;
+ m_fullScreenChangeEventTargetQueue.swap(changeQueue);
+ Deque<RefPtr<Node> > errorQueue;
+ m_fullScreenErrorEventTargetQueue.swap(errorQueue);
+
+ while (!changeQueue.isEmpty()) {
+ RefPtr<Node> node = changeQueue.takeFirst();
+ if (!node)
+ node = document()->documentElement();
+ // The dispatchEvent below may have blown away our documentElement.
+ if (!node)
+ continue;
+
+ // If the element was removed from our tree, also message the documentElement. Since we may
+ // have a document hierarchy, check that node isn't in another document.
+ if (!document()->contains(node.get()) && !node->inDocument())
+ changeQueue.append(document()->documentElement());
+
+ node->dispatchEvent(Event::create(eventNames().webkitfullscreenchangeEvent, true, false));
+ }
+
+ while (!errorQueue.isEmpty()) {
+ RefPtr<Node> node = errorQueue.takeFirst();
+ if (!node)
+ node = document()->documentElement();
+ // The dispatchEvent below may have blown away our documentElement.
+ if (!node)
+ continue;
+
+ // If the element was removed from our tree, also message the documentElement. Since we may
+ // have a document hierarchy, check that node isn't in another document.
+ if (!document()->contains(node.get()) && !node->inDocument())
+ errorQueue.append(document()->documentElement());
+
+ node->dispatchEvent(Event::create(eventNames().webkitfullscreenerrorEvent, true, false));
+ }
+}
+
+void FullscreenController::fullScreenElementRemoved()
+{
+ m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
+ webkitCancelFullScreen();
+}
+
+void FullscreenController::removeFullScreenElementOfSubtree(Node* node, bool amongChildrenOnly)
+{
+ if (!m_fullScreenElement)
+ return;
+
+ bool elementInSubtree = false;
+ if (amongChildrenOnly)
+ elementInSubtree = m_fullScreenElement->isDescendantOf(node);
+ else
+ elementInSubtree = (m_fullScreenElement == node) || m_fullScreenElement->isDescendantOf(node);
+
+ if (elementInSubtree)
+ fullScreenElementRemoved();
+}
+
+void FullscreenController::setAnimatingFullScreen(bool flag)
+{
+ if (m_isAnimatingFullScreen == flag)
+ return;
+ m_isAnimatingFullScreen = flag;
+
+ if (m_fullScreenElement && m_fullScreenElement->isDescendantOf(document())) {
+ m_fullScreenElement->setNeedsStyleRecalc();
+ document()->scheduleForcedStyleRecalc();
+ }
+}
+
+void FullscreenController::clearFullscreenElementStack()
+{
+ m_fullScreenElementStack.clear();
+}
+
+void FullscreenController::popFullscreenElementStack()
+{
+ if (m_fullScreenElementStack.isEmpty())
+ return;
+
+ m_fullScreenElementStack.removeLast();
+}
+
+void FullscreenController::pushFullscreenElementStack(Element* element)
+{
+ m_fullScreenElementStack.append(element);
+}
+
+void FullscreenController::addDocumentToFullScreenChangeEventQueue(Document* doc)
+{
+ ASSERT(doc);
+
+ Node* target = 0;
+ if (FullscreenController* controller = fromIfExists(doc)) {
+ target = controller->webkitFullscreenElement();
+ if (!target)
+ target = controller->webkitCurrentFullScreenElement();
+ }
+
+ if (!target)
+ target = doc;
+ m_fullScreenChangeEventTargetQueue.append(target);
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/FullscreenController.h b/Source/core/dom/FullscreenController.h
new file mode 100644
index 0000000..b32a96b
--- /dev/null
+++ b/Source/core/dom/FullscreenController.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef FullscreenController_h
+#define FullscreenController_h
+
+#include "core/dom/DocumentLifecycleObserver.h"
+#include "core/dom/Element.h"
+#include "core/platform/Supplementable.h"
+#include "core/platform/Timer.h"
+#include "core/platform/graphics/LayoutRect.h"
+#include "wtf/Deque.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Document;
+class Element;
+class Node;
+class RenderFullScreen;
+class RenderStyle;
+class ScriptExecutionContext;
+
+class FullscreenController
+ : public Supplement<ScriptExecutionContext>
+ , public DocumentLifecycleObserver {
+public:
+ virtual ~FullscreenController();
+ static const char* supplementName();
+ static FullscreenController* from(Document*);
+ static FullscreenController* fromIfExists(Document*);
+ static Element* fullscreenElementFrom(Document*);
+ static Element* currentFullScreenElementFrom(Document*);
+ static bool isFullScreen(Document*);
+ static bool isAnimatingFullScreen(Document*);
+ static bool isActiveFullScreenElement(const Element*);
+
+ enum FullScreenCheckType {
+ EnforceIFrameAllowFullScreenRequirement,
+ ExemptIFrameAllowFullScreenRequirement,
+ };
+
+ void requestFullScreenForElement(Element*, unsigned short flags, FullScreenCheckType);
+ void webkitCancelFullScreen();
+
+ void webkitWillEnterFullScreenForElement(Element*);
+ void webkitDidEnterFullScreenForElement(Element*);
+ void webkitWillExitFullScreenForElement(Element*);
+ void webkitDidExitFullScreenForElement(Element*);
+
+ void setFullScreenRenderer(RenderFullScreen*);
+ RenderFullScreen* fullScreenRenderer() const { return m_fullScreenRenderer; }
+ void fullScreenRendererDestroyed();
+
+ void clearFullscreenElementStack();
+ void popFullscreenElementStack();
+ void pushFullscreenElementStack(Element*);
+ void addDocumentToFullScreenChangeEventQueue(Document*);
+
+ bool fullScreenIsAllowedForElement(Element*) const;
+ void fullScreenElementRemoved();
+ void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
+ bool isAnimatingFullScreen() const { return m_isAnimatingFullScreen; }
+ void setAnimatingFullScreen(bool);
+
+ // W3C API
+ static bool webkitFullscreenEnabled(Document*);
+ Element* webkitFullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; }
+ void webkitExitFullscreen();
+
+ bool webkitIsFullScreen() const { return m_fullScreenElement.get(); }
+ bool webkitFullScreenKeyboardInputAllowed() const { return m_fullScreenElement.get() && m_areKeysEnabledInFullScreen; }
+ Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
+
+ virtual void documentWasDetached() OVERRIDE;
+ virtual void documentWasDisposed() OVERRIDE;
+
+private:
+ static FullscreenController* fromIfExistsSlow(Document*);
+
+ explicit FullscreenController(Document*);
+
+ Document* document();
+ void fullScreenChangeDelayTimerFired(Timer<FullscreenController>*);
+
+ bool m_areKeysEnabledInFullScreen;
+ bool m_isAnimatingFullScreen;
+ RefPtr<Element> m_fullScreenElement;
+ Vector<RefPtr<Element> > m_fullScreenElementStack;
+ RenderFullScreen* m_fullScreenRenderer;
+ Timer<FullscreenController> m_fullScreenChangeDelayTimer;
+ Deque<RefPtr<Node> > m_fullScreenChangeEventTargetQueue;
+ Deque<RefPtr<Node> > m_fullScreenErrorEventTargetQueue;
+ LayoutRect m_savedPlaceholderFrameRect;
+ RefPtr<RenderStyle> m_savedPlaceholderRenderStyle;
+};
+
+inline bool FullscreenController::isActiveFullScreenElement(const Element* element)
+{
+ FullscreenController* controller = fromIfExists(element->document());
+ if (!controller)
+ return false;
+ return controller->webkitIsFullScreen() && controller->webkitCurrentFullScreenElement() == element;
+}
+
+inline FullscreenController* FullscreenController::fromIfExists(Document* document)
+{
+ if (!document->hasFullscreenController())
+ return 0;
+ return fromIfExistsSlow(document);
+}
+
+} // namespace WebCore
+
+#endif // FullscreenController_h
diff --git a/Source/core/dom/IconURL.h b/Source/core/dom/IconURL.h
index d4109b2..7b689bb 100644
--- a/Source/core/dom/IconURL.h
+++ b/Source/core/dom/IconURL.h
@@ -31,7 +31,7 @@
#ifndef IconURL_h
#define IconURL_h
-#include "core/platform/KURL.h"
+#include "weborigin/KURL.h"
namespace WebCore {
diff --git a/Source/core/dom/KeyboardEvent.idl b/Source/core/dom/KeyboardEvent.idl
index 6eefd3a..134cb59 100644
--- a/Source/core/dom/KeyboardEvent.idl
+++ b/Source/core/dom/KeyboardEvent.idl
@@ -34,7 +34,7 @@
void initKeyboardEvent([Default=Undefined] optional DOMString type,
[Default=Undefined] optional boolean canBubble,
[Default=Undefined] optional boolean cancelable,
- [Default=Undefined] optional DOMWindow view,
+ [Default=Undefined] optional Window view,
[Default=Undefined] optional DOMString keyIdentifier,
[Default=Undefined] optional unsigned long keyLocation,
[Default=Undefined] optional boolean ctrlKey,
diff --git a/Source/core/dom/MessageChannel.idl b/Source/core/dom/MessageChannel.idl
index f83d729..ca0e39f 100644
--- a/Source/core/dom/MessageChannel.idl
+++ b/Source/core/dom/MessageChannel.idl
@@ -27,7 +27,7 @@
[
GlobalContext=WindowAndWorker,
Constructor,
- CallWith=ScriptExecutionContext,
+ ConstructorCallWith=ScriptExecutionContext,
CustomConstructor
] interface MessageChannel {
diff --git a/Source/core/dom/MessageEvent.idl b/Source/core/dom/MessageEvent.idl
index 66adad2..540b17d 100644
--- a/Source/core/dom/MessageEvent.idl
+++ b/Source/core/dom/MessageEvent.idl
@@ -31,7 +31,7 @@
] interface MessageEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString origin;
[InitializedByEventConstructor] readonly attribute DOMString lastEventId;
- [InitializedByEventConstructor] readonly attribute DOMWindow source;
+ [InitializedByEventConstructor] readonly attribute Window source;
[InitializedByEventConstructor, CustomGetter] readonly attribute any data;
[InitializedByEventConstructor] readonly attribute MessagePort[] ports;
@@ -41,7 +41,7 @@
[Default=Undefined] optional any dataArg,
[Default=Undefined] optional DOMString originArg,
[Default=Undefined] optional DOMString lastEventIdArg,
- [Default=Undefined] optional DOMWindow sourceArg,
+ [Default=Undefined] optional Window sourceArg,
[Default=Undefined] optional Array messagePorts);
[Custom] void webkitInitMessageEvent([Default=Undefined] optional DOMString typeArg,
@@ -50,7 +50,7 @@
[Default=Undefined] optional any dataArg,
[Default=Undefined] optional DOMString originArg,
[Default=Undefined] optional DOMString lastEventIdArg,
- [Default=Undefined] optional DOMWindow sourceArg,
+ [Default=Undefined] optional Window sourceArg,
[Default=Undefined] optional Array transferables);
};
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index 92fe39f..dec07cf 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -29,7 +29,6 @@
#include <wtf/text/AtomicString.h>
#include "core/dom/Document.h"
-#include "core/dom/EventException.h"
#include "core/dom/EventNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/MessageEvent.h"
diff --git a/Source/core/dom/MessagePort.h b/Source/core/dom/MessagePort.h
index aa58831..5124eb2 100644
--- a/Source/core/dom/MessagePort.h
+++ b/Source/core/dom/MessagePort.h
@@ -82,12 +82,12 @@
bool hasPendingActivity();
- void setOnmessage(PassRefPtr<EventListener> listener)
+ void setOnmessage(PassRefPtr<EventListener> listener, DOMWrapperWorld* world)
{
- setAttributeEventListener(eventNames().messageEvent, listener);
+ setAttributeEventListener(eventNames().messageEvent, listener, world);
start();
}
- EventListener* onmessage() { return getAttributeEventListener(eventNames().messageEvent); }
+ EventListener* onmessage(DOMWrapperWorld* world) { return getAttributeEventListener(eventNames().messageEvent, world); }
// Returns null if there is no entangled port, or if the entangled port is run by a different thread.
// This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership
diff --git a/Source/core/dom/MouseEvent.idl b/Source/core/dom/MouseEvent.idl
index 5465735..516cb1e 100644
--- a/Source/core/dom/MouseEvent.idl
+++ b/Source/core/dom/MouseEvent.idl
@@ -36,7 +36,7 @@
void initMouseEvent([Default=Undefined] optional DOMString type,
[Default=Undefined] optional boolean canBubble,
[Default=Undefined] optional boolean cancelable,
- [Default=Undefined] optional DOMWindow view,
+ [Default=Undefined] optional Window view,
[Default=Undefined] optional long detail,
[Default=Undefined] optional long screenX,
[Default=Undefined] optional long screenY,
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index b529869..730d4eb 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -51,7 +51,6 @@
#include "core/dom/EventContext.h"
#include "core/dom/EventDispatchMediator.h"
#include "core/dom/EventDispatcher.h"
-#include "core/dom/EventException.h"
#include "core/dom/EventListener.h"
#include "core/dom/EventNames.h"
#include "core/dom/ExceptionCode.h"
@@ -497,15 +496,6 @@
return this;
}
-HTMLInputElement* Node::toInputElement()
-{
- // If one of the below ASSERTs trigger, you are calling this function
- // directly or indirectly from a constructor or destructor of this object.
- // Don't do this!
- ASSERT(!(isHTMLElement() && hasTagName(inputTag)));
- return 0;
-}
-
short Node::tabIndex() const
{
return 0;
@@ -685,7 +675,7 @@
// Both non-empty text nodes. Merge them.
unsigned offset = text->length();
- text->appendData(nextText->data(), IGNORE_EXCEPTION);
+ text->appendData(nextText->data());
document()->textNodesMerged(nextText.get(), offset);
nextText->remove(IGNORE_EXCEPTION);
}
@@ -895,49 +885,35 @@
void Node::lazyAttach(ShouldSetAttached shouldSetAttached)
{
- for (Node* n = this; n; n = NodeTraversal::next(n, this)) {
- if (n->hasChildNodes())
- n->setChildNeedsStyleRecalc();
- n->setStyleChange(FullStyleChange);
- if (shouldSetAttached == SetAttached)
- n->setAttached();
+ // It's safe to synchronously attach here because we're in the middle of style recalc
+ // while it's not safe to mark nodes as needing style recalc except in the loop in
+ // Element::recalcStyle because we may mark an ancestor as not needing recalc and
+ // then the node would never get updated. One place this currently happens is
+ // HTMLObjectElement::renderFallbackContent which may call lazyAttach from inside
+ // attach which was triggered by a recalcStyle.
+ if (document()->inStyleRecalc()) {
+ attach();
+ return;
}
+ setStyleChange(FullStyleChange);
markAncestorsWithChildNeedsStyleRecalc();
+ if (shouldSetAttached == DoNotSetAttached)
+ return;
+ for (Node* node = this; node; node = NodeTraversal::next(node, this))
+ node->setAttached();
}
bool Node::supportsFocus() const
{
return false;
}
-
+
bool Node::isFocusable() const
{
if (!inDocument() || !supportsFocus())
return false;
-
- // Elements in canvas fallback content are not rendered, but they are allowed to be
- // focusable as long as their canvas is displayed and visible.
- if (isElementNode() && toElement(this)->isInCanvasSubtree()) {
- const Element* e = toElement(this);
- while (e && !e->hasLocalName(canvasTag))
- e = e->parentElement();
- ASSERT(e);
- return e->renderer() && e->renderer()->style()->visibility() == VISIBLE;
- }
- if (renderer())
- ASSERT(!renderer()->needsLayout());
- else
- // If the node is in a display:none tree it might say it needs style recalc but
- // the whole document is actually up to date.
- ASSERT(!document()->childNeedsStyleRecalc());
-
- // FIXME: Even if we are not visible, we might have a child that is visible.
- // Hyatt wants to fix that some day with a "has visible content" flag or the like.
- if (!renderer() || renderer()->style()->visibility() != VISIBLE)
- return false;
-
- return true;
+ return rendererIsFocusable();
}
bool Node::isKeyboardFocusable(KeyboardEvent*) const
@@ -1097,7 +1073,7 @@
return false;
}
-void Node::attach()
+void Node::attach(const AttachContext&)
{
ASSERT(!attached());
ASSERT(!renderer() || (renderer()->style() && (renderer()->parent() || renderer()->isRenderView())));
@@ -1140,7 +1116,7 @@
}
#endif
-void Node::detach()
+void Node::detach(const AttachContext& context)
{
#ifndef NDEBUG
ASSERT(!detachingNode);
@@ -1151,13 +1127,17 @@
renderer()->destroyAndCleanupAnonymousWrappers();
setRenderer(0);
- Document* doc = document();
- if (isUserActionElement()) {
- if (hovered())
- doc->hoveredNodeDetached(this);
- if (inActiveChain())
- doc->activeChainNodeDetached(this);
- doc->userActionElements().didDetach(this);
+ // Do not remove the element's hovered and active status
+ // if performing a reattach.
+ if (!context.performingReattach) {
+ Document* doc = document();
+ if (isUserActionElement()) {
+ if (hovered())
+ doc->hoveredNodeDetached(this);
+ if (inActiveChain())
+ doc->activeChainNodeDetached(this);
+ doc->userActionElements().didDetach(this);
+ }
}
clearFlag(IsAttachedFlag);
@@ -1310,11 +1290,6 @@
return toElement(parent);
}
-bool Node::needsShadowTreeWalkerSlow() const
-{
- return (isShadowRoot() || (isElementNode() && (isInsertionPoint() || isPseudoElement() || toElement(this)->hasPseudoElements() || toElement(this)->shadow())));
-}
-
bool Node::isBlockFlowElement() const
{
return isElementNode() && renderer() && renderer()->isBlockFlow();
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 67869aa..87c486b 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -33,10 +33,10 @@
#include "core/editing/EditingBoundary.h"
#include "core/inspector/InspectorCounters.h"
#include "core/page/FocusDirection.h"
-#include "core/platform/KURLHash.h"
#include "core/platform/TreeShared.h"
#include "core/platform/graphics/LayoutRect.h"
#include "core/rendering/style/RenderStyleConstants.h"
+#include "weborigin/KURLHash.h"
#include <wtf/Forward.h>
#include <wtf/ListHashSet.h>
#include <wtf/text/AtomicString.h>
@@ -263,18 +263,12 @@
virtual bool isCharacterDataNode() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
virtual bool isPluginElement() const { return false; }
- virtual bool isInsertionPointNode() const { return false; }
bool isDocumentNode() const;
bool isTreeScope() const { return treeScope()->rootNode() == this; }
bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
- bool isInsertionPoint() const { return getFlag(NeedsShadowTreeWalkerFlag) && isInsertionPointNode(); }
-
- bool needsShadowTreeWalker() const;
- bool needsShadowTreeWalkerSlow() const;
- void setNeedsShadowTreeWalker() { setFlag(NeedsShadowTreeWalkerFlag); }
- void resetNeedsShadowTreeWalker() { setFlag(needsShadowTreeWalkerSlow(), NeedsShadowTreeWalkerFlag); }
+ bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
@@ -413,11 +407,13 @@
virtual short tabIndex() const;
- // Whether this kind of node can receive focus by default. Most nodes are
- // not focusable but some elements, such as form controls and links, are.
+ // Whether this node can receive focus at all. Most nodes are not focusable
+ // but some elements, such as form controls and links, are. Unlike
+ // rendererIsFocusable(), this method may be called when layout is not up to
+ // date, so it must not use the renderer to determine focusability.
virtual bool supportsFocus() const;
// Whether the node can actually be focused.
- virtual bool isFocusable() const;
+ bool isFocusable() const;
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
virtual Node* focusDelegate();
@@ -534,20 +530,27 @@
RenderBox* renderBox() const;
RenderBoxModelObject* renderBoxModelObject() const;
+ struct AttachContext {
+ RenderStyle* resolvedStyle;
+ bool performingReattach;
+
+ AttachContext() : resolvedStyle(0), performingReattach(false) { }
+ };
+
// Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
// appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
// makes the node visible in the FrameView.
- virtual void attach();
+ virtual void attach(const AttachContext& = AttachContext());
// Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
// the node's rendering object from the rendering tree and delete it.
- virtual void detach();
+ virtual void detach(const AttachContext& = AttachContext());
#ifndef NDEBUG
bool inDetach() const;
#endif
- void reattach();
+ void reattach(const AttachContext& = AttachContext());
void lazyReattachIfAttached();
ContainerNode* parentNodeForRenderingAndStyle();
@@ -626,8 +629,6 @@
unsigned short compareDocumentPositionInternal(const Node*, ShadowTreesTreatment) const;
virtual Node* toNode();
- // Obsolete. Use toHTMLInputElement.
- virtual HTMLInputElement* toInputElement();
virtual const AtomicString& interfaceName() const;
virtual ScriptExecutionContext* scriptExecutionContext() const;
@@ -730,7 +731,7 @@
HasScopedHTMLStyleChildFlag = 1 << 22,
HasEventTargetDataFlag = 1 << 23,
V8CollectableDuringMinorGCFlag = 1 << 24,
- NeedsShadowTreeWalkerFlag = 1 << 25,
+ IsInsertionPointFlag = 1 << 25,
IsInShadowTreeFlag = 1 << 26,
IsCustomElement = 1 << 27,
@@ -750,14 +751,14 @@
CreateText = DefaultNodeFlags | IsTextFlag,
CreateContainer = DefaultNodeFlags | IsContainerFlag,
CreateElement = CreateContainer | IsElementFlag,
- CreatePseudoElement = CreateElement | InDocumentFlag | NeedsShadowTreeWalkerFlag,
- CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | NeedsShadowTreeWalkerFlag | IsInShadowTreeFlag,
+ CreatePseudoElement = CreateElement | InDocumentFlag,
+ CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
CreateStyledElement = CreateElement | IsStyledElementFlag,
CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
CreateSVGElement = CreateStyledElement | IsSVGFlag,
CreateDocument = CreateContainer | InDocumentFlag,
- CreateInsertionPoint = CreateHTMLElement | NeedsShadowTreeWalkerFlag,
+ CreateInsertionPoint = CreateHTMLElement | IsInsertionPointFlag,
CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
};
@@ -796,6 +797,13 @@
Document* documentInternal() const { return treeScope()->documentScope(); }
void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
+ // Subclasses may override this method to affect focusability. Unlike
+ // supportsFocus, this method must be called on an up-to-date layout, so it
+ // may use the renderer to reason about focusability. This method cannot be
+ // moved to RenderObject because some focusable nodes don't have renderers,
+ // e.g., HTMLOptionElement.
+ virtual bool rendererIsFocusable() const { return false; }
+
private:
friend class TreeShared<Node>;
@@ -888,11 +896,14 @@
return parentOrShadowHostNode();
}
-inline void Node::reattach()
+inline void Node::reattach(const AttachContext& context)
{
+ AttachContext reattachContext(context);
+ reattachContext.performingReattach = true;
+
if (attached())
- detach();
- attach();
+ detach(reattachContext);
+ attach(reattachContext);
}
inline void Node::lazyReattachIfAttached()
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index a521b04..3d685d2 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -72,8 +72,8 @@
return node;
}
-NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
- : Traversal(rootNode, whatToShow, filter, expandEntityReferences)
+NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ : Traversal(rootNode, whatToShow, filter)
, m_referenceNode(root(), true)
, m_detached(false)
{
diff --git a/Source/core/dom/NodeIterator.h b/Source/core/dom/NodeIterator.h
index cb81a01..53f3d20 100644
--- a/Source/core/dom/NodeIterator.h
+++ b/Source/core/dom/NodeIterator.h
@@ -37,9 +37,9 @@
class NodeIterator : public ScriptWrappable, public RefCounted<NodeIterator>, public Traversal {
public:
- static PassRefPtr<NodeIterator> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
+ static PassRefPtr<NodeIterator> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
{
- return adoptRef(new NodeIterator(rootNode, whatToShow, filter, expandEntityReferences));
+ return adoptRef(new NodeIterator(rootNode, whatToShow, filter));
}
~NodeIterator();
@@ -54,7 +54,7 @@
void nodeWillBeRemoved(Node*);
private:
- NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
+ NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
struct NodePointer {
RefPtr<Node> node;
diff --git a/Source/core/dom/NodeRenderingContext.cpp b/Source/core/dom/NodeRenderingContext.cpp
index 41c6ce0..856fc6f 100644
--- a/Source/core/dom/NodeRenderingContext.cpp
+++ b/Source/core/dom/NodeRenderingContext.cpp
@@ -30,6 +30,7 @@
#include "SVGNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ContainerNode.h"
+#include "core/dom/FullscreenController.h"
#include "core/dom/Node.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/Text.h"
@@ -66,6 +67,14 @@
{
}
+NodeRenderingContext::NodeRenderingContext(Node* node, const Node::AttachContext& context)
+: m_node(node)
+, m_style(context.resolvedStyle)
+, m_parentFlowRenderer(0)
+{
+ m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
+}
+
NodeRenderingContext::~NodeRenderingContext()
{
}
@@ -173,8 +182,6 @@
bool NodeRenderingContext::shouldCreateRenderer() const
{
- if (!m_node->document()->shouldCreateRenderers())
- return false;
if (!m_renderingParent)
return false;
RenderObject* parentRenderer = this->parentRenderer();
@@ -206,8 +213,7 @@
if (m_node->isInShadowTree())
return;
- Document* document = m_node->document();
- if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == m_node)
+ if (m_node->isElementNode() && FullscreenController::isActiveFullScreenElement(toElement(m_node)))
return;
// Allow only svg root elements to be directly collected by a render flow thread.
@@ -268,7 +274,7 @@
element->setRenderer(newRenderer);
newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
- if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == element) {
+ if (FullscreenController::isActiveFullScreenElement(element)) {
newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, document);
if (!newRenderer)
return;
diff --git a/Source/core/dom/NodeRenderingContext.h b/Source/core/dom/NodeRenderingContext.h
index 79038d3..c0e0c9d 100644
--- a/Source/core/dom/NodeRenderingContext.h
+++ b/Source/core/dom/NodeRenderingContext.h
@@ -47,6 +47,7 @@
public:
explicit NodeRenderingContext(Node*);
NodeRenderingContext(Node*, RenderStyle*);
+ NodeRenderingContext(Node*, const Node::AttachContext&);
~NodeRenderingContext();
void createRendererForTextIfNeeded();
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index 1b23181..a04d763 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -47,14 +47,17 @@
m_resetStyleInheritance = m_resetStyleInheritance || root->resetStyleInheritance();
}
-ContainerNode* parentSlow(const Node* node, ParentDetails* details)
+ContainerNode* parent(const Node* node, ParentDetails* details)
{
+ if (ShadowRoot* root = node->containingShadowRoot())
+ root->host()->ensureDistribution();
+
ComposedShadowTreeWalker walker(node, ComposedShadowTreeWalker::CrossUpperBoundary, ComposedShadowTreeWalker::CanStartFromShadowBoundary);
ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
return details->outOfComposition() ? 0 : found;
}
-Node* nextSiblingSlow(const Node* node)
+Node* nextSibling(const Node* node)
{
ComposedShadowTreeWalker walker(node);
if (node->isBeforePseudoElement()) {
@@ -73,7 +76,7 @@
return 0;
}
-Node* previousSiblingSlow(const Node* node)
+Node* previousSibling(const Node* node)
{
ComposedShadowTreeWalker walker(node);
if (node->isAfterPseudoElement()) {
diff --git a/Source/core/dom/NodeRenderingTraversal.h b/Source/core/dom/NodeRenderingTraversal.h
index 23bee1d..13fb985 100644
--- a/Source/core/dom/NodeRenderingTraversal.h
+++ b/Source/core/dom/NodeRenderingTraversal.h
@@ -66,11 +66,8 @@
ContainerNode* parent(const Node*);
ContainerNode* parent(const Node*, ParentDetails*);
-ContainerNode* parentSlow(const Node*, ParentDetails*);
Node* nextSibling(const Node*);
-Node* nextSiblingSlow(const Node*);
Node* previousSibling(const Node*);
-Node* previousSiblingSlow(const Node*);
Node* nextInScope(const Node*);
Node* previousInScope(const Node*);
@@ -83,46 +80,6 @@
return parent(node, &unusedDetails);
}
-inline ContainerNode* parent(const Node* node, ParentDetails* details)
-{
- if (!node->needsShadowTreeWalker()) {
-#ifndef NDEBUG
- ParentDetails slowDetails;
- ASSERT(node->parentNode() == parentSlow(node, &slowDetails));
- ASSERT(slowDetails == *details);
-#endif
- return node->parentNodeGuaranteedHostFree();
- }
-
- return parentSlow(node, details);
-}
-
-inline Node* nextSibling(const Node* node)
-{
- if (!node->needsShadowTreeWalker()) {
- Node* next = node->nextSibling();
- if (!next || !next->isInsertionPoint()) {
- ASSERT(nextSiblingSlow(node) == next);
- return next;
- }
- }
-
- return nextSiblingSlow(node);
-}
-
-inline Node* previousSibling(const Node* node)
-{
- if (!node->needsShadowTreeWalker()) {
- Node* prev = node->previousSibling();
- if (!prev || !prev->isInsertionPoint()) {
- ASSERT(previousSiblingSlow(node) == prev);
- return prev;
- }
- }
-
- return previousSiblingSlow(node);
-}
-
}
} // namespace WebCore
diff --git a/Source/core/dom/ParentNode.idl b/Source/core/dom/ParentNode.idl
new file mode 100644
index 0000000..fef5c3b
--- /dev/null
+++ b/Source/core/dom/ParentNode.idl
@@ -0,0 +1,12 @@
+[
+ NoInterfaceObject
+] interface ParentNode {
+ [PerWorldBindings] readonly attribute HTMLCollection children;
+ [PerWorldBindings] readonly attribute Element firstElementChild;
+ [PerWorldBindings] readonly attribute Element lastElementChild;
+ [PerWorldBindings] readonly attribute unsigned long childElementCount;
+};
+
+Document implements ParentNode;
+DocumentFragment implements ParentNode;
+Element implements ParentNode;
diff --git a/Source/core/dom/PseudoElement.cpp b/Source/core/dom/PseudoElement.cpp
index 225ac0a..468883b 100644
--- a/Source/core/dom/PseudoElement.cpp
+++ b/Source/core/dom/PseudoElement.cpp
@@ -74,11 +74,11 @@
return parentOrShadowHostElement()->renderer()->getCachedPseudoStyle(m_pseudoId);
}
-void PseudoElement::attach()
+void PseudoElement::attach(const AttachContext& context)
{
ASSERT(!renderer());
- Element::attach();
+ Element::attach(context);
RenderObject* renderer = this->renderer();
if (!renderer || !renderer->style()->regionThread().isEmpty())
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index 87c8064..a5d7018 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -43,7 +43,7 @@
~PseudoElement();
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
- virtual void attach() OVERRIDE;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual bool rendererIsNeeded(const NodeRenderingContext&) OVERRIDE;
virtual bool canStartSelection() const OVERRIDE { return false; }
diff --git a/Source/core/dom/Range.idl b/Source/core/dom/Range.idl
index f816069..8418229 100644
--- a/Source/core/dom/Range.idl
+++ b/Source/core/dom/Range.idl
@@ -21,7 +21,7 @@
// Introduced in DOM Level 2:
[
Constructor,
- CallWith=ScriptExecutionContext
+ ConstructorCallWith=ScriptExecutionContext
] interface Range {
[GetterRaisesException] readonly attribute Node startContainer;
diff --git a/Source/core/dom/ScriptElement.cpp b/Source/core/dom/ScriptElement.cpp
index a49e985..d80a9c8 100644
--- a/Source/core/dom/ScriptElement.cpp
+++ b/Source/core/dom/ScriptElement.cpp
@@ -275,6 +275,16 @@
return false;
}
+bool isHTMLScriptElement(Element* element)
+{
+ return element->hasTagName(HTMLNames::scriptTag);
+}
+
+bool isSVGScriptElement(Element* element)
+{
+ return element->hasTagName(SVGNames::scriptTag);
+}
+
void ScriptElement::executeScript(const ScriptSourceCode& sourceCode)
{
ASSERT(m_alreadyStarted);
@@ -298,10 +308,19 @@
if (frame) {
{
IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.get() : 0);
+
+ if (isHTMLScriptElement(m_element))
+ document->pushCurrentScript(toHTMLScriptElement(m_element));
+
// Create a script from the script element node, using the script
// block's source and the script block's type.
// Note: This is where the script is compiled and actually executed.
frame->script()->executeScriptInMainWorld(sourceCode);
+
+ if (isHTMLScriptElement(m_element)) {
+ ASSERT(document->currentScript() == m_element);
+ document->popCurrentScript();
+ }
}
}
}
@@ -410,11 +429,11 @@
ScriptElement* toScriptElementIfPossible(Element* element)
{
- if (element->isHTMLElement() && element->hasTagName(HTMLNames::scriptTag))
- return static_cast<HTMLScriptElement*>(element);
+ if (isHTMLScriptElement(element))
+ return toHTMLScriptElement(element);
- if (element->isSVGElement() && element->hasTagName(SVGNames::scriptTag))
- return static_cast<SVGScriptElement*>(element);
+ if (isSVGScriptElement(element))
+ return toSVGScriptElement(element);
return 0;
}
diff --git a/Source/core/dom/ScriptExecutionContext.h b/Source/core/dom/ScriptExecutionContext.h
index adfbda3..af5e831 100644
--- a/Source/core/dom/ScriptExecutionContext.h
+++ b/Source/core/dom/ScriptExecutionContext.h
@@ -31,9 +31,9 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/dom/SecurityContext.h"
#include "core/page/ConsoleTypes.h"
-#include "core/platform/KURL.h"
#include "core/platform/Supplementable.h"
-#include <wtf/HashSet.h>
+#include "weborigin/KURL.h"
+#include "wtf/HashSet.h"
namespace WebCore {
diff --git a/Source/core/dom/SecurityPolicyViolationEvent.idl b/Source/core/dom/SecurityPolicyViolationEvent.idl
index b214e6f..528b0cc 100644
--- a/Source/core/dom/SecurityPolicyViolationEvent.idl
+++ b/Source/core/dom/SecurityPolicyViolationEvent.idl
@@ -23,7 +23,7 @@
*/
[
- NoInterfaceObject,
+ EnabledAtRuntime=experimentalContentSecurityPolicyFeatures,
ConstructorTemplate=Event
] interface SecurityPolicyViolationEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString documentURI;
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index b48f7ad..32ed0f3 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -163,8 +163,21 @@
matchedElements.append(element);
return;
}
+
+ unsigned selectorCount = m_selectors.size();
+ if (selectorCount == 1) {
+ const SelectorData& selector = m_selectors[0];
+ for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+ if (selectorMatches(selector, element, rootNode)) {
+ matchedElements.append(element);
+ if (firstMatchOnly)
+ return;
+ }
+ }
+ return;
+ }
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
- for (unsigned i = 0; i < m_selectors.size(); ++i) {
+ for (unsigned i = 0; i < selectorCount; ++i) {
if (selectorMatches(m_selectors[i], element, rootNode)) {
matchedElements.append(element);
if (firstMatchOnly)
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index e2b1400..f5d58a3 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -176,7 +176,7 @@
return 0;
}
- setData(newText, IGNORE_EXCEPTION);
+ setData(newText);
return protectedThis.release();
}
@@ -216,9 +216,7 @@
if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
return true;
-
- // FIXME: We should resolve this function's dependencies on next and previous renderers
- // lazily to avoid potentially N^2 walks through the DOM.
+
RenderObject* prev = context.previousRenderer();
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
@@ -272,25 +270,30 @@
return new (arena) RenderText(this, dataImpl());
}
-void Text::attach()
+void Text::attach(const AttachContext& context)
{
createTextRendererIfNeeded();
- CharacterData::attach();
+ CharacterData::attach(context);
}
void Text::recalcTextStyle(StyleChange change)
{
RenderText* renderer = toRenderText(this->renderer());
- if (change != NoChange && renderer)
- renderer->setStyle(document()->styleResolver()->styleForText(this));
+ if (!renderer) {
+ if (needsStyleRecalc())
+ reattach();
+ clearNeedsStyleRecalc();
+ return;
+ }
if (needsStyleRecalc()) {
- if (renderer)
- renderer->setText(dataImpl());
- else
- reattach();
+ renderer->setStyle(document()->styleResolver()->styleForText(this));
+ renderer->setText(dataImpl());
+ } else if (change != NoChange) {
+ renderer->setStyle(document()->styleResolver()->styleForText(this));
}
+
clearNeedsStyleRecalc();
}
diff --git a/Source/core/dom/Text.h b/Source/core/dom/Text.h
index 136822d..3f33246 100644
--- a/Source/core/dom/Text.h
+++ b/Source/core/dom/Text.h
@@ -52,7 +52,7 @@
RenderText* createTextRenderer(RenderArena*, RenderStyle*);
void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
- virtual void attach() OVERRIDE FINAL;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return true; }
virtual NodeType nodeType() const OVERRIDE;
diff --git a/Source/core/dom/Text.idl b/Source/core/dom/Text.idl
index f8b1a15..a770f78 100644
--- a/Source/core/dom/Text.idl
+++ b/Source/core/dom/Text.idl
@@ -18,7 +18,7 @@
*/
[
Constructor([Default=NullString] optional DOMString data),
- CallWith=ScriptExecutionContext,
+ ConstructorCallWith=ScriptExecutionContext,
CustomToV8
] interface Text : CharacterData {
diff --git a/Source/core/dom/TextEvent.idl b/Source/core/dom/TextEvent.idl
index 4af1a6f..10ec19a 100644
--- a/Source/core/dom/TextEvent.idl
+++ b/Source/core/dom/TextEvent.idl
@@ -31,7 +31,7 @@
void initTextEvent([Default=Undefined] optional DOMString typeArg,
[Default=Undefined] optional boolean canBubbleArg,
[Default=Undefined] optional boolean cancelableArg,
- [Default=Undefined] optional DOMWindow viewArg,
+ [Default=Undefined] optional Window viewArg,
[Default=Undefined] optional DOMString dataArg);
};
diff --git a/Source/core/dom/Touch.idl b/Source/core/dom/Touch.idl
index 2d89c3b..c748ec8 100644
--- a/Source/core/dom/Touch.idl
+++ b/Source/core/dom/Touch.idl
@@ -23,9 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject
-] interface Touch {
+interface Touch {
readonly attribute long clientX;
readonly attribute long clientY;
readonly attribute long screenX;
diff --git a/Source/core/dom/TouchEvent.idl b/Source/core/dom/TouchEvent.idl
index c0838a8..6348e68 100644
--- a/Source/core/dom/TouchEvent.idl
+++ b/Source/core/dom/TouchEvent.idl
@@ -23,9 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject
-] interface TouchEvent : UIEvent {
+interface TouchEvent : UIEvent {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
@@ -38,7 +36,7 @@
[Default=Undefined] optional TouchList targetTouches,
[Default=Undefined] optional TouchList changedTouches,
[Default=Undefined] optional DOMString type,
- [Default=Undefined] optional DOMWindow view,
+ [Default=Undefined] optional Window view,
[Default=Undefined] optional long screenX,
[Default=Undefined] optional long screenY,
[Default=Undefined] optional long clientX,
diff --git a/Source/core/dom/TouchList.idl b/Source/core/dom/TouchList.idl
index 19900ac..351a59c 100644
--- a/Source/core/dom/TouchList.idl
+++ b/Source/core/dom/TouchList.idl
@@ -23,9 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject
-] interface TouchList {
+interface TouchList {
readonly attribute unsigned long length;
getter Touch item(unsigned long index);
diff --git a/Source/core/dom/Traversal.cpp b/Source/core/dom/Traversal.cpp
index 207480c..a9262cc 100644
--- a/Source/core/dom/Traversal.cpp
+++ b/Source/core/dom/Traversal.cpp
@@ -30,18 +30,15 @@
namespace WebCore {
-Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter, bool expandEntityReferences)
+Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter)
: m_root(rootNode)
, m_whatToShow(whatToShow)
, m_filter(nodeFilter)
- , m_expandEntityReferences(expandEntityReferences)
{
}
short Traversal::acceptNode(ScriptState* state, Node* node) const
{
- // FIXME: To handle XML properly we would have to check m_expandEntityReferences.
-
// The bit twiddling here is done to map DOM node types, which are given as integers from
// 1 through 14, to whatToShow bit masks.
if (!(((1 << (node->nodeType() - 1)) & m_whatToShow)))
diff --git a/Source/core/dom/Traversal.h b/Source/core/dom/Traversal.h
index 45cd76e..3e70886 100644
--- a/Source/core/dom/Traversal.h
+++ b/Source/core/dom/Traversal.h
@@ -38,17 +38,19 @@
Node* root() const { return m_root.get(); }
unsigned whatToShow() const { return m_whatToShow; }
NodeFilter* filter() const { return m_filter.get(); }
- bool expandEntityReferences() const { return m_expandEntityReferences; }
+ // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
+ // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
+ // Document.createNodeIterator() and Document.createTreeWalker().
+ bool expandEntityReferences() const { return false; }
protected:
- Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
+ Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
short acceptNode(ScriptState*, Node*) const;
private:
RefPtr<Node> m_root;
unsigned m_whatToShow;
RefPtr<NodeFilter> m_filter;
- bool m_expandEntityReferences;
};
} // namespace WebCore
diff --git a/Source/core/dom/TreeWalker.cpp b/Source/core/dom/TreeWalker.cpp
index 41c8210..8ed9d78 100644
--- a/Source/core/dom/TreeWalker.cpp
+++ b/Source/core/dom/TreeWalker.cpp
@@ -34,8 +34,8 @@
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
- : Traversal(rootNode, whatToShow, filter, expandEntityReferences)
+TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ : Traversal(rootNode, whatToShow, filter)
, m_current(root())
{
ScriptWrappable::init(this);
diff --git a/Source/core/dom/TreeWalker.h b/Source/core/dom/TreeWalker.h
index 0fce42f..0ab3976 100644
--- a/Source/core/dom/TreeWalker.h
+++ b/Source/core/dom/TreeWalker.h
@@ -37,10 +37,10 @@
class TreeWalker : public ScriptWrappable, public RefCounted<TreeWalker>, public Traversal {
public:
- static PassRefPtr<TreeWalker> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences)
+ static PassRefPtr<TreeWalker> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
{
- return adoptRef(new TreeWalker(rootNode, whatToShow, filter, expandEntityReferences));
- }
+ return adoptRef(new TreeWalker(rootNode, whatToShow, filter));
+ }
Node* currentNode() const { return m_current.get(); }
void setCurrentNode(PassRefPtr<Node>, ExceptionCode&);
@@ -54,8 +54,8 @@
Node* nextNode(ScriptState*);
private:
- TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>, bool expandEntityReferences);
-
+ TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+
Node* setCurrent(PassRefPtr<Node>);
RefPtr<Node> m_current;
diff --git a/Source/core/dom/UIEvent.idl b/Source/core/dom/UIEvent.idl
index 415078a..09960d7 100644
--- a/Source/core/dom/UIEvent.idl
+++ b/Source/core/dom/UIEvent.idl
@@ -20,13 +20,13 @@
[
ConstructorTemplate=Event
] interface UIEvent : Event {
- [InitializedByEventConstructor] readonly attribute DOMWindow view;
+ [InitializedByEventConstructor] readonly attribute Window view;
[InitializedByEventConstructor] readonly attribute long detail;
void initUIEvent([Default=Undefined] optional DOMString type,
[Default=Undefined] optional boolean canBubble,
[Default=Undefined] optional boolean cancelable,
- [Default=Undefined] optional DOMWindow view,
+ [Default=Undefined] optional Window view,
[Default=Undefined] optional long detail);
// extensions
diff --git a/Source/core/dom/ViewportArguments.cpp b/Source/core/dom/ViewportArguments.cpp
index 8593f84..331ac12 100644
--- a/Source/core/dom/ViewportArguments.cpp
+++ b/Source/core/dom/ViewportArguments.cpp
@@ -103,41 +103,16 @@
}
if (type == ViewportArguments::CSSDeviceAdaptation) {
- switch (int(resultMinWidth)) {
- case ViewportArguments::ValueDeviceWidth:
- resultMinWidth = deviceSize.width();
- break;
- case ViewportArguments::ValueDeviceHeight:
- resultMinWidth = deviceSize.height();
- break;
- }
- switch (int(resultMaxWidth)) {
- case ViewportArguments::ValueDeviceWidth:
- resultMaxWidth = deviceSize.width();
- break;
- case ViewportArguments::ValueDeviceHeight:
- resultMaxWidth = deviceSize.height();
- break;
- }
-
- switch (int(resultMinHeight)) {
- case ViewportArguments::ValueDeviceWidth:
- resultMinHeight = deviceSize.width();
- break;
- case ViewportArguments::ValueDeviceHeight:
- resultMinHeight = deviceSize.height();
- break;
- }
-
- switch (int(resultMaxHeight)) {
- case ViewportArguments::ValueDeviceWidth:
- resultMaxHeight = deviceSize.width();
- break;
- case ViewportArguments::ValueDeviceHeight:
- resultMaxHeight = deviceSize.height();
- break;
- }
+ // device-width/device-height not supported for @viewport.
+ ASSERT(resultMinWidth != ViewportArguments::ValueDeviceWidth);
+ ASSERT(resultMinWidth != ViewportArguments::ValueDeviceHeight);
+ ASSERT(resultMaxWidth != ViewportArguments::ValueDeviceWidth);
+ ASSERT(resultMaxWidth != ViewportArguments::ValueDeviceHeight);
+ ASSERT(resultMinHeight != ViewportArguments::ValueDeviceWidth);
+ ASSERT(resultMinHeight != ViewportArguments::ValueDeviceHeight);
+ ASSERT(resultMaxHeight != ViewportArguments::ValueDeviceWidth);
+ ASSERT(resultMaxHeight != ViewportArguments::ValueDeviceHeight);
if (resultMinWidth != ViewportArguments::ValueAuto || resultMaxWidth != ViewportArguments::ValueAuto)
resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, deviceSize.width(), min), max);
diff --git a/Source/core/dom/AnimationEvent.idl b/Source/core/dom/WebKitAnimationEvent.idl
similarity index 95%
rename from Source/core/dom/AnimationEvent.idl
rename to Source/core/dom/WebKitAnimationEvent.idl
index 46ff164..e53b4e7 100644
--- a/Source/core/dom/AnimationEvent.idl
+++ b/Source/core/dom/WebKitAnimationEvent.idl
@@ -25,8 +25,8 @@
[
ConstructorTemplate=Event,
- InterfaceName=WebKitAnimationEvent
-] interface AnimationEvent : Event {
+ ImplementedAs=AnimationEvent
+] interface WebKitAnimationEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString animationName;
[InitializedByEventConstructor] readonly attribute double elapsedTime;
};
diff --git a/Source/core/dom/NamedFlow.idl b/Source/core/dom/WebKitNamedFlow.idl
similarity index 97%
rename from Source/core/dom/NamedFlow.idl
rename to Source/core/dom/WebKitNamedFlow.idl
index ae2cfeb..5a008bd 100644
--- a/Source/core/dom/NamedFlow.idl
+++ b/Source/core/dom/WebKitNamedFlow.idl
@@ -31,9 +31,9 @@
NoInterfaceObject,
EnabledAtRuntime=cssRegions,
EventTarget,
- InterfaceName=WebKitNamedFlow,
+ ImplementedAs=NamedFlow,
GenerateIsReachable=ownerNode
-] interface NamedFlow {
+] interface WebKitNamedFlow {
readonly attribute DOMString name;
readonly attribute boolean overset;
readonly attribute long firstEmptyRegionIndex;
diff --git a/Source/core/dom/DOMNamedFlowCollection.idl b/Source/core/dom/WebKitNamedFlowCollection.idl
similarity index 84%
rename from Source/core/dom/DOMNamedFlowCollection.idl
rename to Source/core/dom/WebKitNamedFlowCollection.idl
index 1ec92f4..65aa56d 100644
--- a/Source/core/dom/DOMNamedFlowCollection.idl
+++ b/Source/core/dom/WebKitNamedFlowCollection.idl
@@ -30,10 +30,10 @@
[
NoInterfaceObject,
EnabledAtRuntime=cssRegions,
- InterfaceName=WebKitNamedFlowCollection
-] interface DOMNamedFlowCollection {
+ ImplementedAs=DOMNamedFlowCollection
+] interface WebKitNamedFlowCollection {
readonly attribute unsigned long length;
- getter NamedFlow item(unsigned long index);
- NamedFlow namedItem(DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter NamedFlow (DOMString name);
+ getter WebKitNamedFlow item(unsigned long index);
+ WebKitNamedFlow namedItem(DOMString name);
+ [NotEnumerable, ImplementedAs=namedItem] getter WebKitNamedFlow (DOMString name);
};
diff --git a/Source/core/dom/WheelEvent.idl b/Source/core/dom/WheelEvent.idl
index ec923b3..6c8dad4 100644
--- a/Source/core/dom/WheelEvent.idl
+++ b/Source/core/dom/WheelEvent.idl
@@ -36,7 +36,7 @@
void initWebKitWheelEvent([Default=Undefined] optional long wheelDeltaX,
[Default=Undefined] optional long wheelDeltaY,
- [Default=Undefined] optional DOMWindow view,
+ [Default=Undefined] optional Window view,
[Default=Undefined] optional long screenX,
[Default=Undefined] optional long screenY,
[Default=Undefined] optional long clientX,
diff --git a/Source/core/dom/shadow/ContentDistributor.cpp b/Source/core/dom/shadow/ContentDistributor.cpp
index 95db175..b9033b1 100644
--- a/Source/core/dom/shadow/ContentDistributor.cpp
+++ b/Source/core/dom/shadow/ContentDistributor.cpp
@@ -265,7 +265,7 @@
}
}
-bool ContentDistributor::invalidate(Element* host)
+bool ContentDistributor::invalidate(Element* host, Vector<Node*, 8>& nodesNeedingReattach)
{
ASSERT(needsInvalidation());
bool needsReattach = (m_validity == Undetermined) || !m_nodeToInsertionPoint.isEmpty();
@@ -275,7 +275,10 @@
scope->setInsertionPointAssignedTo(0);
const Vector<RefPtr<InsertionPoint> >& insertionPoints = scope->ensureInsertionPointList(root);
for (size_t i = 0; i < insertionPoints.size(); ++i) {
- needsReattach = needsReattach || true;
+ needsReattach = true;
+ for (Node* child = insertionPoints[i]->firstChild(); child; child = child->nextSibling())
+ nodesNeedingReattach.append(child);
+
insertionPoints[i]->clearDistribution();
// After insertionPoint's distribution is invalidated, its reprojection should also be invalidated.
@@ -342,12 +345,10 @@
insertionPoint->setDistribution(distribution);
}
-void ContentDistributor::ensureDistribution(ShadowRoot* shadowRoot)
+void ContentDistributor::ensureDistribution(Element* host)
{
- ASSERT(shadowRoot);
-
Vector<ElementShadow*, 8> elementShadows;
- for (Element* current = shadowRoot->host(); current; current = current->shadowHost()) {
+ for (Element* current = host; current; current = current->shadowHost()) {
ElementShadow* elementShadow = current->shadow();
if (!elementShadow->distributor().needsDistribution())
break;
@@ -362,12 +363,15 @@
void ContentDistributor::invalidateDistribution(Element* host)
{
+ Vector<Node*, 8> nodesNeedingReattach;
bool didNeedInvalidation = needsInvalidation();
- bool needsReattach = didNeedInvalidation ? invalidate(host) : false;
+ bool needsReattach = didNeedInvalidation ? invalidate(host, nodesNeedingReattach) : false;
if (needsReattach && host->attached()) {
for (Node* n = host->firstChild(); n; n = n->nextSibling())
- n->lazyReattach();
+ n->lazyReattachIfAttached();
+ for (size_t i = 0; i < nodesNeedingReattach.size(); ++i)
+ nodesNeedingReattach[i]->lazyReattachIfAttached();
host->setNeedsStyleRecalc();
}
@@ -428,6 +432,14 @@
invalidateDistribution(host);
}
+void ContentDistributor::setNeedsStyleRecalcIfDistributedTo(InsertionPoint* insertionPoint)
+{
+ for (NodeInsertionPointMap::iterator i = m_nodeToInsertionPoint.begin(); i != m_nodeToInsertionPoint.end(); ++i) {
+ if (i->value == insertionPoint)
+ const_cast<Node*>(i->key)->setNeedsStyleRecalc(SyntheticStyleChange);
+ }
+}
+
void ContentDistributor::didShadowBoundaryChange(Element* host)
{
setValidity(Undetermined);
diff --git a/Source/core/dom/shadow/ContentDistributor.h b/Source/core/dom/shadow/ContentDistributor.h
index 91a480c..c90049b 100644
--- a/Source/core/dom/shadow/ContentDistributor.h
+++ b/Source/core/dom/shadow/ContentDistributor.h
@@ -132,12 +132,13 @@
void didShadowBoundaryChange(Element* host);
void didAffectSelector(Element* host, AffectedSelectorMask);
void willAffectSelector(Element* host);
+ void setNeedsStyleRecalcIfDistributedTo(InsertionPoint*);
- static void ensureDistribution(ShadowRoot*);
+ static void ensureDistribution(Element*);
private:
void distribute(Element* host);
- bool invalidate(Element* host);
+ bool invalidate(Element* host, Vector<Node*, 8>& nodesNeedingReattach);
void populate(Node*, ContentDistribution&);
void collectSelectFeatureSetFrom(ShadowRoot*);
@@ -149,7 +150,8 @@
bool needsDistribution() const;
bool needsInvalidation() const { return m_validity != Invalidated; }
- HashMap<const Node*, RefPtr<InsertionPoint> > m_nodeToInsertionPoint;
+ typedef HashMap<const Node*, RefPtr<InsertionPoint> > NodeInsertionPointMap;
+ NodeInsertionPointMap m_nodeToInsertionPoint;
SelectRuleFeatureSet m_selectFeatures;
unsigned m_needsSelectFeatureSet : 1;
unsigned m_validity : 2;
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index ec30bd6..807aeab 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -41,12 +41,6 @@
m_distributor.didShadowBoundaryChange(shadowHost);
ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
- // Existence of shadow roots requires the host and its children to do traversal using ComposedShadowTreeWalker.
- shadowHost->setNeedsShadowTreeWalker();
-
- // FIXME(94905): ShadowHost should be reattached during recalcStyle.
- // Set some flag here and recreate shadow hosts' renderer in
- // Element::recalcStyle.
if (shadowHost->attached())
shadowHost->lazyReattach();
@@ -80,7 +74,7 @@
void ElementShadow::attach()
{
- ContentDistributor::ensureDistribution(youngestShadowRoot());
+ ContentDistributor::ensureDistribution(host());
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
if (!root->attached())
diff --git a/Source/core/dom/shadow/ElementShadow.h b/Source/core/dom/shadow/ElementShadow.h
index 914471b..fc7c7b9 100644
--- a/Source/core/dom/shadow/ElementShadow.h
+++ b/Source/core/dom/shadow/ElementShadow.h
@@ -99,6 +99,11 @@
return 0;
}
+inline void Element::ensureDistribution()
+{
+ ContentDistributor::ensureDistribution(this);
+}
+
inline ElementShadow* ElementShadow::containingShadow() const
{
if (ShadowRoot* parentRoot = host()->containingShadowRoot())
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 8e905c7..e0ef0b2 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -45,33 +45,44 @@
: HTMLElement(tagName, document, CreateInsertionPoint)
, m_registeredWithShadowRoot(false)
{
+ setHasCustomStyleCallbacks();
}
InsertionPoint::~InsertionPoint()
{
}
-void InsertionPoint::attach()
+void InsertionPoint::attach(const AttachContext& context)
{
if (ShadowRoot* shadowRoot = containingShadowRoot())
- ContentDistributor::ensureDistribution(shadowRoot);
+ shadowRoot->host()->ensureDistribution();
for (size_t i = 0; i < m_distribution.size(); ++i) {
if (!m_distribution.at(i)->attached())
- m_distribution.at(i)->attach();
+ m_distribution.at(i)->attach(context);
}
- HTMLElement::attach();
+ HTMLElement::attach(context);
}
-void InsertionPoint::detach()
+void InsertionPoint::detach(const AttachContext& context)
{
if (ShadowRoot* shadowRoot = containingShadowRoot())
- ContentDistributor::ensureDistribution(shadowRoot);
+ shadowRoot->host()->ensureDistribution();
for (size_t i = 0; i < m_distribution.size(); ++i)
- m_distribution.at(i)->detach();
+ m_distribution.at(i)->detach(context);
- HTMLElement::detach();
+ HTMLElement::detach(context);
+}
+
+void InsertionPoint::willRecalcStyle(StyleChange change)
+{
+ if (change < Inherit)
+ return;
+ if (ShadowRoot* shadowRoot = containingShadowRoot()) {
+ shadowRoot->host()->ensureDistribution();
+ shadowRoot->owner()->distributor().setNeedsStyleRecalcIfDistributedTo(this);
+ }
}
bool InsertionPoint::shouldUseFallbackElements() const
@@ -101,7 +112,7 @@
PassRefPtr<NodeList> InsertionPoint::getDistributedNodes() const
{
if (ShadowRoot* shadowRoot = containingShadowRoot())
- ContentDistributor::ensureDistribution(shadowRoot);
+ shadowRoot->host()->ensureDistribution();
Vector<RefPtr<Node> > nodes;
@@ -206,8 +217,9 @@
while (current) {
if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
+ shadow->host()->ensureDistribution();
if (ShadowRoot* root = current->containingShadowRoot())
- ContentDistributor::ensureDistribution(root);
+ root->host()->ensureDistribution();
if (InsertionPoint* insertedTo = shadow->distributor().findInsertionPointFor(projectedNode)) {
current = insertedTo;
insertionPoint = insertedTo;
@@ -235,7 +247,7 @@
while (true) {
if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
if (ShadowRoot* root = current->containingShadowRoot())
- ContentDistributor::ensureDistribution(root);
+ root->host()->ensureDistribution();
if (InsertionPoint* insertedTo = shadow->distributor().findInsertionPointFor(node)) {
current = insertedTo;
results.append(insertedTo);
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index cbc5afb..9348f23 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -72,8 +72,8 @@
bool resetStyleInheritance() const;
void setResetStyleInheritance(bool);
- virtual void attach();
- virtual void detach();
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
bool shouldUseFallbackElements() const;
@@ -95,7 +95,7 @@
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool isInsertionPointNode() const OVERRIDE { return true; }
+ virtual void willRecalcStyle(StyleChange) OVERRIDE;
private:
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index d409799..b3f02e9 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -98,6 +98,15 @@
removeDetachedChildren();
}
+ShadowRoot* ShadowRoot::bindingsOlderShadowRoot() const
+{
+ ShadowRoot* older = olderShadowRoot();
+ while (older && !older->shouldExposeToBindings())
+ older = older->olderShadowRoot();
+ ASSERT(!older || older->shouldExposeToBindings());
+ return older;
+}
+
PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
{
ec = DATA_CLONE_ERR;
@@ -139,16 +148,24 @@
// ShadowRoot doesn't support custom callbacks.
ASSERT(!hasCustomStyleCallbacks());
+ StyleResolver* styleResolver = document()->styleResolver();
+ styleResolver->pushParentShadowRoot(this);
+
+ if (!attached()) {
+ attach();
+ // attach recalculates the style for all children. No need to do it twice.
+ clearNeedsStyleRecalc();
+ clearChildNeedsStyleRecalc();
+ return;
+ }
+
// When we're set to lazyAttach we'll have a FullStyleChange and we'll need
// to promote the change to a Force for all our descendants so they get a
// recalc and will attach.
if (styleChangeType() == FullStyleChange)
change = Force;
- StyleResolver* styleResolver = document()->styleResolver();
- styleResolver->pushParentShadowRoot(this);
-
- for (Node* child = lastChild(); child; child = child->previousSibling()) {
+ for (Node* child = firstChild(); child; child = child->nextSibling()) {
if (child->isElementNode())
toElement(child)->recalcStyle(change);
else if (child->isTextNode())
@@ -198,11 +215,11 @@
setNeedsStyleRecalc();
}
-void ShadowRoot::attach()
+void ShadowRoot::attach(const AttachContext& context)
{
StyleResolver* styleResolver = document()->styleResolver();
styleResolver->pushParentShadowRoot(this);
- DocumentFragment::attach();
+ DocumentFragment::attach(context);
styleResolver->popParentShadowRoot(this);
}
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 792e95f..203e2b6 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -75,10 +75,13 @@
ShadowRoot* youngerShadowRoot() const { return prev(); }
ShadowRoot* olderShadowRoot() const { return next(); }
+ ShadowRoot* bindingsOlderShadowRoot() const;
+ bool shouldExposeToBindings() const { return type() == AuthorShadowRoot; }
+
bool isYoungest() const { return !youngerShadowRoot(); }
bool isOldest() const { return !olderShadowRoot(); }
- virtual void attach();
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
diff --git a/Source/core/dom/shadow/ShadowRoot.idl b/Source/core/dom/shadow/ShadowRoot.idl
index 39488df..6a6e07e 100644
--- a/Source/core/dom/shadow/ShadowRoot.idl
+++ b/Source/core/dom/shadow/ShadowRoot.idl
@@ -30,6 +30,7 @@
readonly attribute Element activeElement;
attribute boolean applyAuthorStyles;
attribute boolean resetStyleInheritance;
+ [EnabledAtRuntime=experimentalShadowDOM, ImplementedAs=bindingsOlderShadowRoot] readonly attribute ShadowRoot olderShadowRoot;
[TreatNullAs=NullString, DeliverCustomElementCallbacks, PerWorldBindings, ActivityLog=SetterForIsolatedWorlds, SetterRaisesException] attribute DOMString innerHTML;