Diff
Modified: trunk/Source/WebCore/ChangeLog (156250 => 156251)
--- trunk/Source/WebCore/ChangeLog 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/ChangeLog 2013-09-22 22:11:37 UTC (rev 156251)
@@ -1,5 +1,46 @@
2013-09-22 Sam Weinig <[email protected]>
+ CTTE: StaticNodeLists often contain only Elements, we shouldn't store them as Vector<RefPtr<Node>> in those cases
+ https://bugs.webkit.org/show_bug.cgi?id=121769
+
+ Reviewed by Andreas Kling.
+
+ Introduces StaticElementList and uses it.
+
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::addRadioButtonGroupMembers):
+ * bindings/js/JSHTMLAllCollectionCustom.cpp:
+ (WebCore::getNamedItems):
+ * bindings/js/JSHTMLCollectionCustom.cpp:
+ * bindings/js/JSHTMLFormControlsCollectionCustom.cpp:
+ (WebCore::getNamedItems):
+ * bindings/js/JSHTMLFormElementCustom.cpp:
+ (WebCore::JSHTMLFormElement::nameGetter):
+ * dom/SelectorQuery.cpp:
+ (WebCore::AllElementExtractorSelectorQueryTrait::appendOutputForElement):
+ (WebCore::SelectorDataList::queryAll):
+ * dom/StaticNodeList.cpp:
+ (WebCore::StaticElementList::length):
+ (WebCore::StaticElementList::item):
+ (WebCore::StaticElementList::namedItem):
+ * dom/StaticNodeList.h:
+ * dom/WebKitNamedFlow.cpp:
+ (WebCore::WebKitNamedFlow::getRegionsByContent):
+ (WebCore::WebKitNamedFlow::getRegions):
+ (WebCore::WebKitNamedFlow::getContent):
+ (WebCore::WebKitNamedFlow::dispatchRegionLayoutUpdateEvent):
+ (WebCore::WebKitNamedFlow::dispatchRegionOversetChangeEvent):
+ * html/HTMLCollection.cpp:
+ (WebCore::HTMLCollection::namedItems):
+ * html/HTMLCollection.h:
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::getNamedElements):
+ * html/HTMLFormElement.h:
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::collectIntersectionOrEnclosureList):
+
+2013-09-22 Sam Weinig <[email protected]>
+
CTTE: RenderNamedFlowThread and FlowThreadController should operate on Elements, not Nodes
https://bugs.webkit.org/show_bug.cgi?id=121768
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (156250 => 156251)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -931,13 +931,13 @@
HTMLInputElement* input = toHTMLInputElement(node);
// if there's a form, then this is easy
if (input->form()) {
- Vector<RefPtr<Node> > formElements;
+ Vector<Ref<Element>> formElements;
input->form()->getNamedElements(input->name(), formElements);
unsigned len = formElements.size();
for (unsigned i = 0; i < len; ++i) {
- Node* associateElement = formElements[i].get();
- if (AccessibilityObject* object = axObjectCache()->getOrCreate(associateElement))
+ Element& associateElement = formElements[i].get();
+ if (AccessibilityObject* object = axObjectCache()->getOrCreate(&associateElement))
linkedUIElements.append(object);
}
} else {
Modified: trunk/Source/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp (156250 => 156251)
--- trunk/Source/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -42,17 +42,17 @@
static JSValue getNamedItems(ExecState* exec, JSHTMLAllCollection* collection, PropertyName propertyName)
{
- Vector<RefPtr<Node> > namedItems;
+ Vector<Ref<Element>> namedItems;
collection->impl()->namedItems(propertyNameToAtomicString(propertyName), namedItems);
if (namedItems.isEmpty())
return jsUndefined();
if (namedItems.size() == 1)
- return toJS(exec, collection->globalObject(), namedItems[0].get());
+ return toJS(exec, collection->globalObject(), &namedItems[0].get());
// FIXME: HTML5 specification says this should be a HTMLCollection.
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlallcollection
- return toJS(exec, collection->globalObject(), StaticNodeList::adopt(namedItems).get());
+ return toJS(exec, collection->globalObject(), StaticElementList::adopt(namedItems).get());
}
// HTMLAllCollections are strange objects, they support both get and call.
Modified: trunk/Source/WebCore/bindings/js/JSHTMLCollectionCustom.cpp (156250 => 156251)
--- trunk/Source/WebCore/bindings/js/JSHTMLCollectionCustom.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/bindings/js/JSHTMLCollectionCustom.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -33,7 +33,6 @@
#include "JSRadioNodeList.h"
#include "Node.h"
#include "RadioNodeList.h"
-#include "StaticNodeList.h"
#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
Modified: trunk/Source/WebCore/bindings/js/JSHTMLFormControlsCollectionCustom.cpp (156250 => 156251)
--- trunk/Source/WebCore/bindings/js/JSHTMLFormControlsCollectionCustom.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/bindings/js/JSHTMLFormControlsCollectionCustom.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -39,14 +39,14 @@
static JSValue getNamedItems(ExecState* exec, JSHTMLFormControlsCollection* collection, PropertyName propertyName)
{
- Vector<RefPtr<Node> > namedItems;
+ Vector<Ref<Element>> namedItems;
const AtomicString& name = propertyNameToAtomicString(propertyName);
collection->impl()->namedItems(name, namedItems);
if (namedItems.isEmpty())
return jsUndefined();
if (namedItems.size() == 1)
- return toJS(exec, collection->globalObject(), namedItems[0].get());
+ return toJS(exec, collection->globalObject(), &namedItems[0].get());
ASSERT(collection->impl()->type() == FormControls);
return toJS(exec, collection->globalObject(), collection->impl()->ownerNode()->radioNodeList(name).get());
Modified: trunk/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp (156250 => 156251)
--- trunk/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/bindings/js/JSHTMLFormElementCustom.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -47,16 +47,16 @@
JSHTMLElement* jsForm = jsCast<JSHTMLFormElement*>(asObject(slotBase));
HTMLFormElement* form = toHTMLFormElement(jsForm->impl());
- Vector<RefPtr<Node> > namedItems;
+ Vector<Ref<Element>> namedItems;
form->getNamedElements(propertyNameToAtomicString(propertyName), namedItems);
if (namedItems.isEmpty())
return jsUndefined();
if (namedItems.size() == 1)
- return toJS(exec, jsForm->globalObject(), namedItems[0].get());
+ return toJS(exec, jsForm->globalObject(), &namedItems[0].get());
// FIXME: HTML5 specifies that this should be a RadioNodeList.
- return toJS(exec, jsForm->globalObject(), StaticNodeList::adopt(namedItems).get());
+ return toJS(exec, jsForm->globalObject(), StaticElementList::adopt(namedItems).get());
}
}
Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (156250 => 156251)
--- trunk/Source/WebCore/dom/SelectorQuery.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -81,16 +81,16 @@
}
struct AllElementExtractorSelectorQueryTrait {
- typedef Vector<RefPtr<Node>> OutputType;
+ typedef Vector<Ref<Element>> OutputType;
static const bool shouldOnlyMatchFirstElement = false;
- ALWAYS_INLINE static void appendOutputForElement(OutputType& output, Element* element) { output.append(element); }
+ ALWAYS_INLINE static void appendOutputForElement(OutputType& output, Element* element) { ASSERT(element); output.append(*element); }
};
PassRefPtr<NodeList> SelectorDataList::queryAll(Node* rootNode) const
{
- Vector<RefPtr<Node>> result;
+ Vector<Ref<Element>> result;
execute<AllElementExtractorSelectorQueryTrait>(rootNode, result);
- return StaticNodeList::adopt(result);
+ return StaticElementList::adopt(result);
}
struct SingleElementExtractorSelectorQueryTrait {
Modified: trunk/Source/WebCore/dom/StaticNodeList.cpp (156250 => 156251)
--- trunk/Source/WebCore/dom/StaticNodeList.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/dom/StaticNodeList.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -57,4 +57,28 @@
return 0;
}
+unsigned StaticElementList::length() const
+{
+ return m_elements.size();
+}
+
+Node* StaticElementList::item(unsigned index) const
+{
+ if (index < m_elements.size())
+ return &const_cast<Element&>(m_elements[index].get());
+ return 0;
+}
+
+Node* StaticElementList::namedItem(const AtomicString& elementId) const
+{
+ size_t length = m_elements.size();
+ for (size_t i = 0; i < length; ++i) {
+ Element& element = const_cast<Element&>(m_elements[i].get());
+ if (element.getIdAttribute() == elementId)
+ return &element;
+ }
+
+ return 0;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/StaticNodeList.h (156250 => 156251)
--- trunk/Source/WebCore/dom/StaticNodeList.h 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/dom/StaticNodeList.h 2013-09-22 22:11:37 UTC (rev 156251)
@@ -29,6 +29,7 @@
#ifndef StaticNodeList_h
#define StaticNodeList_h
+#include "Element.h"
#include "NodeList.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -36,32 +37,56 @@
namespace WebCore {
- class Node;
+class StaticNodeList FINAL : public NodeList {
+public:
+ static PassRefPtr<StaticNodeList> adopt(Vector<RefPtr<Node>>& nodes)
+ {
+ RefPtr<StaticNodeList> nodeList = adoptRef(new StaticNodeList);
+ nodeList->m_nodes.swap(nodes);
+ return nodeList.release();
+ }
- class StaticNodeList : public NodeList {
- public:
- static PassRefPtr<StaticNodeList> adopt(Vector<RefPtr<Node> >& nodes)
- {
- RefPtr<StaticNodeList> nodeList = adoptRef(new StaticNodeList);
- nodeList->m_nodes.swap(nodes);
- return nodeList.release();
- }
+ static PassRefPtr<StaticNodeList> createEmpty()
+ {
+ return adoptRef(new StaticNodeList);
+ }
- static PassRefPtr<StaticNodeList> createEmpty()
- {
- return adoptRef(new StaticNodeList);
- }
+ virtual unsigned length() const OVERRIDE;
+ virtual Node* item(unsigned index) const OVERRIDE;
+ virtual Node* namedItem(const AtomicString&) const OVERRIDE;
- virtual unsigned length() const OVERRIDE;
- virtual Node* item(unsigned index) const OVERRIDE;
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+private:
+ StaticNodeList() { }
- private:
- StaticNodeList() { }
+ Vector<RefPtr<Node>> m_nodes;
+};
- Vector<RefPtr<Node> > m_nodes;
- };
+class StaticElementList FINAL : public NodeList {
+public:
+ static PassRefPtr<StaticElementList> adopt(Vector<Ref<Element>>& elements)
+ {
+ RefPtr<StaticElementList> nodeList = adoptRef(new StaticElementList);
+ nodeList->m_elements.swap(elements);
+ return nodeList.release();
+ }
+ static PassRefPtr<StaticElementList> createEmpty()
+ {
+ return adoptRef(new StaticElementList);
+ }
+
+ virtual unsigned length() const OVERRIDE;
+ virtual Node* item(unsigned index) const OVERRIDE;
+ virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+
+private:
+ StaticElementList()
+ {
+ }
+
+ Vector<Ref<Element>> m_elements;
+};
+
} // namespace WebCore
#endif // StaticNodeList_h
Modified: trunk/Source/WebCore/dom/WebKitNamedFlow.cpp (156250 => 156251)
--- trunk/Source/WebCore/dom/WebKitNamedFlow.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/dom/WebKitNamedFlow.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -118,7 +118,7 @@
PassRefPtr<NodeList> WebKitNamedFlow::getRegionsByContent(Node* contentNode)
{
if (!contentNode)
- return StaticNodeList::createEmpty();
+ return StaticElementList::createEmpty();
if (m_flowManager->document())
m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
@@ -126,9 +126,9 @@
// The renderer may be destroyed or created after the style update.
// Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
if (!m_parentFlowThread)
- return StaticNodeList::createEmpty();
+ return StaticElementList::createEmpty();
- Vector<RefPtr<Node>> regionElements;
+ Vector<Ref<Element>> regionElements;
if (inFlowThread(contentNode->renderer(), m_parentFlowThread)) {
const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
@@ -141,12 +141,12 @@
continue;
if (m_parentFlowThread->objectInFlowRegion(contentNode->renderer(), renderRegion)) {
ASSERT(renderRegion->generatingElement());
- regionElements.append(renderRegion->generatingElement());
+ regionElements.append(*renderRegion->generatingElement());
}
}
}
- return StaticNodeList::adopt(regionElements);
+ return StaticElementList::adopt(regionElements);
}
PassRefPtr<NodeList> WebKitNamedFlow::getRegions()
@@ -157,9 +157,9 @@
// The renderer may be destroyed or created after the style update.
// Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
if (!m_parentFlowThread)
- return StaticNodeList::createEmpty();
+ return StaticElementList::createEmpty();
- Vector<RefPtr<Node>> regionElements;
+ Vector<Ref<Element>> regionElements;
const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
for (auto iter = regionList.begin(), end = regionList.end(); iter != end; ++iter) {
@@ -170,10 +170,10 @@
if (renderRegion->isPseudoElement())
continue;
ASSERT(renderRegion->generatingElement());
- regionElements.append(renderRegion->generatingElement());
+ regionElements.append(*renderRegion->generatingElement());
}
- return StaticNodeList::adopt(regionElements);
+ return StaticElementList::adopt(regionElements);
}
PassRefPtr<NodeList> WebKitNamedFlow::getContent()
@@ -184,18 +184,18 @@
// The renderer may be destroyed or created after the style update.
// Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
if (!m_parentFlowThread)
- return StaticNodeList::createEmpty();
+ return StaticElementList::createEmpty();
- Vector<RefPtr<Node>> contentElements;
+ Vector<Ref<Element>> contentElements;
const NamedFlowContentElements& contentElementsList = m_parentFlowThread->contentElements();
for (auto it = contentElementsList.begin(), end = contentElementsList.end(); it != end; ++it) {
Element* element = *it;
ASSERT(element->computedStyle()->flowThread() == m_parentFlowThread->flowThreadName());
- contentElements.append(element);
+ contentElements.append(*element);
}
- return StaticNodeList::adopt(contentElements);
+ return StaticElementList::adopt(contentElements);
}
void WebKitNamedFlow::setRenderer(RenderNamedFlowThread* parentFlowThread)
@@ -225,9 +225,7 @@
if (flowState() == FlowStateNull)
return;
- RefPtr<Event> event = UIEvent::create(eventNames().webkitregionlayoutupdateEvent, false, false, m_flowManager->document()->defaultView(), 0);
-
- dispatchEvent(event);
+ dispatchEvent(UIEvent::create(eventNames().webkitregionlayoutupdateEvent, false, false, m_flowManager->document()->defaultView(), 0));
}
void WebKitNamedFlow::dispatchRegionOversetChangeEvent()
@@ -237,10 +235,8 @@
// If the flow is in the "NULL" state the event should not be dispatched any more.
if (flowState() == FlowStateNull)
return;
-
- RefPtr<Event> event = UIEvent::create(eventNames().webkitregionoversetchangeEvent, false, false, m_flowManager->document()->defaultView(), 0);
-
- dispatchEvent(event);
+
+ dispatchEvent(UIEvent::create(eventNames().webkitregionoversetchangeEvent, false, false, m_flowManager->document()->defaultView(), 0));
}
EventTargetInterface WebKitNamedFlow::eventTargetInterface() const
Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (156250 => 156251)
--- trunk/Source/WebCore/html/HTMLCollection.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -646,7 +646,7 @@
return namedItem(name);
}
-void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
+void HTMLCollection::namedItems(const AtomicString& name, Vector<Ref<Element>>& result) const
{
ASSERT(result.isEmpty());
if (name.isEmpty())
@@ -658,10 +658,10 @@
Vector<Element*>* nameResults = nameCache(name);
for (unsigned i = 0; idResults && i < idResults->size(); ++i)
- result.append(idResults->at(i));
+ result.append(*idResults->at(i));
for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
- result.append(nameResults->at(i));
+ result.append(*nameResults->at(i));
}
PassRefPtr<NodeList> HTMLCollection::tags(const String& name)
Modified: trunk/Source/WebCore/html/HTMLCollection.h (156250 => 156251)
--- trunk/Source/WebCore/html/HTMLCollection.h 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/html/HTMLCollection.h 2013-09-22 22:11:37 UTC (rev 156251)
@@ -43,7 +43,7 @@
// Non-DOM API
virtual bool hasNamedItem(const AtomicString& name) const;
- void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
+ void namedItems(const AtomicString& name, Vector<Ref<Element>>&) const;
bool isEmpty() const
{
if (isLengthCacheValid())
Modified: trunk/Source/WebCore/html/HTMLFormElement.cpp (156250 => 156251)
--- trunk/Source/WebCore/html/HTMLFormElement.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/html/HTMLFormElement.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -673,16 +673,16 @@
}
// FIXME: Use RefPtr<HTMLElement> for namedItems. elements()->namedItems never return non-HTMLElement nodes.
-void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<Node> >& namedItems)
+void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<Ref<Element>>& namedItems)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#dom-form-nameditem
elements()->namedItems(name, namedItems);
HTMLElement* elementFromPast = elementFromPastNamesMap(name);
- if (namedItems.size() == 1 && namedItems.first() != elementFromPast)
- addToPastNamesMap(toHTMLElement(namedItems.first().get())->asFormNamedItem(), name);
+ if (namedItems.size() == 1 && &namedItems.first().get() != elementFromPast)
+ addToPastNamesMap(toHTMLElement(&namedItems.first().get())->asFormNamedItem(), name);
else if (elementFromPast && namedItems.isEmpty())
- namedItems.append(elementFromPast);
+ namedItems.append(*elementFromPast);
}
void HTMLFormElement::documentDidResumeFromPageCache()
Modified: trunk/Source/WebCore/html/HTMLFormElement.h (156250 => 156251)
--- trunk/Source/WebCore/html/HTMLFormElement.h 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/html/HTMLFormElement.h 2013-09-22 22:11:37 UTC (rev 156251)
@@ -48,7 +48,7 @@
PassRefPtr<HTMLCollection> elements();
bool hasNamedElement(const AtomicString&);
- void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&);
+ void getNamedElements(const AtomicString&, Vector<Ref<Element>>&);
unsigned length() const;
Node* item(unsigned index);
Modified: trunk/Source/WebCore/svg/SVGSVGElement.cpp (156250 => 156251)
--- trunk/Source/WebCore/svg/SVGSVGElement.cpp 2013-09-22 21:23:48 UTC (rev 156250)
+++ trunk/Source/WebCore/svg/SVGSVGElement.cpp 2013-09-22 22:11:37 UTC (rev 156251)
@@ -335,20 +335,21 @@
PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const FloatRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure collect) const
{
- Vector<RefPtr<Node> > nodes;
+ Vector<Ref<Element>> elements;
auto svgDescendants = descendantsOfType<SVGElement>(referenceElement ? referenceElement : this);
for (auto it = svgDescendants.begin(), end = svgDescendants.end(); it != end; ++it) {
const SVGElement* svgElement = &*it;
if (collect == CollectIntersectionList) {
- if (checkIntersection(svgElement, rect))
- nodes.append(const_cast<SVGElement*>(svgElement));
+ if (RenderSVGModelObject::checkIntersection(svgElement->renderer(), rect))
+ elements.append(*const_cast<SVGElement*>(svgElement));
} else {
- if (checkEnclosure(svgElement, rect))
- nodes.append(const_cast<SVGElement*>(svgElement));
+ if (RenderSVGModelObject::checkEnclosure(svgElement->renderer(), rect))
+ elements.append(*const_cast<SVGElement*>(svgElement));
}
}
- return StaticNodeList::adopt(nodes);
+
+ return StaticElementList::adopt(elements);
}
PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(const FloatRect& rect, SVGElement* referenceElement) const