Title: [136996] trunk
Revision
136996
Author
[email protected]
Date
2012-12-07 15:43:48 -0800 (Fri, 07 Dec 2012)

Log Message

MutationRecord addedNodes/removedNodes should never be null
https://bugs.webkit.org/show_bug.cgi?id=98921

Reviewed by Ryosuke Niwa.

Source/WebCore:

Per an update to the DOM4 spec that matches Gecko's behavior,
addedNodes/removedNodes should be empty NodeLists on 'attributes'
and 'characterData' records, rather than null.

This is accomplished with lazy initialization of addedNodes/removedNodes
attributes on 'attributes'/'characterData' records and the
addition of a new StaticNodeList::createEmpty() factory method.

* dom/MutationRecord.cpp:
* dom/MutationRecord.h:
(MutationRecord):
* dom/StaticNodeList.h:
(WebCore::StaticNodeList::adopt):
(StaticNodeList):
(WebCore::StaticNodeList::createEmpty):
(WebCore::StaticNodeList::StaticNodeList):

LayoutTests:

Updated nullity test to check for empty nodelists.

* fast/mutation/mutation-record-nullity-expected.txt:
* fast/mutation/mutation-record-nullity.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (136995 => 136996)


--- trunk/LayoutTests/ChangeLog	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/LayoutTests/ChangeLog	2012-12-07 23:43:48 UTC (rev 136996)
@@ -1,3 +1,15 @@
+2012-12-07  Adam Klein  <[email protected]>
+
+        MutationRecord addedNodes/removedNodes should never be null
+        https://bugs.webkit.org/show_bug.cgi?id=98921
+
+        Reviewed by Ryosuke Niwa.
+
+        Updated nullity test to check for empty nodelists.
+
+        * fast/mutation/mutation-record-nullity-expected.txt:
+        * fast/mutation/mutation-record-nullity.html:
+
 2012-12-07  Emil A Eklund  <[email protected]>
 
         Unreviewed chromium-win rebaselines.

Modified: trunk/LayoutTests/fast/mutation/mutation-record-nullity-expected.txt (136995 => 136996)


--- trunk/LayoutTests/fast/mutation/mutation-record-nullity-expected.txt	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/LayoutTests/fast/mutation/mutation-record-nullity-expected.txt	2012-12-07 23:43:48 UTC (rev 136996)
@@ -1,4 +1,4 @@
-Non-relevant properties on mutation records should be null
+Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
@@ -7,10 +7,10 @@
 PASS record.attributeName is null
 PASS record.attributeNamespace is null
 PASS record.oldValue is null
-PASS record.addedNodes is null
-PASS record.removedNodes is null
 PASS record.previousSibling is null
 PASS record.nextSibling is null
+PASS record.addedNodes.length is 0
+PASS record.removedNodes.length is 0
 
 childList record:
 PASS record.attributeName is null
@@ -20,10 +20,10 @@
 attributes record:
 PASS record.attributeNamespace is null
 PASS record.oldValue is null
-PASS record.addedNodes is null
-PASS record.removedNodes is null
 PASS record.previousSibling is null
 PASS record.nextSibling is null
+PASS record.addedNodes.length is 0
+PASS record.removedNodes.length is 0
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/mutation/mutation-record-nullity.html (136995 => 136996)


--- trunk/LayoutTests/fast/mutation/mutation-record-nullity.html	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/LayoutTests/fast/mutation/mutation-record-nullity.html	2012-12-07 23:43:48 UTC (rev 136996)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <script src=""
 <script>
-description('Non-relevant properties on mutation records should be null');
+description('Non-relevant properties on mutation records should be null, except for NodeLists, which should be empty');
 var observer = new WebKitMutationObserver(function() {});
 
 var text = document.createTextNode('something');
@@ -12,10 +12,10 @@
 shouldBeNull('record.attributeName');
 shouldBeNull('record.attributeNamespace');
 shouldBeNull('record.oldValue');
-shouldBeNull('record.addedNodes');
-shouldBeNull('record.removedNodes');
 shouldBeNull('record.previousSibling');
 shouldBeNull('record.nextSibling');
+shouldBe('record.addedNodes.length', '0');
+shouldBe('record.removedNodes.length', '0');
 
 var div = document.createElement('div');
 observer.observe(div, {childList: true});
@@ -32,9 +32,9 @@
 debug('\nattributes record:');
 shouldBeNull('record.attributeNamespace');
 shouldBeNull('record.oldValue');
-shouldBeNull('record.addedNodes');
-shouldBeNull('record.removedNodes');
 shouldBeNull('record.previousSibling');
 shouldBeNull('record.nextSibling');
+shouldBe('record.addedNodes.length', '0');
+shouldBe('record.removedNodes.length', '0');
 </script>
 <script src=""

Modified: trunk/Source/WebCore/ChangeLog (136995 => 136996)


--- trunk/Source/WebCore/ChangeLog	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/Source/WebCore/ChangeLog	2012-12-07 23:43:48 UTC (rev 136996)
@@ -1,3 +1,27 @@
+2012-12-07  Adam Klein  <[email protected]>
+
+        MutationRecord addedNodes/removedNodes should never be null
+        https://bugs.webkit.org/show_bug.cgi?id=98921
+
+        Reviewed by Ryosuke Niwa.
+
+        Per an update to the DOM4 spec that matches Gecko's behavior,
+        addedNodes/removedNodes should be empty NodeLists on 'attributes'
+        and 'characterData' records, rather than null.
+
+        This is accomplished with lazy initialization of addedNodes/removedNodes
+        attributes on 'attributes'/'characterData' records and the
+        addition of a new StaticNodeList::createEmpty() factory method.
+
+        * dom/MutationRecord.cpp:
+        * dom/MutationRecord.h:
+        (MutationRecord):
+        * dom/StaticNodeList.h:
+        (WebCore::StaticNodeList::adopt):
+        (StaticNodeList):
+        (WebCore::StaticNodeList::createEmpty):
+        (WebCore::StaticNodeList::StaticNodeList):
+
 2012-12-07  Brent Fulgham  <[email protected]>
 
         Unreviewed build correction after 136959.

Modified: trunk/Source/WebCore/dom/MutationRecord.cpp (136995 => 136996)


--- trunk/Source/WebCore/dom/MutationRecord.cpp	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/Source/WebCore/dom/MutationRecord.cpp	2012-12-07 23:43:48 UTC (rev 136996)
@@ -37,6 +37,7 @@
 #include "Node.h"
 #include "NodeList.h"
 #include "QualifiedName.h"
+#include "StaticNodeList.h"
 #include <wtf/Assertions.h>
 #include <wtf/StdLibExtras.h>
 
@@ -70,44 +71,60 @@
     RefPtr<Node> m_nextSibling;
 };
 
-class AttributesRecord : public MutationRecord {
+class RecordWithEmptyNodeLists : public MutationRecord {
 public:
+    RecordWithEmptyNodeLists(PassRefPtr<Node> target, const String& oldValue)
+        : m_target(target)
+        , m_oldValue(oldValue)
+    {
+    }
+
+private:
+    virtual Node* target() OVERRIDE { return m_target.get(); }
+    virtual String oldValue() OVERRIDE { return m_oldValue; }
+    virtual NodeList* addedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_addedNodes); }
+    virtual NodeList* removedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_removedNodes); }
+
+    static NodeList* lazilyInitializeEmptyNodeList(RefPtr<NodeList>& nodeList)
+    {
+        if (!nodeList)
+            nodeList = StaticNodeList::createEmpty();
+        return nodeList.get();
+    }
+
+    RefPtr<Node> m_target;
+    String m_oldValue;
+    RefPtr<NodeList> m_addedNodes;
+    RefPtr<NodeList> m_removedNodes;
+};
+
+class AttributesRecord : public RecordWithEmptyNodeLists {
+public:
     AttributesRecord(PassRefPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
-        : m_target(target)
+        : RecordWithEmptyNodeLists(target, oldValue)
         , m_attributeName(name.localName())
         , m_attributeNamespace(name.namespaceURI())
-        , m_oldValue(oldValue)
     {
     }
 
 private:
     virtual const AtomicString& type() OVERRIDE;
-    virtual Node* target() OVERRIDE { return m_target.get(); }
     virtual const AtomicString& attributeName() OVERRIDE { return m_attributeName; }
     virtual const AtomicString& attributeNamespace() OVERRIDE { return m_attributeNamespace; }
-    virtual String oldValue() OVERRIDE { return m_oldValue; }
 
-    RefPtr<Node> m_target;
     AtomicString m_attributeName;
     AtomicString m_attributeNamespace;
-    AtomicString m_oldValue;
 };
 
-class CharacterDataRecord : public MutationRecord {
+class CharacterDataRecord : public RecordWithEmptyNodeLists {
 public:
     CharacterDataRecord(PassRefPtr<Node> target, const String& oldValue)
-        : m_target(target)
-        , m_oldValue(oldValue)
+        : RecordWithEmptyNodeLists(target, oldValue)
     {
     }
 
 private:
     virtual const AtomicString& type() OVERRIDE;
-    virtual Node* target() OVERRIDE { return m_target.get(); }
-    virtual String oldValue() OVERRIDE { return m_oldValue; }
-
-    RefPtr<Node> m_target;
-    String m_oldValue;
 };
 
 class MutationRecordWithNullOldValue : public MutationRecord {

Modified: trunk/Source/WebCore/dom/MutationRecord.h (136995 => 136996)


--- trunk/Source/WebCore/dom/MutationRecord.h	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/Source/WebCore/dom/MutationRecord.h	2012-12-07 23:43:48 UTC (rev 136996)
@@ -57,8 +57,8 @@
     virtual const AtomicString& type() = 0;
     virtual Node* target() = 0;
 
-    virtual NodeList* addedNodes() { return 0; }
-    virtual NodeList* removedNodes() { return 0; }
+    virtual NodeList* addedNodes() = 0;
+    virtual NodeList* removedNodes() = 0;
     virtual Node* previousSibling() { return 0; }
     virtual Node* nextSibling() { return 0; }
 

Modified: trunk/Source/WebCore/dom/StaticNodeList.h (136995 => 136996)


--- trunk/Source/WebCore/dom/StaticNodeList.h	2012-12-07 23:42:02 UTC (rev 136995)
+++ trunk/Source/WebCore/dom/StaticNodeList.h	2012-12-07 23:43:48 UTC (rev 136996)
@@ -40,21 +40,25 @@
 
     class StaticNodeList : public NodeList {
     public:
-        // Adopts the contents of the nodes vector.
         static PassRefPtr<StaticNodeList> adopt(Vector<RefPtr<Node> >& nodes)
         {
-            return adoptRef(new StaticNodeList(nodes));
+            RefPtr<StaticNodeList> nodeList = adoptRef(new StaticNodeList);
+            nodeList->m_nodes.swap(nodes);
+            return nodeList.release();
         }
 
+        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;
 
     private:
-        explicit StaticNodeList(Vector<RefPtr<Node> >& nodes)
-        {
-            m_nodes.swap(nodes);
-        }
+        StaticNodeList() { }
+
         Vector<RefPtr<Node> > m_nodes;
     };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to