WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Extracted helper function
bug-70436-20111020153241.patch (text/plain), 11.33 KB, created by
Adam Klein
on 2011-10-20 15:32:42 PDT
(
hide
)
Description:
Extracted helper function
Filename:
MIME Type:
Creator:
Adam Klein
Created:
2011-10-20 15:32:42 PDT
Size:
11.33 KB
patch
obsolete
>Subversion Revision: 98023 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index f66def9e97350ed5d5e3551cc7dc0837c51b5bfc..2fe520015083742931ca5923bb873faea34590ec 100755 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,29 @@ >+2011-10-20 Adam Klein <adamk@chromium.org> >+ >+ [MutationObservers] Implement basic subtree observation >+ https://bugs.webkit.org/show_bug.cgi?id=70436 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Note that this patch only implements "basic" subtree >+ semantics, not the fully robust semantics described in >+ http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/1622.html. >+ Most importantly, this change does not handle the case where mutations >+ occur in a temporarily detached subtree. >+ >+ The plan is to implement those semantics in a followup to avoid >+ blocking other parts of the MutationObserver spec that rely on >+ the existence of subtree observation but not its specific >+ implementation. >+ >+ Test: fast/mutation/observe-subtree.html >+ >+ * dom/Node.cpp: >+ (WebCore::addMatchingObservers): Static helper method for the below. >+ (WebCore::Node::registeredMutationObserversOfType): Walk up the tree looking for observers. >+ * dom/NodeRareData.h: >+ (WebCore::MutationObserverEntry::hasAllOptions): A stricter, renamed from matches(). >+ > 2011-10-20 Dan Bernstein <mitz@apple.com> > > Flipped-blocks writing mode blocks do not hit test their overflow >diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp >index 23ff7fe21a83f231eb68dc7cc2f4a4169dd6cc45..c1ab2ed97c462a3a9b1b48ef808282c1fa8def59 100644 >--- a/Source/WebCore/dom/Node.cpp >+++ b/Source/WebCore/dom/Node.cpp >@@ -2694,16 +2694,28 @@ Vector<MutationObserverEntry>* Node::mutationObserverEntries() > return hasRareData() ? rareData()->mutationObserverEntries() : 0; > } > >+static void addMatchingObservers(HashSet<WebKitMutationObserver*>& observerSet, Vector<MutationObserverEntry>* observerEntries, MutationObserverOptions options) >+{ >+ if (observerEntries) { >+ const size_t size = observerEntries->size(); >+ for (size_t i = 0; i < size; ++i) { >+ MutationObserverEntry& entry = observerEntries->at(i); >+ if (entry.hasAllOptions(options)) >+ observerSet.add(entry.observer.get()); >+ } >+ } >+} >+ > void Node::registeredMutationObserversOfType(Vector<WebKitMutationObserver*>& observers, WebKitMutationObserver::MutationType type) > { >- Vector<MutationObserverEntry>* observerEntries = mutationObserverEntries(); >- if (!observerEntries || observerEntries->isEmpty()) >- return; >+ HashSet<WebKitMutationObserver*> observerSet; >+ addMatchingObservers(observerSet, mutationObserverEntries(), type); >+ for (Node* node = parentNode(); node; node = node->parentNode()) >+ addMatchingObservers(observerSet, node->mutationObserverEntries(), type | WebKitMutationObserver::Subtree); > >- for (Vector<MutationObserverEntry>::iterator iter = observerEntries->begin(); iter != observerEntries->end(); ++iter) { >- if (iter->matches(type)) >- observers.append(iter->observer.get()); >- } >+ // FIXME: this method should output a HashSet instead of a Vector. >+ if (!observerSet.isEmpty()) >+ copyToVector(observerSet, observers); > } > > Node::MutationRegistrationResult Node::registerMutationObserver(PassRefPtr<WebKitMutationObserver> observer, MutationObserverOptions options) >diff --git a/Source/WebCore/dom/NodeRareData.h b/Source/WebCore/dom/NodeRareData.h >index e258afa4e26c0da206de648916df28a9d9faede6..502b658fc04bea687917175505e8c8a17027498b 100644 >--- a/Source/WebCore/dom/NodeRareData.h >+++ b/Source/WebCore/dom/NodeRareData.h >@@ -101,15 +101,14 @@ struct MutationObserverEntry { > return observer == other.observer; > } > >- bool matches(MutationObserverOptions options) const >+ bool hasAllOptions(MutationObserverOptions options) const > { >- return this->options & options; >+ return (this->options & options) == options; > } > > RefPtr<WebKitMutationObserver> observer; > MutationObserverOptions options; > }; >- > #endif // ENABLE(MUTATION_OBSERVERS) > > class NodeRareData { >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 30b8419ae80a89be43e7a5219328d91541cc1b48..474ae6bef219a05c9dd17ca08d575a5f2909bd77 100755 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2011-10-19 Adam Klein <adamk@chromium.org> >+ >+ [MutationObservers] Implement basic subtree observation >+ https://bugs.webkit.org/show_bug.cgi?id=70436 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/mutation/observe-subtree-expected.txt: Added. >+ * fast/mutation/observe-subtree.html: Added. >+ > 2011-10-20 Dan Bernstein <mitz@apple.com> > > Flipped-blocks writing mode blocks do not hit test their overflow >diff --git a/LayoutTests/fast/mutation/observe-subtree-expected.txt b/LayoutTests/fast/mutation/observe-subtree-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5527eb1ac30e0241247dd1a91273073eb46ea3af >--- /dev/null >+++ b/LayoutTests/fast/mutation/observe-subtree-expected.txt >@@ -0,0 +1,39 @@ >+Test WebKitMutationObserver.observe on a subtree >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+Testing basic aspects of subtree observation. >+...attribute and characterData changes in subtree >+PASS mutations.length is 2 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].target is subDiv >+PASS mutations[0].attributeName is "foo" >+PASS mutations[0].attributeNamespace is null >+PASS mutations[1].type is "characterData" >+PASS mutations[1].target is subDiv.firstChild >+ >+Testing two observers at different depths. >+PASS mutations.length is 1 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].target is subDiv >+PASS mutations[0].attributeName is "foo" >+PASS mutations[0].attributeNamespace is null >+PASS mutations2.length is 1 >+PASS mutations2[0].type is "attributes" >+PASS mutations2[0].target is subDiv >+PASS mutations2[0].attributeName is "foo" >+PASS mutations2[0].attributeNamespace is null >+ >+Testing one observer at two different depths. >+PASS calls is 1 >+PASS mutations.length is 1 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].target is subDiv >+PASS mutations[0].attributeName is "foo" >+PASS mutations[0].attributeNamespace is null >+ >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/fast/mutation/observe-subtree.html b/LayoutTests/fast/mutation/observe-subtree.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ac1fbc9c355c90e5210b6496c4123d797b759a2d >--- /dev/null >+++ b/LayoutTests/fast/mutation/observe-subtree.html >@@ -0,0 +1,160 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8"> >+<link rel="stylesheet" href="../js/resources/js-test-style.css"> >+<script src="../js/resources/js-test-pre.js"></script> >+<title></title> >+</head> >+<body> >+<p id=description></p> >+<div id="console"></div> >+<script> >+ >+window.jsTestIsAsync = true; >+var mutations; >+var mutations2; >+var div; >+var subDiv; >+var calls; >+ >+function testBasic() { >+ var observer; >+ >+ function start() { >+ debug('Testing basic aspects of subtree observation.'); >+ >+ mutations = null; >+ div = document.createElement('div'); >+ subDiv = div.appendChild(document.createElement('div')); >+ subDiv.innerHTML = 'hello, world'; >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ >+ observer.observe(div, {attributes: true, characterData: true, subtree: true}); >+ subDiv.setAttribute('foo', 'bar'); >+ subDiv.firstChild.textContent = 'goodbye!'; >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ debug('...attribute and characterData changes in subtree'); >+ >+ shouldBe('mutations.length', '2'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].target', 'subDiv'); >+ shouldBe('mutations[0].attributeName', '"foo"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations[1].type', '"characterData"'); >+ shouldBe('mutations[1].target', 'subDiv.firstChild'); >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ >+function testMultipleObservers() { >+ var observer; >+ var observer2; >+ >+ function start() { >+ debug('Testing two observers at different depths.'); >+ >+ mutations = null; >+ mutations2 = null; >+ div = document.createElement('div'); >+ subDiv = div.appendChild(document.createElement('div')); >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ observer2 = new WebKitMutationObserver(function(m) { >+ mutations2 = m; >+ }); >+ >+ observer.observe(div, {attributes: true, subtree: true}); >+ observer2.observe(subDiv, {attributes: true}); >+ subDiv.setAttribute('foo', 'bar'); >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ shouldBe('mutations.length', '1'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].target', 'subDiv'); >+ shouldBe('mutations[0].attributeName', '"foo"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations2.length', '1'); >+ shouldBe('mutations2[0].type', '"attributes"'); >+ shouldBe('mutations2[0].target', 'subDiv'); >+ shouldBe('mutations2[0].attributeName', '"foo"'); >+ shouldBe('mutations2[0].attributeNamespace', 'null'); >+ observer.disconnect(); >+ observer2.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ >+function testMultipleObservations() { >+ var observer; >+ >+ function start() { >+ debug('Testing one observer at two different depths.'); >+ >+ mutations = null; >+ calls = 0; >+ div = document.createElement('div'); >+ subDiv = div.appendChild(document.createElement('div')); >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ ++calls; >+ }); >+ >+ observer.observe(div, {attributes: true, subtree: true}); >+ observer.observe(subDiv, {attributes: true, subtree: true}); >+ subDiv.setAttribute('foo', 'bar'); >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ shouldBe('calls', '1'); >+ shouldBe('mutations.length', '1'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].target', 'subDiv'); >+ shouldBe('mutations[0].attributeName', '"foo"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+var tests = [testBasic, testMultipleObservers, testMultipleObservations]; >+var testIndex = 0; >+ >+function runNextTest() { >+ if (testIndex < tests.length) >+ tests[testIndex++](); >+ else >+ finishJSTest(); >+} >+ >+description('Test WebKitMutationObserver.observe on a subtree'); >+ >+if (!window.WebKitMutationObserver) >+ testFailed('This test requires ENABLE(MUTATION_OBSERVERS)'); >+else >+ runNextTest(); >+ >+var successfullyParsed = true; >+ >+</script> >+<script src="../js/resources/js-test-post.js"></script> >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 70436
:
111668
|
111856
|
112009
|
112033