Merge from Chromium at DEPS revision 232870
This commit was generated by merge_to_master.py.
Change-Id: Ib9d83ad19b18b768c3ab444a5de7965a594872e7
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 676aac1..efe778d 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -63,16 +63,16 @@
static const char insertBeforeMethodName[] = "insertBefore";
static const char replaceChildMethodName[] = "replaceChild";
-static void collectChildrenAndRemoveFromOldParent(Node* node, NodeVector& nodes, ExceptionState& es)
+static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes, ExceptionState& es)
{
- if (node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
- nodes.append(node);
- if (ContainerNode* oldParent = node->parentNode())
- oldParent->removeChild(node, es);
+ if (node.nodeType() != Node::DOCUMENT_FRAGMENT_NODE) {
+ nodes.append(&node);
+ if (ContainerNode* oldParent = node.parentNode())
+ oldParent->removeChild(&node, es);
return;
}
getChildNodes(node, nodes);
- toContainerNode(node)->removeChildren();
+ toContainerNode(node).removeChildren();
}
void ContainerNode::removeDetachedChildren()
@@ -81,14 +81,14 @@
for (Node* child = firstChild(); child; child = child->nextSibling())
child->updateAncestorConnectedSubframeCountForRemoval();
}
- // FIXME: We should be able to ASSERT(!confusingAndOftenMisusedAttached()) here: https://bugs.webkit.org/show_bug.cgi?id=107801
+ ASSERT(needsAttach());
removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
}
-void ContainerNode::parserTakeAllChildrenFrom(ContainerNode* oldParent)
+void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
{
- while (RefPtr<Node> child = oldParent->firstChild()) {
- oldParent->parserRemoveChild(*child);
+ while (RefPtr<Node> child = oldParent.firstChild()) {
+ oldParent.parserRemoveChild(*child);
treeScope().adoptIfNeeded(*child);
parserAppendChild(child.get());
}
@@ -100,32 +100,32 @@
removeDetachedChildren();
}
-static inline bool isChildTypeAllowed(ContainerNode* newParent, Node* child)
+static inline bool isChildTypeAllowed(ContainerNode& newParent, Node& child)
{
- if (!child->isDocumentFragment())
- return newParent->childTypeAllowed(child->nodeType());
+ if (!child.isDocumentFragment())
+ return newParent.childTypeAllowed(child.nodeType());
- for (Node* node = child->firstChild(); node; node = node->nextSibling()) {
- if (!newParent->childTypeAllowed(node->nodeType()))
+ for (Node* node = child.firstChild(); node; node = node->nextSibling()) {
+ if (!newParent.childTypeAllowed(node->nodeType()))
return false;
}
return true;
}
-static inline bool isInTemplateContent(const Node* node)
+static inline bool isInTemplateContent(const Node& node)
{
- Document& document = node->document();
+ const Document& document = node.document();
return document == document.templateDocument();
}
-static inline bool containsConsideringHostElements(const Node* newChild, const Node* newParent)
+static inline bool containsConsideringHostElements(const Node& newChild, const Node& newParent)
{
- return (newParent->isInShadowTree() || isInTemplateContent(newParent))
- ? newChild->containsIncludingHostElements(newParent)
- : newChild->contains(newParent);
+ return (newParent.isInShadowTree() || isInTemplateContent(newParent))
+ ? newChild.containsIncludingHostElements(newParent)
+ : newChild.contains(&newParent);
}
-static inline bool checkAcceptChild(ContainerNode* newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
+static inline bool checkAcceptChild(ContainerNode& newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
{
// Not mentioned in spec: throw NotFoundError if newChild is null
if (!newChild) {
@@ -134,10 +134,10 @@
}
// Use common case fast path if possible.
- if ((newChild->isElementNode() || newChild->isTextNode()) && newParent->isElementNode()) {
- ASSERT(!newParent->isDocumentTypeNode());
- ASSERT(isChildTypeAllowed(newParent, newChild));
- if (containsConsideringHostElements(newChild, newParent)) {
+ if ((newChild->isElementNode() || newChild->isTextNode()) && newParent.isElementNode()) {
+ ASSERT(!newParent.isDocumentTypeNode());
+ ASSERT(isChildTypeAllowed(newParent, *newChild));
+ if (containsConsideringHostElements(*newChild, newParent)) {
es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
return false;
}
@@ -151,30 +151,30 @@
return false;
}
- if (containsConsideringHostElements(newChild, newParent)) {
+ if (containsConsideringHostElements(*newChild, newParent)) {
es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
return false;
}
- if (oldChild && newParent->isDocumentNode()) {
- if (!toDocument(newParent)->canReplaceChild(newChild, oldChild)) {
+ if (oldChild && newParent.isDocumentNode()) {
+ if (!toDocument(newParent).canReplaceChild(*newChild, *oldChild)) {
// FIXME: Adjust 'Document::canReplaceChild' to return some additional detail (or an error message).
es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "ContainerNode"));
return false;
}
- } else if (!isChildTypeAllowed(newParent, newChild)) {
- es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent->nodeName() + "'."));
+ } else if (!isChildTypeAllowed(newParent, *newChild)) {
+ es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "Nodes of type '" + newChild->nodeName() + "' may not be inserted inside nodes of type '" + newParent.nodeName() + "'."));
return false;
}
return true;
}
-static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es)
+static inline bool checkAcceptChildGuaranteedNodeTypes(ContainerNode& newParent, Node& newChild, const char* method, ExceptionState& es)
{
- ASSERT(!newParent->isDocumentTypeNode());
+ ASSERT(!newParent.isDocumentTypeNode());
ASSERT(isChildTypeAllowed(newParent, newChild));
- if (newChild->contains(newParent)) {
+ if (newChild.contains(&newParent)) {
es.throwDOMException(HierarchyRequestError, ExceptionMessages::failedToExecute(method, "Node", "The new child element contains the parent."));
return false;
}
@@ -182,14 +182,14 @@
return true;
}
-static inline bool checkAddChild(ContainerNode* newParent, Node* newChild, const char* method, ExceptionState& es)
+static inline bool checkAddChild(ContainerNode& newParent, Node* newChild, const char* method, ExceptionState& es)
{
return checkAcceptChild(newParent, newChild, 0, method, es);
}
-static inline bool checkReplaceChild(ContainerNode* newParent, Node* newChild, Node* oldChild, const char* method, ExceptionState& es)
+static inline bool checkReplaceChild(ContainerNode& newParent, Node* newChild, Node& oldChild, const char* method, ExceptionState& es)
{
- return checkAcceptChild(newParent, newChild, oldChild, method, es);
+ return checkAcceptChild(newParent, newChild, &oldChild, method, es);
}
void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& es)
@@ -207,8 +207,9 @@
}
// Make sure adding the new child is OK.
- if (!checkAddChild(this, newChild.get(), insertBeforeMethodName, es))
+ if (!checkAddChild(*this, newChild.get(), insertBeforeMethodName, es))
return;
+ ASSERT(newChild);
// NotFoundError: Raised if refChild is not a child of this node
if (refChild->parentNode() != this) {
@@ -222,14 +223,14 @@
RefPtr<Node> next = refChild;
NodeVector targets;
- collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+ collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
if (es.hadException())
return;
if (targets.isEmpty())
return;
// We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
- if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), insertBeforeMethodName, es))
+ if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, insertBeforeMethodName, es))
return;
InspectorInstrumentation::willInsertDOMNode(this);
@@ -283,27 +284,26 @@
newChild.setNextSibling(&nextChild);
}
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node* nextChild)
+void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChild)
{
ASSERT(newChild);
- ASSERT(nextChild);
- ASSERT(nextChild->parentNode() == this);
+ ASSERT(nextChild.parentNode() == this);
ASSERT(!newChild->isDocumentFragment());
ASSERT(!hasTagName(HTMLNames::templateTag));
- if (nextChild->previousSibling() == newChild || nextChild == newChild) // nothing to do
+ if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
return;
if (document() != newChild->document())
document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
- insertBeforeCommon(*nextChild, *newChild);
+ insertBeforeCommon(nextChild, *newChild);
newChild->updateAncestorConnectedSubframeCountForInsertion();
ChildListMutationScope(*this).childAdded(*newChild);
- childrenChanged(true, newChild->previousSibling(), nextChild, 1);
+ childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
ChildNodeInsertionNotifier(*this).notify(*newChild);
}
@@ -325,7 +325,7 @@
}
// Make sure replacing the old child with the new is ok
- if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+ if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
return;
// NotFoundError: Raised if oldChild is not a child of this node.
@@ -348,16 +348,16 @@
return;
// Does this one more time because removeChild() fires a MutationEvent.
- if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+ if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
return;
NodeVector targets;
- collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+ collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
if (es.hadException())
return;
// Does this yet another check because collectChildrenAndRemoveFromOldParent() fires a MutationEvent.
- if (!checkReplaceChild(this, newChild.get(), oldChild, replaceChildMethodName, es))
+ if (!checkReplaceChild(*this, newChild.get(), *oldChild, replaceChildMethodName, es))
return;
InspectorInstrumentation::willInsertDOMNode(this);
@@ -399,14 +399,14 @@
ChildListMutationScope(*child.parentNode()).willRemoveChild(child);
child.notifyMutationObserversNodeWillDetach();
dispatchChildRemovalEvents(child);
- child.document().nodeWillBeRemoved(&child); // e.g. mutation event listener can create a new range.
+ child.document().nodeWillBeRemoved(child); // e.g. mutation event listener can create a new range.
ChildFrameDisconnector(child).disconnect();
}
static void willRemoveChildren(ContainerNode& container)
{
NodeVector children;
- getChildNodes(&container, children);
+ getChildNodes(container, children);
ChildListMutationScope mutation(container);
for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
@@ -540,7 +540,7 @@
{
// Removing focus can cause frames to load, either via events (focusout, blur)
// or widget updates (e.g., for <embed>).
- SubframeLoadingDisabler disabler(this);
+ SubframeLoadingDisabler disabler(*this);
// Exclude this node when looking for removed focusedElement since only
// children will be removed.
@@ -583,14 +583,15 @@
ASSERT(refCount() || parentOrShadowHostNode());
// Make sure adding the new child is ok
- if (!checkAddChild(this, newChild.get(), appendChildMethodName, es))
+ if (!checkAddChild(*this, newChild.get(), appendChildMethodName, es))
return;
+ ASSERT(newChild);
if (newChild == m_lastChild) // nothing to do
return;
NodeVector targets;
- collectChildrenAndRemoveFromOldParent(newChild.get(), targets, es);
+ collectChildrenAndRemoveFromOldParent(*newChild, targets, es);
if (es.hadException())
return;
@@ -598,7 +599,7 @@
return;
// We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events.
- if (!checkAcceptChildGuaranteedNodeTypes(this, newChild.get(), appendChildMethodName, es))
+ if (!checkAcceptChildGuaranteedNodeTypes(*this, *newChild, appendChildMethodName, es))
return;
InspectorInstrumentation::willInsertDOMNode(this);
@@ -955,13 +956,13 @@
// dispatch pre-removal mutation events
if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
- NodeChildRemovalTracker scope(&child);
+ NodeChildRemovalTracker scope(child);
c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemoved, true, c->parentNode()));
}
// dispatch the DOMNodeRemovedFromDocument event to all descendants
if (c->inDocument() && document->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER)) {
- NodeChildRemovalTracker scope(&child);
+ NodeChildRemovalTracker scope(child);
for (; c; c = NodeTraversal::next(c.get(), &child))
c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeRemovedFromDocument, false));
}
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 16d0942..e7d067c 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -106,8 +106,8 @@
// However, arbitrary code may be run by beforeload handlers.
void parserAppendChild(PassRefPtr<Node>);
void parserRemoveChild(Node&);
- void parserInsertBefore(PassRefPtr<Node> newChild, Node* refChild);
- void parserTakeAllChildrenFrom(ContainerNode*);
+ void parserInsertBefore(PassRefPtr<Node> newChild, Node& refChild);
+ void parserTakeAllChildrenFrom(ContainerNode&);
void removeChildren();
@@ -235,10 +235,10 @@
const int initialNodeVectorSize = 11;
typedef Vector<RefPtr<Node>, initialNodeVectorSize> NodeVector;
-inline void getChildNodes(Node* node, NodeVector& nodes)
+inline void getChildNodes(Node& node, NodeVector& nodes)
{
ASSERT(!nodes.size());
- for (Node* child = node->firstChild(); child; child = child->nextSibling())
+ for (Node* child = node.firstChild(); child; child = child->nextSibling())
nodes.append(child);
}
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index a0b7dbe..c3cd3bf 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -313,7 +313,7 @@
{
// Must disable frame loading in the subtree so an unload handler cannot
// insert more frames and create loaded frames in detached subtrees.
- SubframeLoadingDisabler disabler(&m_root);
+ SubframeLoadingDisabler disabler(m_root);
for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
diff --git a/Source/core/dom/ContextFeatures.h b/Source/core/dom/ContextFeatures.h
index 231ee04..b3f309f 100644
--- a/Source/core/dom/ContextFeatures.h
+++ b/Source/core/dom/ContextFeatures.h
@@ -27,7 +27,7 @@
#ifndef ContextFeatures_h
#define ContextFeatures_h
-#include "core/platform/RefCountedSupplement.h"
+#include "platform/RefCountedSupplement.h"
namespace WebCore {
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 2f97a3f..ddbf569 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -174,6 +174,7 @@
#include "platform/network/HTTPParsers.h"
#include "platform/text/PlatformLocale.h"
#include "platform/text/SegmentedString.h"
+#include "weborigin/OriginAccessEntry.h"
#include "weborigin/SchemeRegistry.h"
#include "weborigin/SecurityOrigin.h"
#include "wtf/CurrentTime.h"
@@ -406,6 +407,7 @@
, m_gotoAnchorNeededAfterStylesheetsLoad(false)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
+ , m_containsPlugins(false)
, m_ignoreDestructiveWriteCount(0)
, m_titleSetExplicitly(false)
, m_markers(adoptPtr(new DocumentMarkerController))
@@ -487,20 +489,9 @@
m_lifecyle.advanceTo(DocumentLifecycle::Inactive);
}
-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;
-}
-
Document::~Document()
{
- ASSERT(!renderer());
+ ASSERT(!renderView());
ASSERT(m_ranges.isEmpty());
ASSERT(!m_parentTreeScope);
ASSERT(!hasGuardRefCount());
@@ -1022,7 +1013,7 @@
PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderer())
+ if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !isActive())
return 0;
updateStyleIfNeeded();
@@ -1197,7 +1188,7 @@
Element* Document::elementFromPoint(int x, int y) const
{
- if (!renderer())
+ if (!isActive())
return 0;
return TreeScope::elementFromPoint(x, y);
@@ -1205,7 +1196,7 @@
PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
- if (!renderer())
+ if (!isActive())
return 0;
LayoutPoint localPoint;
RenderObject* renderer = rendererFromPoint(this, x, y, &localPoint);
@@ -1543,7 +1534,7 @@
void Document::unscheduleStyleRecalc()
{
- ASSERT(!confusingAndOftenMisusedAttached() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
+ ASSERT(!isActive() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
m_styleRecalcTimer.stop();
}
@@ -1704,9 +1695,9 @@
if (change == Force || (change >= Inherit && shouldDisplaySeamlesslyWithParent())) {
m_hasNodesWithPlaceholderStyle = false;
RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
- StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderer()->style());
+ StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderView()->style());
if (localChange != NoChange)
- renderer()->setStyle(documentStyle.release());
+ renderView()->setStyle(documentStyle.release());
}
inheritHtmlAndBodyElementStyles(change);
@@ -1788,7 +1779,7 @@
updateStyleIfNeeded();
// Only do a layout if changes have occurred that make it necessary.
- if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
+ if (frameView && isActive() && (frameView->layoutPending() || renderView()->needsLayout()))
frameView->layout();
if (frameView)
@@ -1957,7 +1948,7 @@
void Document::attach(const AttachContext& context)
{
- ASSERT(!confusingAndOftenMisusedAttached());
+ ASSERT(m_lifecyle.state() == DocumentLifecycle::Inactive);
ASSERT(!m_axObjectCache || this != topDocument());
m_renderView = new RenderView(this);
@@ -1976,10 +1967,9 @@
void Document::detach(const AttachContext& context)
{
+ ASSERT(isActive());
m_lifecyle.advanceTo(DocumentLifecycle::Stopping);
- ASSERT(confusingAndOftenMisusedAttached());
-
if (page())
page()->documentDetached(this);
@@ -1996,20 +1986,14 @@
if (svgExtensions())
accessSVGExtensions()->pauseAnimations();
- RenderView* renderView = m_renderView;
+ m_renderView->setIsInWindow(false);
- documentWillBecomeInactive();
-
+ // FIXME: How can the frame be null here?
if (m_frame) {
- FrameView* view = m_frame->view();
- if (view)
+ if (FrameView* view = m_frame->view())
view->detachCustomScrollbars();
}
- // indicate destruction mode, i.e. confusingAndOftenMisusedAttached() but renderer == 0
- setRenderer(0);
- m_renderView = 0;
-
m_hoverNode = 0;
m_focusedElement = 0;
m_activeElement = 0;
@@ -2022,9 +2006,6 @@
clearStyleResolver();
- if (renderView)
- renderView->destroy();
-
if (m_touchEventTargets && m_touchEventTargets->size() && parentDocument())
parentDocument()->didRemoveEventTargetNode(this);
@@ -2046,9 +2027,8 @@
{
disconnectDescendantFrames();
- // The process of disconnecting descendant frames could have already
- // detached us.
- if (!confusingAndOftenMisusedAttached())
+ // The process of disconnecting descendant frames could have already detached us.
+ if (!isActive())
return;
if (DOMWindow* window = this->domWindow())
@@ -2081,7 +2061,7 @@
// If the renderer is gone then we are in the process of destruction.
// This method will be called before m_frame = 0.
- if (!topDocument()->renderer())
+ if (!topDocument()->isActive())
return 0;
return topDocument()->m_axObjectCache.get();
@@ -2099,7 +2079,7 @@
Document* topDocument = this->topDocument();
// If the document has already been detached, do not make a new axObjectCache.
- if (!topDocument->renderer())
+ if (!topDocument->isActive())
return 0;
ASSERT(topDocument == this || !m_axObjectCache);
@@ -2112,8 +2092,8 @@
{
m_visuallyOrdered = true;
// FIXME: How is possible to not have a renderer here?
- if (renderer())
- renderer()->style()->setRTLOrdering(VisualOrder);
+ if (renderView())
+ renderView()->style()->setRTLOrdering(VisualOrder);
setNeedsStyleRecalc();
}
@@ -2365,7 +2345,7 @@
return;
}
- RenderObject* renderObject = renderer();
+ RenderView* renderView = this->renderView();
// We used to force a synchronous display and flush here. This really isn't
// necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
@@ -2375,25 +2355,25 @@
updateStyleIfNeeded();
// Always do a layout after loading if needed.
- if (view() && renderObject && (!renderObject->firstChild() || renderObject->needsLayout()))
+ if (view() && renderView && (!renderView->firstChild() || renderView->needsLayout()))
view()->layout();
}
m_loadEventProgress = LoadEventCompleted;
- if (f && renderObject && AXObjectCache::accessibilityEnabled()) {
+ if (f && renderView && AXObjectCache::accessibilityEnabled()) {
// The AX cache may have been cleared at this point, but we need to make sure it contains an
// 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.
if (AXObjectCache* cache = axObjectCache()) {
- cache->getOrCreate(renderObject);
+ cache->getOrCreate(renderView);
if (this == topDocument()) {
- cache->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
+ cache->postNotification(renderView, 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);
+ cache->postNotification(renderView, AXObjectCache::AXLayoutComplete, true);
}
}
}
@@ -2983,15 +2963,13 @@
MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
{
- ASSERT(!renderer() || renderer()->isRenderView());
-
// RenderView::hitTest causes a layout, and we don't want to hit that until the first
// layout because until then, there is nothing shown on the screen - the user can't
// have intentionally clicked on something belonging to this page. Furthermore,
// mousemove events before the first layout should not lead to a premature layout()
// happening, which could show a flash of white.
// See also the similar code in EventHandler::hitTestResultAtPoint.
- if (!renderer() || !view() || !view()->didFirstLayout())
+ if (!isActive() || !view() || !view()->didFirstLayout())
return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()));
HitTestResult result(documentPoint);
@@ -3031,13 +3009,9 @@
return false;
}
-bool Document::canReplaceChild(Node* newChild, Node* oldChild)
+bool Document::canReplaceChild(Node& newChild, Node& oldChild)
{
- if (!oldChild)
- // ContainerNode::replaceChild will raise a NotFoundError.
- return true;
-
- if (oldChild->nodeType() == newChild->nodeType())
+ if (oldChild.nodeType() == newChild.nodeType())
return true;
int numDoctypes = 0;
@@ -3062,8 +3036,8 @@
}
// Then, see how many doctypes and elements might be added by the new child.
- if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
- for (Node* c = newChild->firstChild(); c; c = c->nextSibling()) {
+ if (newChild.nodeType() == DOCUMENT_FRAGMENT_NODE) {
+ for (Node* c = newChild.firstChild(); c; c = c->nextSibling()) {
switch (c->nodeType()) {
case ATTRIBUTE_NODE:
case CDATA_SECTION_NODE:
@@ -3086,7 +3060,7 @@
}
}
} else {
- switch (newChild->nodeType()) {
+ switch (newChild.nodeType()) {
case ATTRIBUTE_NODE:
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
@@ -3172,7 +3146,7 @@
{
// Don't bother updating, since we haven't loaded all our style info yet
// and haven't calculated the style selector for the first time.
- if (!confusingAndOftenMisusedAttached() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
+ if (!isActive() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
m_styleResolver.clear();
return;
}
@@ -3509,19 +3483,19 @@
HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
for (Node* n = container->firstChild(); n; n = n->nextSibling())
- (*it)->nodeWillBeRemoved(n);
+ (*it)->nodeWillBeRemoved(*n);
}
if (Frame* frame = this->frame()) {
for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
- frame->eventHandler().nodeWillBeRemoved(n);
- frame->selection().nodeWillBeRemoved(n);
- frame->page()->dragCaretController().nodeWillBeRemoved(n);
+ frame->eventHandler().nodeWillBeRemoved(*n);
+ frame->selection().nodeWillBeRemoved(*n);
+ frame->page()->dragCaretController().nodeWillBeRemoved(*n);
}
}
}
-void Document::nodeWillBeRemoved(Node* n)
+void Document::nodeWillBeRemoved(Node& n)
{
HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
@@ -3773,42 +3747,15 @@
return;
}
- // Both NS and IE specify that changing the domain is only allowed when
- // the new domain is a suffix of the old domain.
-
- // If the new domain is the same as the old domain, still call
- // securityOrigin()->setDomainForDOM. This will change the
- // security check behavior. For example, if a page loaded on port 8000
- // assigns its current domain using document.domain, the page will
- // allow other pages loaded on different ports in the same domain that
- // have also assigned to access this page.
- if (equalIgnoringCase(domain(), newDomain)) {
- securityOrigin()->setDomainFromDOM(newDomain);
- if (m_frame)
- m_frame->script().updateSecurityOrigin();
- return;
- }
-
- int oldLength = domain().length();
- int newLength = newDomain.length();
- String exceptionMessage = ExceptionMessages::failedToSet("domain", "Document", "'" + newDomain + "' is not a suffix of '" + domain() + "'.");
- // e.g. newDomain = subdomain.www.example.com (25) and domain() = www.example.com (15)
- if (newLength >= oldLength) {
+ String exceptionMessage = ExceptionMessages::failedToSet("domain", "Document", "'" + newDomain + "' is not a suffix of '" + domain() + "'.");
+ if (newDomain.isEmpty()) {
es.throwSecurityError(exceptionMessage);
return;
}
- String test = domain();
- // Check that it's a complete suffix, not e.g. "ample.com"
- if (test[oldLength - newLength - 1] != '.') {
- es.throwSecurityError(exceptionMessage);
- return;
- }
-
- // Now test is "example.com" from domain()
- // and we check that it's the same thing as newDomain
- test.remove(0, oldLength - newLength);
- if (test != newDomain) {
+ OriginAccessEntry::IPAddressSetting ipAddressSetting = settings() && settings()->treatIPAddressAsDomain() ? OriginAccessEntry::TreatIPAddressAsDomain : OriginAccessEntry::TreatIPAddressAsIPAddress;
+ OriginAccessEntry accessEntry(securityOrigin()->protocol(), newDomain, OriginAccessEntry::AllowSubdomains, ipAddressSetting);
+ if (!accessEntry.matchesOrigin(*securityOrigin())) {
es.throwSecurityError(exceptionMessage);
return;
}
@@ -4030,12 +3977,6 @@
return completeURL(url, m_baseURL);
}
-void Document::documentWillBecomeInactive()
-{
- if (renderer())
- renderView()->setIsInWindow(false);
-}
-
// Support for Javascript execCommand, and related methods
static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index 12e5c3f..00a32b9 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -312,7 +312,7 @@
*/
PassRefPtr<NodeList> nodesFromRect(int centerX, int centerY,
unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding,
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent) const;
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent) const;
Element* elementFromPoint(int x, int y) const;
PassRefPtr<Range> caretRangeFromPoint(int x, int y);
@@ -485,6 +485,7 @@
void prepareForDestruction();
RenderView* renderView() const { return m_renderView; }
+ void clearRenderView() { m_renderView = 0; }
AXObjectCache* existingAXObjectCache() const;
AXObjectCache* axObjectCache() const;
@@ -648,8 +649,8 @@
// nodeChildrenWillBeRemoved is used when removing all node children at once.
void nodeChildrenWillBeRemoved(ContainerNode*);
// nodeWillBeRemoved is only safe when removing one node at a time.
- void nodeWillBeRemoved(Node*);
- bool canReplaceChild(Node* newChild, Node* oldChild);
+ void nodeWillBeRemoved(Node&);
+ bool canReplaceChild(Node& newChild, Node& oldChild);
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
@@ -840,8 +841,6 @@
void finishedParsing();
- void documentWillBecomeInactive();
-
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
@@ -884,6 +883,9 @@
bool processingLoadEvent() const { return m_loadEventProgress == LoadEventInProgress; }
bool loadEventFinished() const { return m_loadEventProgress >= LoadEventCompleted; }
+ void setContainsPlugins() { m_containsPlugins = true; }
+ bool containsPlugins() const { return m_containsPlugins; }
+
virtual bool isContextThread() const;
virtual bool isJSExecutionForbidden() const { return false; }
@@ -998,6 +1000,8 @@
DocumentLifecycleNotifier& lifecycleNotifier();
bool isActive() const { return m_lifecyle.state() == DocumentLifecycle::Active; }
+ bool isStopping() const { return m_lifecyle.state() == DocumentLifecycle::Stopping; }
+ bool isStopped() const { return m_lifecyle.state() == DocumentLifecycle::Stopped; }
enum HttpRefreshType {
HttpRefreshFromHeader,
@@ -1191,6 +1195,7 @@
bool m_haveExplicitlyDisabledDNSPrefetch;
bool m_containsValidityStyleRules;
bool m_updateFocusAppearanceRestoresSelection;
+ bool m_containsPlugins;
// http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
unsigned m_ignoreDestructiveWriteCount;
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 41c734a..36cdb70 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -72,6 +72,7 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
#include "core/editing/htmlediting.h"
+#include "core/editing/markup.h"
#include "core/events/EventDispatcher.h"
#include "core/events/FocusEvent.h"
#include "core/frame/ContentSecurityPolicy.h"
@@ -86,6 +87,7 @@
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLOptionsCollection.h"
#include "core/html/HTMLTableRowsCollection.h"
+#include "core/html/HTMLTemplateElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
@@ -960,7 +962,7 @@
void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
- if (ElementShadow* parentElementShadow = shadowOfParentForDistribution(this)) {
+ if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*this)) {
if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow, name, newValue))
parentElementShadow->setNeedsDistributionRecalc();
}
@@ -1272,14 +1274,7 @@
if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
- if (Element* before = pseudoElement(BEFORE))
- before->insertedInto(insertionPoint);
-
- if (Element* after = pseudoElement(AFTER))
- after->insertedInto(insertionPoint);
-
- if (Element* backdrop = pseudoElement(BACKDROP))
- backdrop->insertedInto(insertionPoint);
+ ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
if (!insertionPoint->isInTreeScope())
return InsertionDone;
@@ -1317,15 +1312,7 @@
{
bool wasInDocument = insertionPoint->inDocument();
- if (Element* before = pseudoElement(BEFORE))
- before->removedFrom(insertionPoint);
-
- if (Element* after = pseudoElement(AFTER))
- after->removedFrom(insertionPoint);
-
- if (Element* backdrop = pseudoElement(BACKDROP))
- backdrop->removedFrom(insertionPoint);
- document().removeFromTopLayer(this);
+ ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
if (containsFullScreenElement())
setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
@@ -1360,6 +1347,8 @@
CustomElement::didLeaveDocument(this, insertionPoint->document());
}
+ document().removeFromTopLayer(this);
+
if (hasRareData())
elementRareData()->setIsInCanvasSubtree(false);
}
@@ -1516,7 +1505,7 @@
}
// Active InsertionPoints have no renderers so they never need to go through a recalc.
- if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(this))
+ if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(*this))
change = recalcOwnStyle(change);
// If we reattached we don't need to recalc the style of our descendants anymore.
@@ -1678,7 +1667,7 @@
void Element::didAffectSelector(AffectedSelectorMask mask)
{
setNeedsStyleRecalc();
- if (ElementShadow* elementShadow = shadowOfParentForDistribution(this))
+ if (ElementShadow* elementShadow = shadowWhereNodeCanBeDistributed(*this))
elementShadow->didAffectSelector(mask);
}
@@ -2202,6 +2191,50 @@
dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().domWindow(), 0, newFocusedElement)));
}
+String Element::innerHTML() const
+{
+ return createMarkup(this, ChildrenOnly);
+}
+
+String Element::outerHTML() const
+{
+ return createMarkup(this);
+}
+
+void Element::setInnerHTML(const String& html, ExceptionState& es)
+{
+ if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", es)) {
+ ContainerNode* container = this;
+ if (hasTagName(templateTag))
+ container = toHTMLTemplateElement(this)->content();
+ replaceChildrenWithFragment(container, fragment.release(), es);
+ }
+}
+
+void Element::setOuterHTML(const String& html, ExceptionState& es)
+{
+ Node* p = parentNode();
+ if (!p || !p->isElementNode()) {
+ es.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ return;
+ }
+ RefPtr<Element> parent = toElement(p);
+ RefPtr<Node> prev = previousSibling();
+ RefPtr<Node> next = nextSibling();
+
+ RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", es);
+ if (es.hadException())
+ return;
+
+ parent->replaceChild(fragment.release(), this, es);
+ RefPtr<Node> node = next ? next->previousSibling() : 0;
+ if (!es.hadException() && node && node->isTextNode())
+ mergeWithNextTextNode(node.release(), es);
+
+ if (!es.hadException() && prev && prev->isTextNode())
+ mergeWithNextTextNode(prev.release(), es);
+}
+
String Element::innerText()
{
// We need to update layout, since plainText uses line boxes in the render tree.
@@ -2580,8 +2613,11 @@
RefPtr<PseudoElement> element = PseudoElement::create(this, pseudoId);
if (pseudoId == BACKDROP)
document().addToTopLayer(element.get(), this);
+ element->insertedInto(this);
element->attach();
+ InspectorInstrumentation::pseudoElementCreated(element.get());
+
ensureElementRareData().setPseudoElement(pseudoId, element.release());
}
@@ -2607,7 +2643,7 @@
SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), es);
if (!selectorQuery)
return false;
- return selectorQuery->matches(this);
+ return selectorQuery->matches(*this);
}
DOMTokenList* Element::classList()
@@ -3186,6 +3222,11 @@
return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
}
+bool Element::hasInputMethodContext() const
+{
+ return hasRareData() && elementRareData()->hasInputMethodContext();
+}
+
bool Element::hasPendingResources() const
{
return hasRareData() && elementRareData()->hasPendingResources();
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index c35fe66..bcdbf85 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -82,6 +82,11 @@
static PassRefPtr<Element> create(const QualifiedName&, Document*);
virtual ~Element();
+ String innerHTML() const;
+ String outerHTML() const;
+ void setInnerHTML(const String&, ExceptionState&);
+ void setOuterHTML(const String&, ExceptionState&);
+
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecut);
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforepaste);
@@ -501,6 +506,7 @@
bool hasActiveAnimations() const;
InputMethodContext* inputMethodContext();
+ bool hasInputMethodContext() const;
virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE FINAL;
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index 8d45e7d..3a8d2ba 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -92,6 +92,8 @@
// HTML 5
NodeList getElementsByClassName([Default=Undefined] optional DOMString name);
+ [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, SetterRaisesException] attribute DOMString innerHTML;
+ [TreatNullAs=NullString, CustomElementCallbacks, SetterRaisesException] attribute DOMString outerHTML;
[Reflect=class, TreatNullAs=NullString, PerWorldBindings] attribute DOMString className;
[PerWorldBindings] readonly attribute DOMTokenList classList;
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index d9be4ce..ac97c75 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -30,7 +30,6 @@
#include "core/dom/shadow/ElementShadow.h"
#include "core/html/ClassList.h"
#include "core/html/ime/InputMethodContext.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/style/StyleInheritedData.h"
#include "wtf/OwnPtr.h"
@@ -139,6 +138,7 @@
bool hasPendingResources() const { return m_hasPendingResources; }
void setHasPendingResources(bool has) { m_hasPendingResources = has; }
+ bool hasInputMethodContext() const { return m_inputMethodContext; }
InputMethodContext* ensureInputMethodContext(HTMLElement* element)
{
if (!m_inputMethodContext)
@@ -146,6 +146,8 @@
return m_inputMethodContext.get();
}
+ bool hasPseudoElements() const;
+
private:
short m_tabIndex;
unsigned short m_childIndex;
@@ -187,7 +189,6 @@
RefPtr<PseudoElement> m_backdrop;
ElementRareData(RenderObject*);
- void releasePseudoElement(PseudoElement*);
};
inline IntSize defaultMinimumSizeForResizing()
@@ -228,26 +229,32 @@
ASSERT(!m_backdrop);
}
-inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> prpElement)
+inline bool ElementRareData::hasPseudoElements() const
{
- RefPtr<PseudoElement> element = prpElement;
+ return m_generatedBefore || m_generatedAfter || m_backdrop;
+}
+
+inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
+{
switch (pseudoId) {
case BEFORE:
- releasePseudoElement(m_generatedBefore.get());
+ if (m_generatedBefore)
+ m_generatedBefore->dispose();
m_generatedBefore = element;
break;
case AFTER:
- releasePseudoElement(m_generatedAfter.get());
+ if (m_generatedAfter)
+ m_generatedAfter->dispose();
m_generatedAfter = element;
break;
case BACKDROP:
- releasePseudoElement(m_backdrop.get());
+ if (m_backdrop)
+ m_backdrop->dispose();
m_backdrop = element;
break;
default:
ASSERT_NOT_REACHED();
}
- InspectorInstrumentation::pseudoElementCreated(element.get());
}
inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const
@@ -264,21 +271,6 @@
}
}
-inline void ElementRareData::releasePseudoElement(PseudoElement* element)
-{
- if (!element)
- return;
-
- InspectorInstrumentation::pseudoElementDestroyed(element);
-
- ASSERT(!element->nextSibling());
- ASSERT(!element->previousSibling());
-
- element->detach();
- element->document().removeFromTopLayer(element);
- element->setParentOrShadowHostNode(0);
-}
-
inline void ElementRareData::resetStyleState()
{
setComputedStyle(0);
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index 6d0b514..89c6851 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -187,7 +187,6 @@
// FIXME: Does this need to null-check settings()?
if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
break;
- UserGestureIndicator::consumeUserGesture();
// There is a previously-established user preference, security risk, or platform limitation.
if (!document()->settings() || !document()->settings()->fullScreenEnabled())
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index b3dce05..91b6484 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -69,8 +69,8 @@
if (ports) {
for (unsigned int i = 0; i < ports->size(); ++i) {
MessagePort* dataPort = (*ports)[i].get();
- if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) {
- es.throwDOMException(DataCloneError, ExceptionMessages::failedToExecute("postMessage", "MessagePort", "Item #" + String::number(i) + " in the array of ports contains the " + (dataPort == this ? "source" : "target") + " port."));
+ if (dataPort == this) {
+ es.throwDOMException(DataCloneError, ExceptionMessages::failedToExecute("postMessage", "MessagePort", "Item #" + String::number(i) + " in the array of ports contains the source port."));
return;
}
}
@@ -81,7 +81,7 @@
m_entangledChannel->postMessageToRemote(message, channels.release());
}
-PassRefPtr<MessagePortChannel> MessagePort::disentangle()
+PassOwnPtr<MessagePortChannel> MessagePort::disentangle()
{
ASSERT(m_entangledChannel);
@@ -124,7 +124,7 @@
m_closed = true;
}
-void MessagePort::entangle(PassRefPtr<MessagePortChannel> remote)
+void MessagePort::entangle(PassOwnPtr<MessagePortChannel> remote)
{
// Only invoked to set our initial entanglement.
ASSERT(!m_entangledChannel);
@@ -192,7 +192,7 @@
HashSet<MessagePort*> portSet;
// Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
- for (unsigned int i = 0; i < ports->size(); ++i) {
+ for (unsigned i = 0; i < ports->size(); ++i) {
MessagePort* port = (*ports)[i].get();
if (!port || port->isNeutered() || portSet.contains(port)) {
String type;
@@ -210,10 +210,8 @@
// Passed-in ports passed validity checks, so we can disentangle them.
OwnPtr<MessagePortChannelArray> portArray = adoptPtr(new MessagePortChannelArray(ports->size()));
- for (unsigned int i = 0 ; i < ports->size() ; ++i) {
- RefPtr<MessagePortChannel> channel = (*ports)[i]->disentangle();
- (*portArray)[i] = channel.release();
- }
+ for (unsigned i = 0; i < ports->size(); ++i)
+ (*portArray)[i] = (*ports)[i]->disentangle();
return portArray.release();
}
diff --git a/Source/core/dom/MessagePort.h b/Source/core/dom/MessagePort.h
index 2f2ea5f..4540a9b 100644
--- a/Source/core/dom/MessagePort.h
+++ b/Source/core/dom/MessagePort.h
@@ -60,8 +60,8 @@
void start();
void close();
- void entangle(PassRefPtr<MessagePortChannel>);
- PassRefPtr<MessagePortChannel> disentangle();
+ void entangle(PassOwnPtr<MessagePortChannel>);
+ PassOwnPtr<MessagePortChannel> disentangle();
// Returns 0 if there is an exception, or if the passed-in array is 0/empty.
static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionState&);
@@ -98,7 +98,7 @@
private:
explicit MessagePort(ExecutionContext&);
- RefPtr<MessagePortChannel> m_entangledChannel;
+ OwnPtr<MessagePortChannel> m_entangledChannel;
bool m_started;
bool m_closed;
diff --git a/Source/core/dom/MessagePortChannel.cpp b/Source/core/dom/MessagePortChannel.cpp
index 00fd786..8f5cee3 100644
--- a/Source/core/dom/MessagePortChannel.cpp
+++ b/Source/core/dom/MessagePortChannel.cpp
@@ -39,20 +39,20 @@
namespace WebCore {
-PassRefPtr<MessagePortChannel> MessagePortChannel::create(WebKit::WebMessagePortChannel* channel)
+PassOwnPtr<MessagePortChannel> MessagePortChannel::create(WebKit::WebMessagePortChannel* channel)
{
- return adoptRef(new MessagePortChannel(channel));
+ return adoptPtr(new MessagePortChannel(channel));
}
void MessagePortChannel::createChannel(MessagePort* port1, MessagePort* port2)
{
// Create proxies for each endpoint.
- RefPtr<MessagePortChannel> channel1 = create(WebKit::Platform::current()->createMessagePortChannel());
- RefPtr<MessagePortChannel> channel2 = create(WebKit::Platform::current()->createMessagePortChannel());
+ OwnPtr<MessagePortChannel> channel1 = create(WebKit::Platform::current()->createMessagePortChannel());
+ OwnPtr<MessagePortChannel> channel2 = create(WebKit::Platform::current()->createMessagePortChannel());
// Entangle the two endpoints.
- channel1->setEntangledChannel(channel2);
- channel2->setEntangledChannel(channel1);
+ channel1->m_webChannel->entangle(channel2->m_webChannel);
+ channel2->m_webChannel->entangle(channel1->m_webChannel);
// Now entangle the proxies with the appropriate local ports.
port1->entangle(channel2.release());
@@ -126,14 +126,6 @@
// Disentangle ourselves from the other end. We still maintain a reference to m_webChannel,
// since previously-existing messages should still be delivered.
m_localPort = 0;
- m_entangledChannel = 0;
-}
-
-bool MessagePortChannel::isConnectedTo(MessagePort* port)
-{
- MutexLocker lock(m_mutex);
- // FIXME: Shouldn't the access to m_entangledChannel->m_localPort be protected by m_entangledChannel->m_mutex?
- return m_entangledChannel && m_entangledChannel->m_localPort == port;
}
bool MessagePortChannel::hasPendingActivity()
@@ -149,15 +141,6 @@
m_localPort->messageAvailable();
}
-void MessagePortChannel::setEntangledChannel(PassRefPtr<MessagePortChannel> remote)
-{
- ASSERT(m_webChannel);
- m_webChannel->entangle(remote->m_webChannel);
-
- MutexLocker lock(m_mutex);
- m_entangledChannel = remote;
-}
-
WebKit::WebMessagePortChannel* MessagePortChannel::webChannelRelease()
{
ASSERT(m_webChannel);
diff --git a/Source/core/dom/MessagePortChannel.h b/Source/core/dom/MessagePortChannel.h
index c6e5b53..799a6b6 100644
--- a/Source/core/dom/MessagePortChannel.h
+++ b/Source/core/dom/MessagePortChannel.h
@@ -51,14 +51,14 @@
class SerializedScriptValue;
// The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
-typedef Vector<RefPtr<MessagePortChannel>, 1> MessagePortChannelArray;
+typedef Vector<OwnPtr<MessagePortChannel>, 1> MessagePortChannelArray;
// MessagePortChannel is a platform-independent interface to the remote side of a message channel.
-class MessagePortChannel : public ThreadSafeRefCounted<MessagePortChannel>, public WebKit::WebMessagePortChannelClient {
+class MessagePortChannel : public WebKit::WebMessagePortChannelClient {
WTF_MAKE_NONCOPYABLE(MessagePortChannel);
public:
static void createChannel(MessagePort*, MessagePort*);
- static PassRefPtr<MessagePortChannel> create(WebKit::WebMessagePortChannel*);
+ static PassOwnPtr<MessagePortChannel> create(WebKit::WebMessagePortChannel*);
virtual ~MessagePortChannel();
@@ -71,9 +71,6 @@
// Closes the port (ensures that no further messages can be added to either queue).
void close();
- // Used by MessagePort.postMessage() to prevent callers from passing a port's own entangled port.
- bool isConnectedTo(MessagePort*);
-
// Returns true if the proxy currently contains messages for this port.
bool hasPendingActivity();
@@ -89,17 +86,12 @@
private:
explicit MessagePortChannel(WebKit::WebMessagePortChannel*);
- void setEntangledChannel(PassRefPtr<MessagePortChannel>);
-
// WebKit::WebMessagePortChannelClient implementation
virtual void messageAvailable() OVERRIDE;
// Mutex used to ensure exclusive access to the object internals.
Mutex m_mutex;
- // Pointer to our entangled pair - cleared when close() is called.
- RefPtr<MessagePortChannel> m_entangledChannel;
-
// The port we are connected to - this is the port that is notified when new messages arrive.
MessagePort* m_localPort;
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 89f80b5..8fdeee7 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -383,20 +383,13 @@
return ensureRareData().ensureNodeLists().ensureChildNodeList(this);
}
-Node *Node::lastDescendant() const
+Node& Node::lastDescendant() const
{
- Node *n = const_cast<Node *>(this);
+ Node* n = const_cast<Node*>(this);
while (n && n->lastChild())
n = n->lastChild();
- return n;
-}
-
-Node* Node::firstDescendant() const
-{
- Node *n = const_cast<Node *>(this);
- while (n && n->firstChild())
- n = n->firstChild();
- return n;
+ ASSERT(n);
+ return *n;
}
Node* Node::pseudoAwarePreviousSibling() const
@@ -720,7 +713,7 @@
void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource source)
{
ASSERT(changeType != NoStyleChange);
- if (!confusingAndOftenMisusedAttached()) // changed compared to what?
+ if (!inActiveDocument())
return;
if (source == StyleChangeFromRenderer)
@@ -924,16 +917,17 @@
return false;
}
-bool Node::containsIncludingHostElements(const Node* node) const
+bool Node::containsIncludingHostElements(const Node& node) const
{
- while (node) {
- if (node == this)
+ const Node* current = &node;
+ do {
+ if (current == this)
return true;
- if (node->isDocumentFragment() && toDocumentFragment(node)->isTemplateContent())
- node = static_cast<const TemplateContentDocumentFragment*>(node)->host();
+ if (current->isDocumentFragment() && toDocumentFragment(current)->isTemplateContent())
+ current = static_cast<const TemplateContentDocumentFragment*>(current)->host();
else
- node = node->parentOrShadowHostNode();
- }
+ current = current->parentOrShadowHostNode();
+ } while (current);
return false;
}
@@ -1249,7 +1243,7 @@
SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
if (!selectorQuery)
return 0;
- return selectorQuery->queryFirst(this);
+ return selectorQuery->queryFirst(*this);
}
PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionState& es)
@@ -1262,7 +1256,7 @@
SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), es);
if (!selectorQuery)
return 0;
- return selectorQuery->queryAll(this);
+ return selectorQuery->queryAll(*this);
}
Document* Node::ownerDocument() const
@@ -2518,7 +2512,7 @@
{
document().updateDistributionForNodeIfNeeded(this);
Vector<InsertionPoint*, 8> insertionPoints;
- collectInsertionPointsWhereNodeIsDistributed(this, insertionPoints);
+ collectDestinationInsertionPoints(*this, insertionPoints);
Vector<RefPtr<Node> > filteredInsertionPoints;
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* insertionPoint = insertionPoints[i];
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 1fe0467..fe25b60 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -216,8 +216,7 @@
String textContent(bool convertBRsToNewlines = false) const;
void setTextContent(const String&, ExceptionState&);
- Node* lastDescendant() const;
- Node* firstDescendant() const;
+ Node& lastDescendant() const;
// Other methods (not part of DOM)
@@ -501,7 +500,7 @@
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
bool containsIncludingShadowDOM(const Node*) const;
- bool containsIncludingHostElements(const Node*) const;
+ bool containsIncludingHostElements(const Node&) const;
// FIXME: Remove this when crbug.com/265716 cleans up contains semantics.
bool bindingsContains(const Node* node) const { return containsIncludingShadowDOM(node); }
@@ -922,10 +921,10 @@
inline bool operator!=(const Node& a, const Node& b) { return !(a == b); }
inline bool operator!=(const Node& a, const Node* b) { return !(a == b); }
inline bool operator!=(const Node* a, const Node& b) { return !(a == b); }
-inline bool operator==(const RefPtr<Node>& a, const Node& b) { return a.get() == &b; }
-inline bool operator==(const Node& a, const RefPtr<Node>& b) { return &a == b.get(); }
-inline bool operator!=(const RefPtr<Node>& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const RefPtr<Node>& b) { return !(a == b); }
+inline bool operator==(const PassRefPtr<Node>& a, const Node& b) { return a.get() == &b; }
+inline bool operator==(const Node& a, const PassRefPtr<Node>& b) { return &a == b.get(); }
+inline bool operator!=(const PassRefPtr<Node>& a, const Node& b) { return !(a == b); }
+inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a == b); }
#define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
diff --git a/Source/core/dom/NodeChildRemovalTracker.h b/Source/core/dom/NodeChildRemovalTracker.h
index b4faa11..09fa829 100644
--- a/Source/core/dom/NodeChildRemovalTracker.h
+++ b/Source/core/dom/NodeChildRemovalTracker.h
@@ -33,21 +33,21 @@
class NodeChildRemovalTracker {
public:
- explicit NodeChildRemovalTracker(Node*);
+ explicit NodeChildRemovalTracker(Node&);
~NodeChildRemovalTracker();
static bool isBeingRemoved(Node*);
private:
- Node* node() const { return m_node; }
+ Node& node() const { return m_node; }
NodeChildRemovalTracker* previous() { return m_previous; }
- Node* m_node;
+ Node& m_node;
NodeChildRemovalTracker* m_previous;
static NodeChildRemovalTracker* s_last;
};
-inline NodeChildRemovalTracker::NodeChildRemovalTracker(Node* node)
+inline NodeChildRemovalTracker::NodeChildRemovalTracker(Node& node)
: m_node(node)
, m_previous(s_last)
{
@@ -62,7 +62,7 @@
inline bool NodeChildRemovalTracker::isBeingRemoved(Node* node)
{
for (NodeChildRemovalTracker* removal = s_last; removal; removal = removal->previous()) {
- if (removal->node()->containsIncludingShadowDOM(node))
+ if (removal->node().containsIncludingShadowDOM(node))
return true;
}
diff --git a/Source/core/dom/NodeFilter.idl b/Source/core/dom/NodeFilter.idl
index 989099f..58ac22e 100644
--- a/Source/core/dom/NodeFilter.idl
+++ b/Source/core/dom/NodeFilter.idl
@@ -19,6 +19,7 @@
*/
[
+ DependentLifetime
] interface NodeFilter {
// Constants returned by acceptNode
const short FILTER_ACCEPT = 1;
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index 173edc4..0770aa1 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -153,43 +153,42 @@
m_referenceNode.node.clear();
}
-void NodeIterator::nodeWillBeRemoved(Node* removedNode)
+void NodeIterator::nodeWillBeRemoved(Node& removedNode)
{
updateForNodeRemoval(removedNode, m_candidateNode);
updateForNodeRemoval(removedNode, m_referenceNode);
}
-void NodeIterator::updateForNodeRemoval(Node* removedNode, NodePointer& referenceNode) const
+void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenceNode) const
{
ASSERT(!m_detached);
- ASSERT(removedNode);
- ASSERT(root()->document() == removedNode->document());
+ ASSERT(root()->document() == removedNode.document());
// Iterator is not affected if the removed node is the reference node and is the root.
// or if removed node is not the reference node, or the ancestor of the reference node.
- if (!removedNode->isDescendantOf(root()))
+ if (!removedNode.isDescendantOf(root()))
return;
bool willRemoveReferenceNode = removedNode == referenceNode.node;
- bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(removedNode);
+ bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(&removedNode);
if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
return;
if (referenceNode.isPointerBeforeNode) {
- Node* node = NodeTraversal::next(removedNode, root());
+ Node* node = NodeTraversal::next(&removedNode, root());
if (node) {
// Move out from under the node being removed if the new reference
// node is a descendant of the node being removed.
- while (node && node->isDescendantOf(removedNode))
+ while (node && node->isDescendantOf(&removedNode))
node = NodeTraversal::next(node, root());
if (node)
referenceNode.node = node;
} else {
- node = NodeTraversal::previous(removedNode, root());
+ node = NodeTraversal::previous(&removedNode, root());
if (node) {
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
- while (node && node->isDescendantOf(removedNode))
+ while (node && node->isDescendantOf(&removedNode))
node = NodeTraversal::previous(node, root());
}
if (node) {
@@ -202,23 +201,23 @@
}
}
} else {
- Node* node = NodeTraversal::previous(removedNode, root());
+ Node* node = NodeTraversal::previous(&removedNode, root());
if (node) {
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
- while (node && node->isDescendantOf(removedNode))
+ while (node && node->isDescendantOf(&removedNode))
node = NodeTraversal::previous(node, root());
}
if (node)
referenceNode.node = node;
} else {
// FIXME: This branch doesn't appear to have any LayoutTests.
- node = NodeTraversal::next(removedNode, root());
+ node = NodeTraversal::next(&removedNode, root());
// Move out from under the node being removed if the reference node is
// a descendant of the node being removed.
if (willRemoveReferenceNodeAncestor) {
- while (node && node->isDescendantOf(removedNode))
+ while (node && node->isDescendantOf(&removedNode))
node = NodeTraversal::previous(node, root());
}
if (node)
diff --git a/Source/core/dom/NodeIterator.h b/Source/core/dom/NodeIterator.h
index 4c504bf..1f06a57 100644
--- a/Source/core/dom/NodeIterator.h
+++ b/Source/core/dom/NodeIterator.h
@@ -51,7 +51,7 @@
bool pointerBeforeReferenceNode() const { return m_referenceNode.isPointerBeforeNode; }
// This function is called before any node is removed from the document tree.
- void nodeWillBeRemoved(Node*);
+ void nodeWillBeRemoved(Node&);
private:
NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
@@ -66,7 +66,7 @@
bool moveToPrevious(Node* root);
};
- void updateForNodeRemoval(Node* nodeToBeRemoved, NodePointer&) const;
+ void updateForNodeRemoval(Node& nodeToBeRemoved, NodePointer&) const;
NodePointer m_referenceNode;
NodePointer m_candidateNode;
diff --git a/Source/core/dom/NodeIterator.idl b/Source/core/dom/NodeIterator.idl
index 5e52661..9c636c4 100644
--- a/Source/core/dom/NodeIterator.idl
+++ b/Source/core/dom/NodeIterator.idl
@@ -20,7 +20,7 @@
// Introduced in DOM Level 2:
[
- CustomToV8
+ SetReference(NodeFilter filter)
] interface NodeIterator {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
diff --git a/Source/core/dom/NodeRareData.h b/Source/core/dom/NodeRareData.h
index 8d310c3..38dd440 100644
--- a/Source/core/dom/NodeRareData.h
+++ b/Source/core/dom/NodeRareData.h
@@ -60,7 +60,7 @@
void removeChildNodeList(ChildNodeList* list)
{
- ASSERT(m_childNodeList = list);
+ ASSERT(m_childNodeList == list);
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
return;
m_childNodeList = 0;
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index 7353a13..d0648bd 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -34,7 +34,7 @@
namespace NodeRenderingTraversal {
-void ParentDetails::didTraverseInsertionPoint(InsertionPoint* insertionPoint)
+void ParentDetails::didTraverseInsertionPoint(const InsertionPoint* insertionPoint)
{
if (!m_insertionPoint) {
m_insertionPoint = insertionPoint;
@@ -49,10 +49,12 @@
ContainerNode* parent(const Node* node, ParentDetails* details)
{
+ ASSERT(node);
+ if (isActiveInsertionPoint(*node))
+ return 0;
// FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
ComposedTreeWalker walker(node, ComposedTreeWalker::CanStartFromShadowBoundary);
- ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
- return details->outOfComposition() ? 0 : found;
+ return toContainerNode(walker.traverseParent(walker.get(), details));
}
Node* nextSibling(const Node* node)
diff --git a/Source/core/dom/NodeRenderingTraversal.h b/Source/core/dom/NodeRenderingTraversal.h
index 135d866..8935ae6 100644
--- a/Source/core/dom/NodeRenderingTraversal.h
+++ b/Source/core/dom/NodeRenderingTraversal.h
@@ -40,28 +40,23 @@
ParentDetails()
: m_insertionPoint(0)
, m_resetStyleInheritance(false)
- , m_outOfComposition(false)
{ }
- InsertionPoint* insertionPoint() const { return m_insertionPoint; }
+ const InsertionPoint* insertionPoint() const { return m_insertionPoint; }
bool resetStyleInheritance() const { return m_resetStyleInheritance; }
- bool outOfComposition() const { return m_outOfComposition; }
- void didTraverseInsertionPoint(InsertionPoint*);
+ void didTraverseInsertionPoint(const InsertionPoint*);
void didTraverseShadowRoot(const ShadowRoot*);
- void childWasOutOfComposition() { m_outOfComposition = true; }
bool operator==(const ParentDetails& other)
{
return m_insertionPoint == other.m_insertionPoint
- && m_resetStyleInheritance == other.m_resetStyleInheritance
- && m_outOfComposition == other.m_outOfComposition;
+ && m_resetStyleInheritance == other.m_resetStyleInheritance;
}
private:
- InsertionPoint* m_insertionPoint;
+ const InsertionPoint* m_insertionPoint;
bool m_resetStyleInheritance;
- bool m_outOfComposition;
};
ContainerNode* parent(const Node*);
diff --git a/Source/core/dom/PseudoElement.cpp b/Source/core/dom/PseudoElement.cpp
index f54a507..3900d2f 100644
--- a/Source/core/dom/PseudoElement.cpp
+++ b/Source/core/dom/PseudoElement.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "core/dom/PseudoElement.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderQuote.h"
#include "core/rendering/style/ContentData.h"
@@ -67,6 +68,19 @@
return parentOrShadowHostElement()->renderer()->getCachedPseudoStyle(m_pseudoId);
}
+void PseudoElement::dispose()
+{
+ InspectorInstrumentation::pseudoElementDestroyed(this);
+
+ ASSERT(!nextSibling());
+ ASSERT(!previousSibling());
+
+ detach();
+ RefPtr<Element> parent = parentOrShadowHostElement();
+ setParentOrShadowHostNode(0);
+ removedFrom(parent.get());
+}
+
void PseudoElement::attach(const AttachContext& context)
{
ASSERT(!renderer());
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index fa6c838..6f10933 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -53,6 +53,8 @@
static String pseudoElementNameForEvents(PseudoId);
+ void dispose();
+
private:
PseudoElement(Element*, PseudoId);
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 74a0ca9..5b2d161 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -1035,7 +1035,7 @@
return;
if (collapsed)
- m_end.setToBeforeChild(newText.get());
+ m_end.setToBeforeChild(*newText);
} else {
RefPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
if (lastChild && lastChild == m_start.childBefore()) {
@@ -1043,7 +1043,7 @@
// the inserted nodes.
Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->firstChild() : newNode.get();
ASSERT(firstChild);
- m_start.setToBeforeChild(firstChild);
+ m_start.setToBeforeChild(*firstChild);
return;
}
@@ -1694,7 +1694,7 @@
boundaryNodeChildrenWillBeRemoved(m_end, container);
}
-static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node* nodeToBeRemoved)
+static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node& nodeToBeRemoved)
{
if (boundary.childBefore() == nodeToBeRemoved) {
boundary.childBeforeWillBeRemoved();
@@ -1709,15 +1709,14 @@
}
}
-void Range::nodeWillBeRemoved(Node* node)
+void Range::nodeWillBeRemoved(Node& node)
{
- ASSERT(node);
- ASSERT(node->document() == m_ownerDocument);
+ ASSERT(node.document() == m_ownerDocument);
ASSERT(node != m_ownerDocument);
// FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we
// should change following if-statement to ASSERT(!node->parentNode).
- if (!node->parentNode())
+ if (!node.parentNode())
return;
boundaryNodeWillBeRemoved(m_start, node);
boundaryNodeWillBeRemoved(m_end, node);
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 8975552..ab77a96 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -130,7 +130,7 @@
void nodeChildrenChanged(ContainerNode*);
void nodeChildrenWillBeRemoved(ContainerNode*);
- void nodeWillBeRemoved(Node*);
+ void nodeWillBeRemoved(Node&);
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
diff --git a/Source/core/dom/RangeBoundaryPoint.h b/Source/core/dom/RangeBoundaryPoint.h
index c1a4625..7574a89 100644
--- a/Source/core/dom/RangeBoundaryPoint.h
+++ b/Source/core/dom/RangeBoundaryPoint.h
@@ -48,7 +48,7 @@
void set(PassRefPtr<Node> container, int offset, Node* childBefore);
void setOffset(int offset);
- void setToBeforeChild(Node*);
+ void setToBeforeChild(Node&);
void setToStartOfNode(PassRefPtr<Node>);
void setToEndOfNode(PassRefPtr<Node>);
@@ -136,12 +136,11 @@
m_offsetInContainer = offset;
}
-inline void RangeBoundaryPoint::setToBeforeChild(Node* child)
+inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
{
- ASSERT(child);
- ASSERT(child->parentNode());
- m_childBeforeBoundary = child->previousSibling();
- m_containerNode = child->parentNode();
+ ASSERT(child.parentNode());
+ m_childBeforeBoundary = child.previousSibling();
+ m_containerNode = child.parentNode();
m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
}
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index 5eeaeee..d1f90af 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -139,27 +139,25 @@
m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPath::canUse(selector)));
}
-inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element* element, const Node* rootNode) const
+inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const Node& rootNode) const
{
- if (selectorData.isFastCheckable && !element->isSVGElement()) {
+ if (selectorData.isFastCheckable && !element.isSVGElement()) {
SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, element);
if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::VisitedMatchDisabled))
return false;
return selectorCheckerFastPath.matches();
}
- SelectorChecker selectorChecker(element->document(), SelectorChecker::QueryingRules);
- SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, element, SelectorChecker::VisitedMatchDisabled);
+ SelectorChecker selectorChecker(element.document(), SelectorChecker::QueryingRules);
+ SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, &element, SelectorChecker::VisitedMatchDisabled);
selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTreeScope;
- selectorCheckingContext.scope = !rootNode->isDocumentNode() && rootNode->isContainerNode() ? toContainerNode(rootNode) : 0;
+ selectorCheckingContext.scope = !rootNode.isDocumentNode() && rootNode.isContainerNode() ? &toContainerNode(rootNode) : 0;
PseudoId ignoreDynamicPseudo = NOPSEUDO;
return selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches;
}
-bool SelectorDataList::matches(Element* targetElement) const
+bool SelectorDataList::matches(Element& targetElement) const
{
- ASSERT(targetElement);
-
unsigned selectorCount = m_selectors.size();
for (unsigned i = 0; i < selectorCount; ++i) {
if (selectorMatches(m_selectors[i], targetElement, targetElement))
@@ -169,14 +167,14 @@
return false;
}
-PassRefPtr<NodeList> SelectorDataList::queryAll(Node* rootNode) const
+PassRefPtr<NodeList> SelectorDataList::queryAll(Node& rootNode) const
{
Vector<RefPtr<Node> > result;
executeQueryAll(rootNode, result);
return StaticNodeList::adopt(result);
}
-PassRefPtr<Element> SelectorDataList::queryFirst(Node* rootNode) const
+PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const
{
return executeQueryFirst(rootNode);
}
@@ -187,43 +185,43 @@
return node->isDocumentNode() || node->isShadowRoot();
}
-void SelectorDataList::collectElementsByClassName(Node* rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
+void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
if (element->hasClass() && element->classNames().contains(className))
traversalRoots.append(element);
}
}
-void SelectorDataList::collectElementsByTagName(Node* rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
+void SelectorDataList::collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
- if (SelectorChecker::tagMatches(element, tagName))
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
+ if (SelectorChecker::tagMatches(*element, tagName))
traversalRoots.append(element);
}
}
-Element* SelectorDataList::findElementByClassName(Node* rootNode, const AtomicString& className) const
+Element* SelectorDataList::findElementByClassName(Node& rootNode, const AtomicString& className) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
if (element->hasClass() && element->classNames().contains(className))
return element;
}
return 0;
}
-Element* SelectorDataList::findElementByTagName(Node* rootNode, const QualifiedName& tagName) const
+Element* SelectorDataList::findElementByTagName(Node& rootNode, const QualifiedName& tagName) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
- if (SelectorChecker::tagMatches(element, tagName))
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
+ if (SelectorChecker::tagMatches(*element, tagName))
return element;
}
return 0;
}
-inline bool SelectorDataList::canUseFastQuery(Node* rootNode) const
+inline bool SelectorDataList::canUseFastQuery(const Node& rootNode) const
{
- return m_selectors.size() == 1 && rootNode->inDocument() && !rootNode->document().inQuirksMode();
+ return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.document().inQuirksMode();
}
inline bool ancestorHasClassName(Node* rootNode, const AtomicString& className)
@@ -303,11 +301,11 @@
return adoptPtr(new SingleNodeList(rootNode));
}
-void SelectorDataList::executeSlowQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const
+void SelectorDataList::executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], element, rootNode)) {
+ if (selectorMatches(m_selectors[i], *element, rootNode)) {
matchedElements.append(element);
break;
}
@@ -315,7 +313,7 @@
}
}
-void SelectorDataList::executeQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const
+void SelectorDataList::executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
{
if (!canUseFastQuery(rootNode))
return executeSlowQueryAll(rootNode, matchedElements);
@@ -330,12 +328,12 @@
switch (firstSelector->m_match) {
case CSSSelector::Id:
{
- if (rootNode->document().containsMultipleElementsWithId(firstSelector->value()))
+ if (rootNode.document().containsMultipleElementsWithId(firstSelector->value()))
break;
// Just the same as getElementById.
- Element* element = rootNode->treeScope().getElementById(firstSelector->value());
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
+ Element* element = rootNode.treeScope().getElementById(firstSelector->value());
+ if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
matchedElements.append(element);
return;
}
@@ -349,17 +347,17 @@
}
bool matchTraverseRoots;
- OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(rootNode, matchTraverseRoots);
+ OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(&rootNode, matchTraverseRoots);
if (traverseRoots->isEmpty())
return;
const SelectorData& selector = m_selectors[0];
if (matchTraverseRoots) {
while (!traverseRoots->isEmpty()) {
- Node* node = traverseRoots->next();
- Element* element = toElement(node);
+ Node& node = *traverseRoots->next();
+ Element& element = toElement(node);
if (selectorMatches(selector, element, rootNode))
- matchedElements.append(element);
+ matchedElements.append(&element);
}
return;
}
@@ -367,7 +365,7 @@
while (!traverseRoots->isEmpty()) {
Node* traverseRoot = traverseRoots->next();
for (Element* element = ElementTraversal::firstWithin(traverseRoot); element; element = ElementTraversal::next(element, traverseRoot)) {
- if (selectorMatches(selector, element, rootNode))
+ if (selectorMatches(selector, *element, rootNode))
matchedElements.append(element);
}
}
@@ -380,31 +378,31 @@
//
// The returned Node may be 0, regardless of matchTraverseRoot, if this method finds that the selectors won't
// match any element.
-Node* SelectorDataList::findTraverseRoot(Node* rootNode, bool& matchTraverseRoot) const
+Node* SelectorDataList::findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const
{
// We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
// we would need to sort the results. For now, just traverse the document in that case.
- ASSERT(rootNode);
ASSERT(m_selectors.size() == 1);
ASSERT(m_selectors[0].selector);
bool matchSingleNode = true;
bool startFromParent = false;
for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !rootNode->document().containsMultipleElementsWithId(selector->value())) {
- Element* element = rootNode->treeScope().getElementById(selector->value());
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)))
- rootNode = element;
+ if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
+ Element* element = rootNode.treeScope().getElementById(selector->value());
+ Node* adjustedRootNode = &rootNode;
+ if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
+ adjustedRootNode = element;
else if (!element || matchSingleNode)
- rootNode = 0;
+ adjustedRootNode = 0;
if (matchSingleNode) {
matchTraverseRoot = true;
- return rootNode;
+ return adjustedRootNode;
}
- if (startFromParent && rootNode)
- rootNode = rootNode->parentNode();
+ if (startFromParent && adjustedRootNode)
+ adjustedRootNode = adjustedRootNode->parentNode();
matchTraverseRoot = false;
- return rootNode;
+ return adjustedRootNode;
}
if (selector->relation() == CSSSelector::SubSelector)
continue;
@@ -415,21 +413,21 @@
startFromParent = false;
}
matchTraverseRoot = false;
- return rootNode;
+ return &rootNode;
}
-Element* SelectorDataList::executeSlowQueryFirst(Node* rootNode) const
+Element* SelectorDataList::executeSlowQueryFirst(Node& rootNode) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+ for (Element* element = ElementTraversal::firstWithin(&rootNode); element; element = ElementTraversal::next(element, &rootNode)) {
for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], element, rootNode))
+ if (selectorMatches(m_selectors[i], *element, rootNode))
return element;
}
}
return 0;
}
-Element* SelectorDataList::executeQueryFirst(Node* rootNode) const
+Element* SelectorDataList::executeQueryFirst(Node& rootNode) const
{
if (!canUseFastQuery(rootNode))
return executeSlowQueryFirst(rootNode);
@@ -444,10 +442,10 @@
switch (selector->m_match) {
case CSSSelector::Id:
{
- if (rootNode->document().containsMultipleElementsWithId(selector->value()))
+ if (rootNode.document().containsMultipleElementsWithId(selector->value()))
break;
- Element* element = rootNode->treeScope().getElementById(selector->value());
- return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(rootNode)) ? element : 0;
+ Element* element = rootNode.treeScope().getElementById(selector->value());
+ return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)) ? element : 0;
}
case CSSSelector::Class:
return findElementByClassName(rootNode, selector->value());
@@ -465,12 +463,12 @@
if (matchTraverseRoot) {
ASSERT(m_selectors.size() == 1);
ASSERT(traverseRootNode->isElementNode());
- Element* element = toElement(traverseRootNode);
- return selectorMatches(m_selectors[0], element, rootNode) ? element : 0;
+ Element& element = toElement(*traverseRootNode);
+ return selectorMatches(m_selectors[0], element, rootNode) ? &element : 0;
}
for (Element* element = ElementTraversal::firstWithin(traverseRootNode); element; element = ElementTraversal::next(element, traverseRootNode)) {
- if (selectorMatches(m_selectors[0], element, rootNode))
+ if (selectorMatches(m_selectors[0], *element, rootNode))
return element;
}
return 0;
@@ -482,17 +480,17 @@
m_selectors.initialize(m_selectorList);
}
-bool SelectorQuery::matches(Element* element) const
+bool SelectorQuery::matches(Element& element) const
{
return m_selectors.matches(element);
}
-PassRefPtr<NodeList> SelectorQuery::queryAll(Node* rootNode) const
+PassRefPtr<NodeList> SelectorQuery::queryAll(Node& rootNode) const
{
return m_selectors.queryAll(rootNode);
}
-PassRefPtr<Element> SelectorQuery::queryFirst(Node* rootNode) const
+PassRefPtr<Element> SelectorQuery::queryFirst(Node& rootNode) const
{
return m_selectors.queryFirst(rootNode);
}
diff --git a/Source/core/dom/SelectorQuery.h b/Source/core/dom/SelectorQuery.h
index 2f654c4..bbe607c 100644
--- a/Source/core/dom/SelectorQuery.h
+++ b/Source/core/dom/SelectorQuery.h
@@ -45,9 +45,9 @@
class SelectorDataList {
public:
void initialize(const CSSSelectorList&);
- bool matches(Element*) const;
- PassRefPtr<NodeList> queryAll(Node* rootNode) const;
- PassRefPtr<Element> queryFirst(Node* rootNode) const;
+ bool matches(Element&) const;
+ PassRefPtr<NodeList> queryAll(Node& rootNode) const;
+ PassRefPtr<Element> queryFirst(Node& rootNode) const;
private:
struct SelectorData {
@@ -56,18 +56,18 @@
bool isFastCheckable;
};
- bool canUseFastQuery(Node* rootNode) const;
- bool selectorMatches(const SelectorData&, Element*, const Node*) const;
- void collectElementsByClassName(Node* rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
- Element* findElementByClassName(Node* rootNode, const AtomicString& className) const;
- void collectElementsByTagName(Node* rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
- Element* findElementByTagName(Node* rootNode, const QualifiedName& tagName) const;
+ bool canUseFastQuery(const Node& rootNode) const;
+ bool selectorMatches(const SelectorData&, Element&, const Node&) const;
+ void collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
+ Element* findElementByClassName(Node& rootNode, const AtomicString& className) const;
+ void collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
+ Element* findElementByTagName(Node& rootNode, const QualifiedName& tagName) const;
PassOwnPtr<SimpleNodeList> findTraverseRoots(Node* rootNode, bool& matchTraverseRoots) const;
- void executeSlowQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- void executeQueryAll(Node* rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- Node* findTraverseRoot(Node* rootNode, bool& matchTraverseRoot) const;
- Element* executeSlowQueryFirst(Node* rootNode) const;
- Element* executeQueryFirst(Node* rootNode) const;
+ void executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
+ void executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
+ Node* findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const;
+ Element* executeSlowQueryFirst(Node& rootNode) const;
+ Element* executeQueryFirst(Node& rootNode) const;
Vector<SelectorData> m_selectors;
};
@@ -77,9 +77,9 @@
WTF_MAKE_FAST_ALLOCATED;
public:
explicit SelectorQuery(const CSSSelectorList&);
- bool matches(Element*) const;
- PassRefPtr<NodeList> queryAll(Node* rootNode) const;
- PassRefPtr<Element> queryFirst(Node* rootNode) const;
+ bool matches(Element&) const;
+ PassRefPtr<NodeList> queryAll(Node& rootNode) const;
+ PassRefPtr<Element> queryFirst(Node& rootNode) const;
private:
SelectorDataList m_selectors;
CSSSelectorList m_selectorList;
diff --git a/Source/core/dom/StyleSheetScopingNodeList.h b/Source/core/dom/StyleSheetScopingNodeList.h
index 42ebda3..790be13 100644
--- a/Source/core/dom/StyleSheetScopingNodeList.h
+++ b/Source/core/dom/StyleSheetScopingNodeList.h
@@ -39,6 +39,11 @@
return !node || node->isDocumentNode() || node->isShadowRoot();
}
+inline bool isTreeScopeRoot(const Node& node)
+{
+ return node.isDocumentNode() || node.isShadowRoot();
+}
+
class StyleSheetScopingNodeList {
WTF_MAKE_NONCOPYABLE(StyleSheetScopingNodeList); WTF_MAKE_FAST_ALLOCATED;
public:
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index 8c11f4d..46fe4ca 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -230,7 +230,7 @@
if (!frameView->visibleContentRect().contains(point))
return 0;
- HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
HitTestResult result(point);
document->renderView()->hitTest(request, result);
diff --git a/Source/core/dom/TreeWalker.idl b/Source/core/dom/TreeWalker.idl
index dd545b8..ac04ba0 100644
--- a/Source/core/dom/TreeWalker.idl
+++ b/Source/core/dom/TreeWalker.idl
@@ -20,7 +20,7 @@
// Introduced in DOM Level 2:
[
- CustomToV8
+ SetReference(NodeFilter filter)
] interface TreeWalker {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
diff --git a/Source/core/dom/ViewportDescription.h b/Source/core/dom/ViewportDescription.h
index 96cccc0..53eed26 100644
--- a/Source/core/dom/ViewportDescription.h
+++ b/Source/core/dom/ViewportDescription.h
@@ -106,6 +106,7 @@
bool isLegacyViewportType() const { return type >= HandheldFriendlyMeta && type <= ViewportMeta; }
bool isMetaViewportType() const { return type == ViewportMeta; }
+ bool isSpecifiedByAuthor() const { return type != UserAgentStyleSheet; }
private:
enum Direction { Horizontal, Vertical };
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 1e19ddc..b321d06 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -31,6 +31,7 @@
#include "core/dom/Element.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/InsertionPoint.h"
+#include "core/html/shadow/HTMLShadowElement.h"
namespace WebCore {
@@ -41,22 +42,6 @@
return 0;
}
-static inline bool nodeCanBeDistributed(const Node* node)
-{
- ASSERT(node);
- Node* parent = parentNodeForDistribution(node);
- if (!parent)
- return false;
-
- if (ShadowRoot* shadowRoot = parent->isShadowRoot() ? toShadowRoot(parent) : 0)
- return shadowRoot->insertionPoint();
-
- if (parent->isElementNode() && toElement(parent)->shadow())
- return true;
-
- return false;
-}
-
Node* ComposedTreeWalker::traverseChild(const Node* node, TraversalDirection direction) const
{
ASSERT(node);
@@ -83,7 +68,7 @@
Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection direction)
{
ASSERT(node);
- if (!isActiveInsertionPoint(node))
+ if (!isActiveInsertionPoint(*node))
return const_cast<Node*>(node);
const InsertionPoint* insertionPoint = toInsertionPoint(node);
if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->first() : insertionPoint->last(), insertionPoint, direction))
@@ -104,10 +89,10 @@
{
ASSERT(node);
- if (!nodeCanBeDistributed(node))
+ if (!shadowWhereNodeCanBeDistributed(*node))
return traverseSiblingInCurrentTree(node, direction);
- InsertionPoint* insertionPoint = resolveReprojection(node);
+ const InsertionPoint* insertionPoint = resolveReprojection(node);
if (!insertionPoint)
return traverseSiblingInCurrentTree(node, direction);
@@ -123,7 +108,7 @@
return found;
if (Node* next = traverseBackToYoungerShadowRoot(node, direction))
return next;
- return escapeFallbackContentElement(node, direction);
+ return 0;
}
Node* ComposedTreeWalker::traverseBackToYoungerShadowRoot(const Node* node, TraversalDirection direction)
@@ -132,7 +117,7 @@
if (node->parentNode() && node->parentNode()->isShadowRoot()) {
ShadowRoot* parentShadowRoot = toShadowRoot(node->parentNode());
if (!parentShadowRoot->isYoungest()) {
- InsertionPoint* assignedInsertionPoint = parentShadowRoot->insertionPoint();
+ HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadowInsertionPointOfYoungerShadowRoot();
ASSERT(assignedInsertionPoint);
return traverseSiblingInCurrentTree(assignedInsertionPoint, direction);
}
@@ -140,24 +125,6 @@
return 0;
}
-inline Node* ComposedTreeWalker::escapeFallbackContentElement(const Node* node, TraversalDirection direction)
-{
- ASSERT(node);
- if (node->parentNode() && isActiveInsertionPoint(node->parentNode()))
- return traverseSiblingOrBackToInsertionPoint(node->parentNode(), direction);
- return 0;
-}
-
-inline Node* ComposedTreeWalker::traverseNodeEscapingFallbackContents(const Node* node, ParentTraversalDetails* details) const
-{
- ASSERT(node);
- if (!node->isInsertionPoint())
- return const_cast<Node*>(node);
- const InsertionPoint* insertionPoint = toInsertionPoint(node);
- return insertionPoint->hasDistribution() ? 0 :
- insertionPoint->isActive() ? traverseParent(node, details) : const_cast<Node*>(node);
-}
-
// FIXME: Use an iterative algorithm so that it can be inlined.
// https://bugs.webkit.org/show_bug.cgi?id=90415
Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetails* details) const
@@ -165,16 +132,16 @@
if (node->isPseudoElement())
return node->parentOrShadowHostNode();
- if (nodeCanBeDistributed(node)) {
- if (InsertionPoint* insertionPoint = resolveReprojection(node)) {
+ if (shadowWhereNodeCanBeDistributed(*node)) {
+ if (const InsertionPoint* insertionPoint = resolveReprojection(node)) {
if (details)
details->didTraverseInsertionPoint(insertionPoint);
- return traverseParent(insertionPoint, details);
+ // The node is distributed. But the distribution was stopped at this insertion point.
+ if (shadowWhereNodeCanBeDistributed(*insertionPoint))
+ return 0;
+ return traverseParentInCurrentTree(insertionPoint, details);
}
-
- // The node is a non-distributed light child or older shadow's child.
- if (details)
- details->childWasOutOfComposition();
+ return 0;
}
return traverseParentInCurrentTree(node, details);
}
@@ -182,14 +149,14 @@
inline Node* ComposedTreeWalker::traverseParentInCurrentTree(const Node* node, ParentTraversalDetails* details) const
{
if (Node* parent = node->parentNode())
- return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : traverseNodeEscapingFallbackContents(parent, details);
+ return parent->isShadowRoot() ? traverseParentBackToYoungerShadowRootOrHost(toShadowRoot(parent), details) : parent;
return 0;
}
Node* ComposedTreeWalker::traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot* shadowRoot, ParentTraversalDetails* details) const
{
ASSERT(shadowRoot);
- ASSERT(!shadowRoot->insertionPoint());
+ ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
if (shadowRoot->isYoungest()) {
if (details)
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.h b/Source/core/dom/shadow/ComposedTreeWalker.h
index 2fb9cf3..2754913 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.h
+++ b/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -77,7 +77,7 @@
#ifndef NDEBUG
ASSERT(m_node);
ASSERT(!m_node->isShadowRoot());
- ASSERT(!isActiveInsertionPoint(m_node));
+ ASSERT(!isActiveInsertionPoint(*m_node));
#endif
}
@@ -106,9 +106,7 @@
static Node* traverseDistributedNodes(const Node*, const InsertionPoint*, TraversalDirection);
static Node* traverseBackToYoungerShadowRoot(const Node*, TraversalDirection);
- static Node* escapeFallbackContentElement(const Node*, TraversalDirection);
- Node* traverseNodeEscapingFallbackContents(const Node*, ParentTraversalDetails* = 0) const;
Node* traverseParentInCurrentTree(const Node*, ParentTraversalDetails* = 0) const;
Node* traverseParentBackToYoungerShadowRootOrHost(const ShadowRoot*, ParentTraversalDetails* = 0) const;
diff --git a/Source/core/dom/shadow/ContentDistribution.cpp b/Source/core/dom/shadow/ContentDistribution.cpp
index e0527ad..a53ff57 100644
--- a/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/Source/core/dom/shadow/ContentDistribution.cpp
@@ -39,7 +39,8 @@
void ContentDistribution::append(PassRefPtr<Node> node)
{
- ASSERT(!isActiveInsertionPoint(node.get()));
+ ASSERT(node);
+ ASSERT(!isActiveInsertionPoint(*node));
size_t size = m_nodes.size();
m_indices.set(node.get(), size);
m_nodes.append(node);
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index a75da1b..158addd 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -47,8 +47,8 @@
private:
void populateChildren(const ContainerNode*);
void detachNonDistributedNodes();
- Vector<Node*> m_nodes;
- Vector<bool> m_distributed;
+ Vector<Node*, 32> m_nodes;
+ Vector<bool, 32> m_distributed;
};
inline DistributionPool::DistributionPool(const ContainerNode* parent)
@@ -59,18 +59,11 @@
inline void DistributionPool::populateChildren(const ContainerNode* parent)
{
- m_nodes.reserveInitialCapacity(32);
for (Node* child = parent->firstChild(); child; child = child->nextSibling()) {
- if (isActiveInsertionPoint(child)) {
+ if (isActiveInsertionPoint(*child)) {
InsertionPoint* insertionPoint = toInsertionPoint(child);
- if (insertionPoint->hasDistribution()) {
- for (size_t i = 0; i < insertionPoint->size(); ++i)
- m_nodes.append(insertionPoint->at(i));
- } else {
- // Fallback elements.
- for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling())
- m_nodes.append(fallbackNode);
- }
+ for (size_t i = 0; i < insertionPoint->size(); ++i)
+ m_nodes.append(insertionPoint->at(i));
} else {
m_nodes.append(child);
}
@@ -96,6 +89,13 @@
m_distributed[i] = true;
}
+ // Distributes fallback elements
+ if (insertionPoint->isContentInsertionPoint() && distribution.isEmpty()) {
+ for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fallbackNode = fallbackNode->nextSibling()) {
+ distribution.append(fallbackNode);
+ elementShadow->didDistributeNode(fallbackNode, insertionPoint);
+ }
+ }
insertionPoint->setDistribution(distribution);
}
@@ -240,63 +240,70 @@
return false;
}
-InsertionPoint* ElementShadow::findInsertionPointFor(const Node* key) const
+const InsertionPoint* ElementShadow::finalDestinationInsertionPointFor(const Node* key) const
{
- return m_nodeToInsertionPoint.get(key);
+ NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
+ return it == m_nodeToInsertionPoints.end() ? 0: it->value.last().get();
+}
+
+const DestinationInsertionPoints* ElementShadow::destinationInsertionPointsFor(const Node* key) const
+{
+ NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
+ return it == m_nodeToInsertionPoints.end() ? 0: &it->value;
}
void ElementShadow::distribute()
{
- DistributionPool pool(host());
host()->setNeedsStyleRecalc();
- Vector<HTMLShadowElement*, 32> activeShadowInsertionPoints;
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
+ const ContainerNode* poolContainer = host();
+ Vector<HTMLShadowElement*, 32> shadowInsertionPoints;
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ DistributionPool pool(poolContainer);
+
+ HTMLShadowElement* shadowInsertionPoint = 0;
const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
if (!point->isActive())
continue;
-
if (isHTMLShadowElement(point)) {
- if (!firstActiveShadowInsertionPoint)
- firstActiveShadowInsertionPoint = toHTMLShadowElement(point);
+ if (!shadowInsertionPoint)
+ shadowInsertionPoint = toHTMLShadowElement(point);
} else {
pool.distributeTo(point, this);
- if (ElementShadow* shadow = shadowOfParentForDistribution(point))
+ if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point))
shadow->setNeedsDistributionRecalc();
}
}
-
- if (firstActiveShadowInsertionPoint)
- activeShadowInsertionPoints.append(firstActiveShadowInsertionPoint);
+ if (shadowInsertionPoint)
+ shadowInsertionPoints.append(shadowInsertionPoint);
+ poolContainer = shadowInsertionPoint;
}
- for (size_t i = activeShadowInsertionPoints.size(); i > 0; --i) {
- HTMLShadowElement* shadowElement = activeShadowInsertionPoints[i - 1];
- ShadowRoot* root = shadowElement->containingShadowRoot();
+ for (size_t i = shadowInsertionPoints.size(); i > 0; --i) {
+ HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1];
+ ShadowRoot* root = shadowInsertionPoint->containingShadowRoot();
ASSERT(root);
if (root->olderShadowRoot() && root->olderShadowRoot()->type() == root->type()) {
// Only allow reprojecting older shadow roots between the same type to
// disallow reprojecting UA elements into author shadows.
- distributeNodeChildrenTo(shadowElement, root->olderShadowRoot());
- root->olderShadowRoot()->setInsertionPoint(shadowElement);
- } else if (!root->olderShadowRoot()) {
- // There's assumed to always be a UA shadow that selects all nodes.
- // We don't actually add it, instead we just distribute the pool to the
- // <shadow> in the oldest shadow root.
- pool.distributeTo(shadowElement, this);
+ distributeNodeChildrenTo(shadowInsertionPoint, root->olderShadowRoot());
+ root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint);
+ } else if (root->isOldest()) {
+ DistributionPool pool(shadowInsertionPoint);
+ pool.distributeTo(shadowInsertionPoint, this);
}
- if (ElementShadow* shadow = shadowOfParentForDistribution(shadowElement))
+ if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*shadowInsertionPoint))
shadow->setNeedsDistributionRecalc();
}
}
void ElementShadow::didDistributeNode(const Node* node, InsertionPoint* insertionPoint)
{
- m_nodeToInsertionPoint.add(node, insertionPoint);
+ NodeToDestinationInsertionPoints::AddResult result = m_nodeToInsertionPoints.add(node, DestinationInsertionPoints());
+ result.iterator->value.append(insertionPoint);
}
void ElementShadow::distributeNodeChildrenTo(InsertionPoint* insertionPoint, ContainerNode* containerNode)
@@ -353,10 +360,10 @@
void ElementShadow::clearDistribution()
{
- m_nodeToInsertionPoint.clear();
+ m_nodeToInsertionPoints.clear();
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- root->setInsertionPoint(0);
+ root->setShadowInsertionPointOfYoungerShadowRoot(0);
}
} // namespace
diff --git a/Source/core/dom/shadow/ElementShadow.h b/Source/core/dom/shadow/ElementShadow.h
index a8e040e..bab1c23 100644
--- a/Source/core/dom/shadow/ElementShadow.h
+++ b/Source/core/dom/shadow/ElementShadow.h
@@ -27,6 +27,7 @@
#ifndef ElementShadow_h
#define ElementShadow_h
+#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/SelectRuleFeatureSet.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "wtf/DoublyLinkedList.h"
@@ -38,8 +39,6 @@
namespace WebCore {
-class InsertionPoint;
-
class ElementShadow {
WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -69,7 +68,8 @@
void distributeIfNeeded();
void setNeedsDistributionRecalc();
- InsertionPoint* findInsertionPointFor(const Node*) const;
+ const InsertionPoint* finalDestinationInsertionPointFor(const Node*) const;
+ const DestinationInsertionPoints* destinationInsertionPointsFor(const Node*) const;
void didDistributeNode(const Node*, InsertionPoint*);
@@ -81,13 +81,16 @@
void distribute();
void clearDistribution();
+
void collectSelectFeatureSetFrom(ShadowRoot*);
void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*);
bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; }
void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; }
- HashMap<const Node*, RefPtr<InsertionPoint> > m_nodeToInsertionPoint;
+ typedef HashMap<const Node*, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
+ NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
+
SelectRuleFeatureSet m_selectFeatures;
DoublyLinkedList<ShadowRoot> m_shadowRoots;
bool m_needsDistributionRecalc;
@@ -124,16 +127,6 @@
m_needsDistributionRecalc = false;
}
-inline ElementShadow* shadowOfParent(const Node* node)
-{
- if (!node)
- return 0;
- if (Node* parent = node->parentNode())
- if (parent->isElementNode())
- return toElement(parent)->shadow();
- return 0;
-}
-
} // namespace
#endif
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 3023d66..a1bb7db 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -32,10 +32,13 @@
#include "core/dom/shadow/InsertionPoint.h"
#include "HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/QualifiedName.h"
#include "core/dom/StaticNodeList.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/HTMLShadowElement.h"
namespace WebCore {
@@ -128,20 +131,53 @@
return isActive() && !hasDistribution();
}
-bool InsertionPoint::isActive() const
+bool InsertionPoint::canBeActive() const
{
- if (!containingShadowRoot())
+ if (!isInShadowTree())
return false;
- const Node* node = parentNode();
- while (node) {
- if (node->isInsertionPoint())
- return false;
-
- node = node->parentNode();
+ bool foundShadowElementInAncestors = false;
+ bool thisIsContentHTMLElement = isHTMLContentElement(this);
+ for (Node* node = parentNode(); node; node = node->parentNode()) {
+ if (node->isInsertionPoint()) {
+ // For HTMLContentElement, at most one HTMLShadowElement may appear in its ancestors.
+ if (thisIsContentHTMLElement && isHTMLShadowElement(node) && !foundShadowElementInAncestors)
+ foundShadowElementInAncestors = true;
+ else
+ return false;
+ }
}
return true;
}
+bool InsertionPoint::isActive() const
+{
+ if (!canBeActive())
+ return false;
+ ShadowRoot* shadowRoot = containingShadowRoot();
+ ASSERT(shadowRoot);
+ if (!isHTMLShadowElement(this) || shadowRoot->descendantShadowElementCount() <= 1)
+ return true;
+
+ // Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
+ const Vector<RefPtr<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
+ for (size_t i = 0; i < insertionPoints.size(); ++i) {
+ InsertionPoint* point = insertionPoints[i].get();
+ if (isHTMLShadowElement(point))
+ return point == this;
+ }
+ return true;
+}
+
+bool InsertionPoint::isShadowInsertionPoint() const
+{
+ return isHTMLShadowElement(this) && isActive();
+}
+
+bool InsertionPoint::isContentInsertionPoint() const
+{
+ return isHTMLContentElement(this) && isActive();
+}
+
PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
{
document().updateDistributionForNodeIfNeeded(this);
@@ -171,11 +207,10 @@
Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
-
if (ShadowRoot* root = containingShadowRoot()) {
if (ElementShadow* rootOwner = root->owner()) {
rootOwner->setNeedsDistributionRecalc();
- if (isActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
+ if (canBeActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
m_registeredWithShadowRoot = true;
root->didAddInsertionPoint(this);
rootOwner->didAffectApplyAuthorStyles();
@@ -239,53 +274,43 @@
setBooleanAttribute(reset_style_inheritanceAttr, value);
}
-InsertionPoint* resolveReprojection(const Node* projectedNode)
+const InsertionPoint* resolveReprojection(const Node* projectedNode)
{
- InsertionPoint* insertionPoint = 0;
+ ASSERT(projectedNode);
+ const InsertionPoint* insertionPoint = 0;
const Node* current = projectedNode;
-
- while (current) {
- if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
- if (InsertionPoint* insertedTo = shadow->findInsertionPointFor(projectedNode)) {
- current = insertedTo;
- insertionPoint = insertedTo;
- continue;
- }
- }
-
- if (Node* parent = parentNodeForDistribution(current)) {
- if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
- current = insertedTo;
- insertionPoint = insertedTo;
- continue;
- }
- }
-
- break;
+ ElementShadow* lastElementShadow = 0;
+ while (true) {
+ ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
+ if (!shadow || shadow == lastElementShadow)
+ break;
+ lastElementShadow = shadow;
+ const InsertionPoint* insertedTo = shadow->finalDestinationInsertionPointFor(projectedNode);
+ if (!insertedTo)
+ break;
+ ASSERT(current != insertedTo);
+ current = insertedTo;
+ insertionPoint = insertedTo;
}
-
return insertionPoint;
}
-void collectInsertionPointsWhereNodeIsDistributed(const Node* node, Vector<InsertionPoint*, 8>& results)
+void collectDestinationInsertionPoints(const Node& node, Vector<InsertionPoint*, 8>& results)
{
- const Node* current = node;
+ const Node* current = &node;
+ ElementShadow* lastElementShadow = 0;
while (true) {
- if (ElementShadow* shadow = shadowOfParentForDistribution(current)) {
- if (InsertionPoint* insertedTo = shadow->findInsertionPointFor(node)) {
- current = insertedTo;
- results.append(insertedTo);
- continue;
- }
- }
- if (Node* parent = parentNodeForDistribution(current)) {
- if (InsertionPoint* insertedTo = parent->isShadowRoot() ? toShadowRoot(parent)->insertionPoint() : 0) {
- current = insertedTo;
- results.append(insertedTo);
- continue;
- }
- }
- return;
+ ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
+ if (!shadow || shadow == lastElementShadow)
+ return;
+ lastElementShadow = shadow;
+ const DestinationInsertionPoints* insertionPoints = shadow->destinationInsertionPointsFor(&node);
+ if (!insertionPoints)
+ return;
+ for (size_t i = 0; i < insertionPoints->size(); ++i)
+ results.append(insertionPoints->at(i).get());
+ ASSERT(current != insertionPoints->last().get());
+ current = insertionPoints->last().get();
}
}
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index d12423b..639a52f 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -33,6 +33,7 @@
#include "core/css/CSSSelectorList.h"
#include "core/dom/shadow/ContentDistribution.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLElement.h"
#include "wtf/Forward.h"
@@ -46,6 +47,10 @@
void setDistribution(ContentDistribution&);
void clearDistribution() { m_distribution.clear(); }
bool isActive() const;
+ bool canBeActive() const;
+
+ bool isShadowInsertionPoint() const;
+ bool isContentInsertionPoint() const;
PassRefPtr<NodeList> getDistributedNodes();
@@ -76,11 +81,12 @@
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
private:
-
ContentDistribution m_distribution;
bool m_registeredWithShadowRoot;
};
+typedef Vector<RefPtr<InsertionPoint> > DestinationInsertionPoints;
+
inline InsertionPoint* toInsertionPoint(Node* node)
{
ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isInsertionPoint());
@@ -93,46 +99,39 @@
return static_cast<const InsertionPoint*>(node);
}
-inline bool isActiveInsertionPoint(const Node* node)
+inline const InsertionPoint& toInsertionPoint(const Node& node)
{
- return node->isInsertionPoint() && toInsertionPoint(node)->isActive();
+ ASSERT_WITH_SECURITY_IMPLICATION(node.isInsertionPoint());
+ return static_cast<const InsertionPoint&>(node);
}
-inline Node* parentNodeForDistribution(const Node* node)
+inline bool isActiveInsertionPoint(const Node& node)
{
- ASSERT(node);
+ return node.isInsertionPoint() && toInsertionPoint(node).isActive();
+}
- if (Node* parent = node->parentNode()) {
- if (parent->isInsertionPoint() && toInsertionPoint(parent)->shouldUseFallbackElements())
- return parent->parentNode();
- return parent;
- }
+inline bool isActiveShadowInsertionPoint(const Node& node)
+{
+ return node.isInsertionPoint() && toInsertionPoint(node).isShadowInsertionPoint();
+}
+inline ElementShadow* shadowWhereNodeCanBeDistributed(const Node& node)
+{
+ Node* parent = node.parentNode();
+ if (!parent)
+ return 0;
+ if (parent->isShadowRoot() && !toShadowRoot(parent)->isYoungest())
+ return node.shadowHost()->shadow();
+ if (isActiveInsertionPoint(*parent))
+ return node.shadowHost()->shadow();
+ if (parent->isElementNode())
+ return toElement(parent)->shadow();
return 0;
}
-inline Element* parentElementForDistribution(const Node* node)
-{
- if (Node* parent = parentNodeForDistribution(node)) {
- if (parent->isElementNode())
- return toElement(parent);
- }
+const InsertionPoint* resolveReprojection(const Node*);
- return 0;
-}
-
-inline ElementShadow* shadowOfParentForDistribution(const Node* node)
-{
- ASSERT(node);
- if (Element* parent = parentElementForDistribution(node))
- return parent->shadow();
-
- return 0;
-}
-
-InsertionPoint* resolveReprojection(const Node*);
-
-void collectInsertionPointsWhereNodeIsDistributed(const Node*, Vector<InsertionPoint*, 8>& results);
+void collectDestinationInsertionPoints(const Node&, Vector<InsertionPoint*, 8>& results);
} // namespace WebCore
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 508585a..95865b8 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -294,7 +294,7 @@
void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (InsertionPoint* point = insertionPoint()) {
+ if (InsertionPoint* point = shadowInsertionPointOfYoungerShadowRoot()) {
if (ShadowRoot* root = point->containingShadowRoot())
root->owner()->setNeedsDistributionRecalc();
}
@@ -337,16 +337,21 @@
return m_shadowRootRareData ? m_shadowRootRareData->containsShadowRoots() : 0;
}
-InsertionPoint* ShadowRoot::insertionPoint() const
+unsigned ShadowRoot::descendantShadowElementCount() const
{
- return m_shadowRootRareData ? m_shadowRootRareData->insertionPoint() : 0;
+ return m_shadowRootRareData ? m_shadowRootRareData->descendantShadowElementCount() : 0;
}
-void ShadowRoot::setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint)
+HTMLShadowElement* ShadowRoot::shadowInsertionPointOfYoungerShadowRoot() const
{
- if (!m_shadowRootRareData && !insertionPoint)
+ return m_shadowRootRareData ? m_shadowRootRareData->shadowInsertionPointOfYoungerShadowRoot() : 0;
+}
+
+void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint)
+{
+ if (!m_shadowRootRareData && !shadowInsertionPoint)
return;
- ensureShadowRootRareData()->setInsertionPoint(insertionPoint);
+ ensureShadowRootRareData()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint);
}
void ShadowRoot::didAddInsertionPoint(InsertionPoint* insertionPoint)
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 84ad90b..876dcbf 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -38,6 +38,7 @@
class ElementShadow;
class ExceptionState;
+class HTMLShadowElement;
class InsertionPoint;
class ShadowRootRareData;
@@ -85,11 +86,13 @@
bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); }
bool containsShadowRoots() const;
+ unsigned descendantShadowElementCount() const;
+
// For Internals, don't use this.
unsigned childShadowRootCount() const;
- InsertionPoint* insertionPoint() const;
- void setInsertionPoint(PassRefPtr<InsertionPoint>);
+ HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const;
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement>);
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
index 6ed6376..dae72a7 100644
--- a/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -48,8 +48,8 @@
{
}
- InsertionPoint* insertionPoint() const { return m_insertionPoint.get(); }
- void setInsertionPoint(PassRefPtr<InsertionPoint> insertionPoint) { m_insertionPoint = insertionPoint; }
+ HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const { return m_shadowInsertionPointOfYoungerShadowRoot.get(); }
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
@@ -58,6 +58,8 @@
bool containsContentElements() const { return m_descendantContentElementCount; }
bool containsShadowRoots() const { return m_childShadowRootCount; }
+ unsigned descendantShadowElementCount() const { return m_descendantShadowElementCount; }
+
void didAddChildShadowRoot() { ++m_childShadowRootCount; }
void didRemoveChildShadowRoot() { ASSERT(m_childShadowRootCount > 0); --m_childShadowRootCount; }
@@ -71,7 +73,7 @@
void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
private:
- RefPtr<InsertionPoint> m_insertionPoint;
+ RefPtr<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
unsigned m_descendantShadowElementCount;
unsigned m_descendantContentElementCount;
unsigned m_childShadowRootCount;