Title: [97805] trunk
Revision
97805
Author
[email protected]
Date
2011-10-18 16:06:48 -0700 (Tue, 18 Oct 2011)

Log Message

[MutationObservers] Implement WebKitMutationObserver.observe for characterData changes
https://bugs.webkit.org/show_bug.cgi?id=68957

Reviewed by Ryosuke Niwa.

Source/WebCore:

Test: fast/mutation/observe-characterdata.html

* dom/CharacterData.cpp:
(WebCore::CharacterData::dispatchModifiedEvent):

LayoutTests:

* fast/mutation/observe-characterdata-expected.txt: Added.
* fast/mutation/observe-characterdata.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (97804 => 97805)


--- trunk/LayoutTests/ChangeLog	2011-10-18 23:06:31 UTC (rev 97804)
+++ trunk/LayoutTests/ChangeLog	2011-10-18 23:06:48 UTC (rev 97805)
@@ -1,3 +1,13 @@
+2011-10-18  Adam Klein  <[email protected]>
+
+        [MutationObservers] Implement WebKitMutationObserver.observe for characterData changes
+        https://bugs.webkit.org/show_bug.cgi?id=68957
+
+        Reviewed by Ryosuke Niwa.
+
+        * fast/mutation/observe-characterdata-expected.txt: Added.
+        * fast/mutation/observe-characterdata.html: Added.
+
 2011-10-18  Dirk Pranke  <[email protected]>
 
         Remove expectations for tests that are no longer failing.

Added: trunk/LayoutTests/fast/mutation/observe-characterdata-expected.txt (0 => 97805)


--- trunk/LayoutTests/fast/mutation/observe-characterdata-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mutation/observe-characterdata-expected.txt	2011-10-18 23:06:48 UTC (rev 97805)
@@ -0,0 +1,39 @@
+Test WebKitMutationObserver.observe on CharacterData nodes
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing basic aspects of characterData observation.
+...can characterData changes be observed at all
+PASS mutations.length is 1
+PASS mutations[0].type is "characterData"
+PASS mutations[0].target is charDataNode
+...observer.disconnect() should prevent further delivery of mutations.
+PASS mutations is null
+...re-observing after disconnect works with the same observer.
+PASS mutations.length is 2
+PASS mutations[0].type is "characterData"
+PASS mutations[0].target is charDataNode
+PASS mutations[1].type is "characterData"
+PASS mutations[1].target is charDataNode
+
+Testing that observing without specifying "characterData" does not result in hearing about characterData changes.
+PASS mutations is null
+
+Testing that multiple observers can be registered to a given node and both receive mutations.
+PASS mutations.length is 1
+PASS mutations[0].type is "characterData"
+PASS mutations[0].target is charDataNode
+PASS mutations2.length is 1
+PASS mutations2[0].type is "characterData"
+PASS mutations2[0].target is charDataNode
+
+Testing mutation records are enqueued for characterData before DOMSubtreeModified is dispatched.
+PASS mutations.length is 2
+PASS mutations[0].type is "characterData"
+PASS mutations[1].type is "attributes"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/mutation/observe-characterdata.html (0 => 97805)


--- trunk/LayoutTests/fast/mutation/observe-characterdata.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mutation/observe-characterdata.html	2011-10-18 23:06:48 UTC (rev 97805)
@@ -0,0 +1,218 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href=""
+<script src=""
+<title></title>
+</head>
+<body>
+<p id=description></p>
+<div id="console"></div>
+<script>
+
+window.jsTestIsAsync = true;
+var mutations;
+var mutations2;
+var calls;
+var charDataNode;
+
+function testBasic() {
+    var div;
+    var observer;
+
+    function start() {
+        debug('Testing basic aspects of characterData observation.');
+
+        mutations = null;
+        div = document.createElement('div');
+        div.textContent = 'foo';
+        charDataNode = div.firstChild;
+        observer = new WebKitMutationObserver(function(m) {
+            mutations = m;
+        });
+
+        observer.observe(charDataNode, {characterData: true});
+        charDataNode.textContent = 'bar';
+        setTimeout(checkDisconnectAndMutate, 0);
+    }
+
+    function checkDisconnectAndMutate() {
+        debug('...can characterData changes be observed at all');
+
+        shouldBe('mutations.length', '1');
+        shouldBe('mutations[0].type', '"characterData"');
+        shouldBe('mutations[0].target', 'charDataNode');
+
+        mutations = null;
+        observer.disconnect();
+        charDataNode.textContent = 'baz';
+        setTimeout(checkNotDeliveredAndMutateMultiple, 0);
+    }
+
+    function checkNotDeliveredAndMutateMultiple() {
+        debug('...observer.disconnect() should prevent further delivery of mutations.');
+
+        shouldBe('mutations', 'null');
+        charDataNode = document.createComment();
+        observer.observe(charDataNode, { characterData: true });
+        charDataNode.textContent = 'foo';
+        charDataNode.textContent = 'bar';
+        setTimeout(finish);
+    }
+
+    function finish() {
+        debug('...re-observing after disconnect works with the same observer.');
+
+        shouldBe('mutations.length', '2');
+        shouldBe('mutations[0].type', '"characterData"');
+        shouldBe('mutations[0].target', 'charDataNode');
+        shouldBe('mutations[1].type', '"characterData"');
+        shouldBe('mutations[1].target', 'charDataNode');
+        observer.disconnect();
+        debug('');
+        runNextTest();
+    }
+
+    start();
+}
+
+function testWrongType() {
+    var div;
+    var observer;
+
+    function start() {
+        debug('Testing that observing without specifying "characterData" does not result in hearing about characterData changes.');
+
+        mutations = null;
+        div = document.createElement('div');
+        div.textContent = 'hello';
+        charDataNode = div.firstChild;
+        observer = new WebKitMutationObserver(function(m) {
+            mutations = m;
+        });
+
+        observer.observe(charDataNode, {childList: true, attributes: true});
+        charDataNode = 'goodbye';
+        setTimeout(finish, 0);
+    }
+
+    function finish() {
+        shouldBe('mutations', 'null');
+        observer.disconnect();
+        debug('');
+        runNextTest();
+    }
+
+    start();
+}
+
+function testMultipleObservers() {
+    var div;
+    var observer;
+    var observer2;
+
+    function start() {
+        debug('Testing that multiple observers can be registered to a given node and both receive mutations.');
+        mutations = null;
+        div = document.createElement('div');
+        div.textContent = 'foo';
+        charDataNode = div.firstChild;
+        observer = new WebKitMutationObserver(function(m) {
+            mutations = m;
+        });
+        observer2 = new WebKitMutationObserver(function(m) {
+            mutations2 = m;
+        });
+        observer.observe(charDataNode, {characterData: true});
+        observer2.observe(charDataNode, {characterData: true});
+        charDataNode.textContent = 'bar';
+        setTimeout(finish, 0);
+    }
+
+    function finish() {
+        shouldBe('mutations.length', '1');
+        shouldBe('mutations[0].type', '"characterData"');
+        shouldBe('mutations[0].target', 'charDataNode');
+        shouldBe('mutations2.length', '1');
+        shouldBe('mutations2[0].type', '"characterData"');
+        shouldBe('mutations2[0].target', 'charDataNode');
+        observer.disconnect();
+        observer2.disconnect();
+        debug('');
+        runNextTest();
+    }
+
+    start();
+}
+
+function testOrderingWrtDOMSubtreeModified() {
+    var div, div2, subDiv;
+    var observer;
+    var listener;
+
+    function start() {
+        debug('Testing mutation records are enqueued for characterData before DOMSubtreeModified is dispatched.');
+
+        mutations = null;
+        div = document.body.appendChild(document.createElement('div'));
+        div2 = document.body.appendChild(document.createElement('div'));
+
+        subDiv = div.appendChild(document.createElement('div'));
+        subDiv.textContent = 'foo';
+        charDataNode = subDiv.firstChild;
+
+        observer = new WebKitMutationObserver(function(m) {
+            mutations = m;
+        });
+
+        listener = function(e) {
+            div2.setAttribute('baz', 'bat');
+        }
+
+        div.addEventListener('DOMSubtreeModified', listener);
+        observer.observe(charDataNode, {characterData: true});
+        observer.observe(div2, {attributes: true});
+
+        charDataNode.textContent = 'bar';
+
+        setTimeout(finish, 0);
+    }
+
+    function finish() {
+        shouldBe('mutations.length', '2');
+        shouldBe('mutations[0].type', '"characterData"');
+        shouldBe('mutations[1].type', '"attributes"');
+        div.removeEventListener(listener);
+        document.body.removeChild(div);
+        observer.disconnect();
+        debug('');
+        runNextTest();
+    }
+
+    start();
+}
+
+var tests = [testBasic, testWrongType, testMultipleObservers, testOrderingWrtDOMSubtreeModified];
+var testIndex = 0;
+
+function runNextTest() {
+    if (testIndex < tests.length)
+        tests[testIndex++]();
+    else
+        finishJSTest();
+}
+
+description('Test WebKitMutationObserver.observe on CharacterData nodes');
+
+if (!window.WebKitMutationObserver)
+    testFailed('This test requires ENABLE(MUTATION_OBSERVERS)');
+else
+    runNextTest();
+
+var successfullyParsed = true;
+
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (97804 => 97805)


--- trunk/Source/WebCore/ChangeLog	2011-10-18 23:06:31 UTC (rev 97804)
+++ trunk/Source/WebCore/ChangeLog	2011-10-18 23:06:48 UTC (rev 97805)
@@ -1,3 +1,15 @@
+2011-10-18  Adam Klein  <[email protected]>
+
+        [MutationObservers] Implement WebKitMutationObserver.observe for characterData changes
+        https://bugs.webkit.org/show_bug.cgi?id=68957
+
+        Reviewed by Ryosuke Niwa.
+
+        Test: fast/mutation/observe-characterdata.html
+
+        * dom/CharacterData.cpp:
+        (WebCore::CharacterData::dispatchModifiedEvent):
+
 2011-10-18  Scott Byer  <[email protected]>
 
         Scroll animator tracing

Modified: trunk/Source/WebCore/dom/CharacterData.cpp (97804 => 97805)


--- trunk/Source/WebCore/dom/CharacterData.cpp	2011-10-18 23:06:31 UTC (rev 97804)
+++ trunk/Source/WebCore/dom/CharacterData.cpp	2011-10-18 23:06:48 UTC (rev 97805)
@@ -27,9 +27,11 @@
 #include "ExceptionCode.h"
 #include "InspectorInstrumentation.h"
 #include "MutationEvent.h"
+#include "MutationRecord.h"
 #include "NodeRenderingContext.h"
 #include "RenderText.h"
 #include "TextBreakIterator.h"
+#include "WebKitMutationObserver.h"
 
 using namespace std;
 
@@ -190,6 +192,15 @@
 
 void CharacterData::dispatchModifiedEvent(StringImpl* oldData)
 {
+#if ENABLE(MUTATION_OBSERVERS)
+    Vector<WebKitMutationObserver*> observers;
+    registeredMutationObserversOfType(observers, WebKitMutationObserver::CharacterData);
+    if (!observers.isEmpty()) {
+        RefPtr<MutationRecord> mutation = MutationRecord::createCharacterData(this);
+        for (size_t i = 0; i < observers.size(); ++i)
+            observers[i]->enqueueMutationRecord(mutation);
+    }
+#endif
     if (parentNode())
         parentNode()->childrenChanged();
     if (document()->hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to