WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-70860-20111104201429.patch (text/plain), 29.64 KB, created by
Rafael Weinstein
on 2011-11-04 20:14:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Rafael Weinstein
Created:
2011-11-04 20:14:30 PDT
Size:
29.64 KB
patch
obsolete
>Subversion Revision: 99349 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 52e9c5283c21370d0b7ca4f91eebb44386db8ae3..35b3afd94a1b13006fa83a610bb1244b3519a664 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,38 @@ >+2011-11-04 Rafael Weinstein <rafaelw@chromium.org> >+ >+ [MutationObservers] Support attributeFilter for attribute mutations >+ https://bugs.webkit.org/show_bug.cgi?id=70860 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch adds an attributeFilter to the MutationObserverRegistration and >+ adds support for only observing attributes whose name are in the provided >+ filter set (array of strings). >+ >+ Test: fast/mutation/observe-attributes.html. >+ >+ * bindings/js/JSWebKitMutationObserverCustom.cpp: >+ (WebCore::JSWebKitMutationObserver::observe): >+ * bindings/v8/OptionsObject.cpp: >+ (WebCore::OptionsObject::get): >+ * bindings/v8/OptionsObject.h: >+ * bindings/v8/custom/V8WebKitMutationObserverCustom.cpp: >+ (WebCore::V8WebKitMutationObserver::observeCallback): >+ * dom/Element.cpp: >+ (WebCore::enqueueAttributesMutationRecord): >+ * dom/MutationObserverRegistration.cpp: >+ (WebCore::MutationObserverRegistration::resetObservation): >+ (WebCore::MutationObserverRegistration::shouldReceiveMutationFrom): >+ (WebCore::MutationObserverRegistration::caseInsensitiveAttributeFilter): >+ * dom/MutationObserverRegistration.h: >+ * dom/Node.cpp: >+ (WebCore::Node::collectMatchingObserversForMutation): >+ (WebCore::Node::getRegisteredMutationObserversOfType): >+ * dom/Node.h: >+ * dom/WebKitMutationObserver.cpp: >+ (WebCore::WebKitMutationObserver::observe): >+ * dom/WebKitMutationObserver.h: >+ > 2011-11-04 Ben Wells <benwells@chromium.org> > > Canvas drawImage(canvas) with SourceIn, DestinationIn, SourceOut, DestinationAtop and Copy have errors >diff --git a/Source/WebCore/bindings/js/JSWebKitMutationObserverCustom.cpp b/Source/WebCore/bindings/js/JSWebKitMutationObserverCustom.cpp >index cd613ff160e577723f35cf22e51b1d618b50c321..eacec1423b697ef43fe9e16014ad661a5144066d 100644 >--- a/Source/WebCore/bindings/js/JSWebKitMutationObserverCustom.cpp >+++ b/Source/WebCore/bindings/js/JSWebKitMutationObserverCustom.cpp >@@ -78,6 +78,7 @@ JSValue JSWebKitMutationObserver::observe(ExecState* exec) > > JSDictionary dictionary(exec, optionsObject); > MutationObserverOptions options = 0; >+ // FIXME: Add support for parsing of the attributeFilter option. > bool option; > if (dictionary.tryGetProperty("childList", option) && option) > options |= WebKitMutationObserver::ChildList; >diff --git a/Source/WebCore/bindings/v8/OptionsObject.cpp b/Source/WebCore/bindings/v8/OptionsObject.cpp >index 69025ee32cf47635471f616bc1651e66ea0cc0d1..f80270d855e2c64444cf8cd64781eb919b79af54 100644 >--- a/Source/WebCore/bindings/v8/OptionsObject.cpp >+++ b/Source/WebCore/bindings/v8/OptionsObject.cpp >@@ -215,6 +215,25 @@ bool OptionsObject::get(const String& key, MessagePortArray& value) const > return getMessagePortArray(v8Value, value); > } > >+bool OptionsObject::get(const String& key, HashSet<AtomicString>& value) const >+{ >+ v8::Local<v8::Value> v8Value; >+ if (!getKey(key, v8Value)) >+ return false; >+ >+ // FIXME: Support array-like objects >+ if (!v8Value->IsArray()) >+ return false; >+ >+ v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value); >+ for (size_t i = 0; i < v8Array->Length(); ++i) { >+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Integer::New(i)); >+ value.add(v8ValueToWebCoreString(indexedValue)); >+ } >+ >+ return true; >+} >+ > bool OptionsObject::getWithUndefinedOrNullCheck(const String& key, String& value) const > { > v8::Local<v8::Value> v8Value; >diff --git a/Source/WebCore/bindings/v8/OptionsObject.h b/Source/WebCore/bindings/v8/OptionsObject.h >index 21d4e83506ed0927216d88632ac967607bdac40b..7c4e637648ad329d9e34227a94b1b1c35887a3f2 100644 >--- a/Source/WebCore/bindings/v8/OptionsObject.h >+++ b/Source/WebCore/bindings/v8/OptionsObject.h >@@ -30,6 +30,8 @@ > #include "PlatformString.h" > #include "ScriptValue.h" > #include <v8.h> >+#include <wtf/HashSet.h> >+#include <wtf/text/AtomicString.h> > > namespace WebCore { > >@@ -61,6 +63,7 @@ public: > #if ENABLE(VIDEO_TRACK) > bool get(const String&, RefPtr<TrackBase>&) const; > #endif >+ bool get(const String&, HashSet<AtomicString>&) const; > > bool getWithUndefinedOrNullCheck(const String&, String&) const; > >diff --git a/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp b/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp >index ef53eaf27ef1053ce70eade9d4c773cb43c34874..8df1aa2ab5c45eb364e0e0f612fdd2b19f7a0150 100644 >--- a/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp >+++ b/Source/WebCore/bindings/v8/custom/V8WebKitMutationObserverCustom.cpp >@@ -43,6 +43,10 @@ > #include "V8Node.h" > #include "V8Proxy.h" > #include "V8Utilities.h" >+#include "WebKitMutationObserver.h" >+ >+#include <wtf/HashSet.h> >+#include <wtf/text/AtomicString.h> > > namespace WebCore { > >@@ -89,11 +93,15 @@ v8::Handle<v8::Value> V8WebKitMutationObserver::observeCallback(const v8::Argume > > OptionsObject optionsObject(args[1]); > unsigned options = 0; >+ HashSet<AtomicString> attributeFilter; > bool option; > if (optionsObject.get("childList", option) && option) > options |= WebKitMutationObserver::ChildList; >- if (optionsObject.get("attributes", option) && option) >+ if (optionsObject.get("attributes", option) && option) { > options |= WebKitMutationObserver::Attributes; >+ if (optionsObject.get("attributeFilter", attributeFilter)) >+ options |= WebKitMutationObserver::AttributeFilter; >+ } > if (optionsObject.get("characterData", option) && option) > options |= WebKitMutationObserver::CharacterData; > if (optionsObject.get("subtree", option) && option) >@@ -103,7 +111,7 @@ v8::Handle<v8::Value> V8WebKitMutationObserver::observeCallback(const v8::Argume > if (optionsObject.get("characterDataOldValue", option) && option) > options |= WebKitMutationObserver::CharacterDataOldValue; > >- imp->observe(target, options); >+ imp->observe(target, options, attributeFilter); > return v8::Handle<v8::Value>(); > } > >diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp >index 62c3eaf1be45e46c3ebf6f87d745efd6dc8b6ff7..e8fb63bd6df5e2b7332c4260bbe41aba66cd5fa2 100644 >--- a/Source/WebCore/dom/Element.cpp >+++ b/Source/WebCore/dom/Element.cpp >@@ -634,7 +634,7 @@ static inline bool isOldValueRequested(const HashMap<WebKitMutationObserver*, Mu > static void enqueueAttributesMutationRecord(Element* element, const QualifiedName& name, const AtomicString& oldValue) > { > HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions> observers; >- element->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::Attributes); >+ element->getRegisteredMutationObserversOfType(observers, WebKitMutationObserver::Attributes, name.localName()); > if (observers.isEmpty()) > return; > >diff --git a/Source/WebCore/dom/MutationObserverRegistration.cpp b/Source/WebCore/dom/MutationObserverRegistration.cpp >index 6b21b196e0696ef22166c85af08ece6230308453..c6153c55e8816c45f84023900ce9eff78f29cb33 100644 >--- a/Source/WebCore/dom/MutationObserverRegistration.cpp >+++ b/Source/WebCore/dom/MutationObserverRegistration.cpp >@@ -58,10 +58,12 @@ MutationObserverRegistration::~MutationObserverRegistration() > m_observer->observationEnded(this); > } > >-void MutationObserverRegistration::resetObservation(MutationObserverOptions options) >+void MutationObserverRegistration::resetObservation(MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter) > { > clearTransientRegistrations(); > m_options = options; >+ m_attributeFilter = attributeFilter; >+ m_caseInsensitiveAttributeFilter.clear(); > } > > void MutationObserverRegistration::observedSubtreeNodeWillDetach(PassRefPtr<Node> node) >@@ -102,7 +104,7 @@ void MutationObserverRegistration::unregister() > // The above line will cause this object to be deleted, so don't do any more in this function. > } > >-bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, WebKitMutationObserver::MutationType type) >+bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, WebKitMutationObserver::MutationType type, const AtomicString& attributeName) > { > if (!(m_options & type)) > return false; >@@ -110,7 +112,31 @@ bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, WebKitM > if (m_registrationNode != node && !(m_options & WebKitMutationObserver::Subtree)) > return false; > >- return true; >+ if (type != WebKitMutationObserver::Attributes || !(m_options & WebKitMutationObserver::AttributeFilter)) >+ return true; >+ >+ if (m_attributeFilter.contains(attributeName)) >+ return true; >+ >+ if (node->document()->isHTMLDocument() && node->isHTMLElement()) >+ return caseInsensitiveAttributeFilter().contains(attributeName); >+ >+ return false; >+} >+ >+const HashSet<AtomicString>& MutationObserverRegistration::caseInsensitiveAttributeFilter() >+{ >+ if (m_caseInsensitiveAttributeFilter) >+ return *m_caseInsensitiveAttributeFilter; >+ >+ m_caseInsensitiveAttributeFilter = adoptPtr(new HashSet<AtomicString>()); >+ for (HashSet<AtomicString>::const_iterator iter = m_attributeFilter.begin(); iter != m_attributeFilter.end(); ++iter) { >+ AtomicString attributeNameLower = iter->lower(); >+ if ((*iter) != attributeNameLower) >+ m_caseInsensitiveAttributeFilter->add(attributeNameLower); >+ } >+ >+ return *m_caseInsensitiveAttributeFilter; > } > > } // namespace WebCore >diff --git a/Source/WebCore/dom/MutationObserverRegistration.h b/Source/WebCore/dom/MutationObserverRegistration.h >index 2b822211be3d0a36ed540329653e4660c32481b2..6f65003b70a26c80c254ff5eb182ce9c8876ab45 100644 >--- a/Source/WebCore/dom/MutationObserverRegistration.h >+++ b/Source/WebCore/dom/MutationObserverRegistration.h >@@ -47,12 +47,12 @@ public: > > ~MutationObserverRegistration(); > >- void resetObservation(MutationObserverOptions); >+ void resetObservation(MutationObserverOptions, const HashSet<AtomicString>& attributeFilter); > void observedSubtreeNodeWillDetach(PassRefPtr<Node>); > void clearTransientRegistrations(); > void unregister(); > >- bool shouldReceiveMutationFrom(Node*, WebKitMutationObserver::MutationType); >+ bool shouldReceiveMutationFrom(Node*, WebKitMutationObserver::MutationType, const AtomicString& attributeName); > > WebKitMutationObserver* observer() { return m_observer.get(); } > MutationRecordDeliveryOptions deliveryOptions() { return m_options & (WebKitMutationObserver::AttributeOldValue | WebKitMutationObserver::CharacterDataOldValue); } >@@ -60,6 +60,8 @@ public: > private: > MutationObserverRegistration(PassRefPtr<WebKitMutationObserver>, Node*); > >+ const HashSet<AtomicString>& caseInsensitiveAttributeFilter(); >+ > RefPtr<WebKitMutationObserver> m_observer; > Node* m_registrationNode; > RefPtr<Node> m_registrationNodeKeepAlive; >@@ -67,6 +69,8 @@ private: > OwnPtr<NodeHashSet> m_transientRegistrationNodes; > > MutationObserverOptions m_options; >+ HashSet<AtomicString> m_attributeFilter; >+ OwnPtr<HashSet<AtomicString> >m_caseInsensitiveAttributeFilter; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp >index b76b6d65b459486907bb4d76cf8bfd498eb1dae2..14928e243f21007d0329072a26e22d423f1f8566 100644 >--- a/Source/WebCore/dom/Node.cpp >+++ b/Source/WebCore/dom/Node.cpp >@@ -2703,13 +2703,13 @@ HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry( > return hasRareData() ? rareData()->transientMutationObserverRegistry() : 0; > } > >-void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, Node* fromNode, WebKitMutationObserver::MutationType type) >+void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, Node* fromNode, WebKitMutationObserver::MutationType type, const AtomicString& attributeName) > { > if (Vector<OwnPtr<MutationObserverRegistration> >* registry = fromNode->mutationObserverRegistry()) { > const size_t size = registry->size(); > for (size_t i = 0; i < size; ++i) { > MutationObserverRegistration* registration = registry->at(i).get(); >- if (registration->shouldReceiveMutationFrom(this, type)) { >+ if (registration->shouldReceiveMutationFrom(this, type, attributeName)) { > MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions(); > pair<HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator, bool> result = observers.add(registration->observer(), deliveryOptions); > if (!result.second) >@@ -2722,7 +2722,7 @@ void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, > if (HashSet<MutationObserverRegistration*>* transientRegistry = fromNode->transientMutationObserverRegistry()) { > for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) { > MutationObserverRegistration* registration = *iter; >- if (registration->shouldReceiveMutationFrom(this, type)) { >+ if (registration->shouldReceiveMutationFrom(this, type, attributeName)) { > MutationRecordDeliveryOptions deliveryOptions = registration->deliveryOptions(); > pair<HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>::iterator, bool> result = observers.add(registration->observer(), deliveryOptions); > if (!result.second) >@@ -2732,10 +2732,10 @@ void Node::collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, > } > } > >-void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type) >+void Node::getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>& observers, WebKitMutationObserver::MutationType type, const AtomicString& attributeName) > { > for (Node* node = this; node; node = node->parentNode()) >- collectMatchingObserversForMutation(observers, node, type); >+ collectMatchingObserversForMutation(observers, node, type, attributeName); > } > > MutationObserverRegistration* Node::registerMutationObserver(PassRefPtr<WebKitMutationObserver> observer) >diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h >index 548bc8a443d78aec5a00201a57401dec402b03ee..6b66c81d049283eed63442596d78d83d35545b77 100644 >--- a/Source/WebCore/dom/Node.h >+++ b/Source/WebCore/dom/Node.h >@@ -591,7 +591,7 @@ public: > #endif > > #if ENABLE(MUTATION_OBSERVERS) >- void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType); >+ void getRegisteredMutationObserversOfType(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, WebKitMutationObserver::MutationType, const AtomicString& attributeName = nullAtom); > MutationObserverRegistration* registerMutationObserver(PassRefPtr<WebKitMutationObserver>); > void unregisterMutationObserver(MutationObserverRegistration*); > void registerTransientMutationObserver(MutationObserverRegistration*); >@@ -725,7 +725,7 @@ private: > #if ENABLE(MUTATION_OBSERVERS) > Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry(); > HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry(); >- void collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, Node* fromNode, WebKitMutationObserver::MutationType); >+ void collectMatchingObserversForMutation(HashMap<WebKitMutationObserver*, MutationRecordDeliveryOptions>&, Node* fromNode, WebKitMutationObserver::MutationType, const AtomicString& attributeName); > #endif > > mutable uint32_t m_nodeFlags; >diff --git a/Source/WebCore/dom/WebKitMutationObserver.cpp b/Source/WebCore/dom/WebKitMutationObserver.cpp >index 0c7cbfc240d19e19cc1965def78a265750b6e760..755ac6a0de939c05cba8623d737f69946156a30b 100644 >--- a/Source/WebCore/dom/WebKitMutationObserver.cpp >+++ b/Source/WebCore/dom/WebKitMutationObserver.cpp >@@ -57,10 +57,10 @@ WebKitMutationObserver::~WebKitMutationObserver() > ASSERT(m_registrations.isEmpty()); > } > >-void WebKitMutationObserver::observe(Node* node, MutationObserverOptions options) >+void WebKitMutationObserver::observe(Node* node, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter) > { > MutationObserverRegistration* registration = node->registerMutationObserver(this); >- registration->resetObservation(options); >+ registration->resetObservation(options, attributeFilter); > } > > void WebKitMutationObserver::disconnect() >diff --git a/Source/WebCore/dom/WebKitMutationObserver.h b/Source/WebCore/dom/WebKitMutationObserver.h >index fe6e6e27e09a61473ffd82e4d7aeadee77ca3db9..c33a9a4a05ff3cbe8c1031c1bf9c1e9b37ffc310 100644 >--- a/Source/WebCore/dom/WebKitMutationObserver.h >+++ b/Source/WebCore/dom/WebKitMutationObserver.h >@@ -73,7 +73,7 @@ public: > > ~WebKitMutationObserver(); > >- void observe(Node*, MutationObserverOptions); >+ void observe(Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter); > void disconnect(); > void observationStarted(MutationObserverRegistration*); > void observationEnded(MutationObserverRegistration*); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index e14ca6d5a0505181b90f8f6f310fa01a484534c4..511c030cb15541cd5bc6a4ccca07421ef7dbcfc0 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2011-11-04 Rafael Weinstein <rafaelw@chromium.org> >+ >+ [MutationObservers] Support attributeFilter for attribute mutations >+ https://bugs.webkit.org/show_bug.cgi?id=70860 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/mutation/observe-attributes-expected.txt: >+ * fast/mutation/observe-attributes.html: >+ > 2011-11-04 Ben Wells <benwells@chromium.org> > > Canvas drawImage(canvas) with SourceIn, DestinationIn, SourceOut, DestinationAtop and Copy have errors >diff --git a/LayoutTests/fast/mutation/observe-attributes-expected.txt b/LayoutTests/fast/mutation/observe-attributes-expected.txt >index 9bb07e9530fa7540a990edb07c3ea47b605d35bc..679e90586a88da1f965dfb7656536db44deeedc1 100644 >--- a/LayoutTests/fast/mutation/observe-attributes-expected.txt >+++ b/LayoutTests/fast/mutation/observe-attributes-expected.txt >@@ -92,6 +92,66 @@ PASS mutations[1].type is "attributes" > PASS mutations[1].attributeName is "id" > PASS mutations[1].oldValue is "foo" > >+Testing that attributeFilter works as expected and ignores case with HTML elements. >+...only foo, bar & boom should be received. >+PASS mutations.length is 3 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].attributeName is "foo" >+PASS mutations[0].attributeNamespace is null >+PASS mutations[1].type is "attributes" >+PASS mutations[1].attributeName is "bar" >+PASS mutations[1].attributeNamespace is null >+PASS mutations[2].type is "attributes" >+PASS mutations[2].attributeName is "boom" >+PASS mutations[2].attributeNamespace is null >+ >+Testing the behavior of attributeFilter when the same observer observes at multiple nodes in a subtree with different filter options. >+...only foo, bar & bat should be received. >+PASS mutations.length is 3 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].attributeName is "foo" >+PASS mutations[0].attributeNamespace is null >+PASS mutations[1].type is "attributes" >+PASS mutations[1].attributeName is "bar" >+PASS mutations[1].attributeNamespace is null >+PASS mutations[2].type is "attributes" >+PASS mutations[2].attributeName is "bat" >+PASS mutations[2].attributeNamespace is null >+...bar, bat & baz should all be received. >+PASS mutations.length is 3 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].attributeName is "bar" >+PASS mutations[0].attributeNamespace is null >+PASS mutations[1].type is "attributes" >+PASS mutations[1].attributeName is "bat" >+PASS mutations[1].attributeNamespace is null >+PASS mutations[2].type is "attributes" >+PASS mutations[2].attributeName is "baz" >+PASS mutations[2].attributeNamespace is null >+ >+Testing that attributeFilter respects case with non-HTML elements. >+...pathLength should be received. >+PASS mutations.length is 1 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].attributeName is "pathLength" >+PASS mutations[0].attributeNamespace is "http://www.w3.org/2000/svg" >+ >+Testing that attributeFilter respects case with non-HTML elements. >+...only ID, id, booM, pathLength should be received. >+PASS mutations.length is 4 >+PASS mutations[0].type is "attributes" >+PASS mutations[0].attributeName is "ID" >+PASS mutations[0].attributeNamespace is null >+PASS mutations[1].type is "attributes" >+PASS mutations[1].attributeName is "id" >+PASS mutations[1].attributeNamespace is null >+PASS mutations[2].type is "attributes" >+PASS mutations[2].attributeName is "booM" >+PASS mutations[2].attributeNamespace is null >+PASS mutations[3].type is "attributes" >+PASS mutations[3].attributeName is "pathLength" >+PASS mutations[3].attributeNamespace is "http://www.w3.org/2000/svg" >+ > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/fast/mutation/observe-attributes.html b/LayoutTests/fast/mutation/observe-attributes.html >index 395af7984581bd6a5f821cbce155afa66bdf419c..af58b518b512b08e79da0de8de4675934500198e 100644 >--- a/LayoutTests/fast/mutation/observe-attributes.html >+++ b/LayoutTests/fast/mutation/observe-attributes.html >@@ -107,7 +107,7 @@ function testMultipleRegistration() { > > function start() { > debug('Testing that re-observing the same node with the same observer has the effect of resetting the options.'); >- >+ > calls = 0; > mutations = null; > div = document.createElement('div'); >@@ -435,6 +435,209 @@ function testIDLAttribute() { > start(); > } > >+function testAttributeFilter() { >+ var div, path; >+ var observer; >+ >+ function start() { >+ debug('Testing that attributeFilter works as expected and ignores case with HTML elements.'); >+ >+ mutations = null; >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ >+ div = document.createElement('div'); >+ observer.observe(div, { attributes: true, attributeFilter: ['foo', 'bar', 'booM'] }); >+ div.setAttribute('foo', 'foo'); >+ div.setAttribute('bar', 'bar'); >+ div.setAttribute('baz', 'baz'); >+ div.setAttribute('BOOm', 'boom'); >+ >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ debug('...only foo, bar & boom should be received.'); >+ >+ shouldBe('mutations.length', '3'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].attributeName', '"foo"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations[1].type', '"attributes"'); >+ shouldBe('mutations[1].attributeName', '"bar"'); >+ shouldBe('mutations[1].attributeNamespace', 'null'); >+ shouldBe('mutations[2].type', '"attributes"'); >+ shouldBe('mutations[2].attributeName', '"boom"'); >+ shouldBe('mutations[2].attributeNamespace', 'null'); >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ >+function testAttributeFilterSubtree() { >+ var div, div2, div3; >+ var observer; >+ >+ function start() { >+ debug('Testing the behavior of attributeFilter when the same observer observes at multiple nodes in a subtree with different filter options.'); >+ >+ mutations = null; >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ >+ div = document.createElement('div'); >+ div2 = div.appendChild(document.createElement('div')); >+ div3 = div2.appendChild(document.createElement('div')); >+ >+ observer.observe(div, { attributes: true, subtree: true, attributeFilter: ['foo', 'bar'] }); >+ observer.observe(div2, { attributes: true, subtree: true, attributeFilter: ['bar', 'bat'] }); >+ >+ div3.setAttribute('foo', 'foo'); >+ div3.setAttribute('bar', 'bar'); >+ div3.setAttribute('bat', 'bat'); >+ div3.setAttribute('baz', 'baz'); >+ >+ setTimeout(checkAndObserveAll, 0); >+ } >+ >+ function checkAndObserveAll() { >+ debug('...only foo, bar & bat should be received.'); >+ >+ shouldBe('mutations.length', '3'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].attributeName', '"foo"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations[1].type', '"attributes"'); >+ shouldBe('mutations[1].attributeName', '"bar"'); >+ shouldBe('mutations[1].attributeNamespace', 'null'); >+ shouldBe('mutations[2].type', '"attributes"'); >+ shouldBe('mutations[2].attributeName', '"bat"'); >+ shouldBe('mutations[2].attributeNamespace', 'null'); >+ >+ observer.observe(div2, { attributes: true, subtree: true }); >+ div3.setAttribute('bar', 'bar'); >+ div3.setAttribute('bat', 'bat'); >+ div3.setAttribute('baz', 'baz'); >+ >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ debug('...bar, bat & baz should all be received.'); >+ >+ shouldBe('mutations.length', '3'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].attributeName', '"bar"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations[1].type', '"attributes"'); >+ shouldBe('mutations[1].attributeName', '"bat"'); >+ shouldBe('mutations[1].attributeNamespace', 'null'); >+ shouldBe('mutations[2].type', '"attributes"'); >+ shouldBe('mutations[2].attributeName', '"baz"'); >+ shouldBe('mutations[2].attributeNamespace', 'null'); >+ >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ >+function testAttributeFilterNonHTMLElement() { >+ var path; >+ var observer; >+ >+ function start() { >+ debug('Testing that attributeFilter respects case with non-HTML elements.'); >+ >+ mutations = null; >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ >+ path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); >+ observer.observe(path, { attributes: true, attributeFilter: ['pathLength'] }); >+ path.setAttributeNS('http://www.w3.org/2000/svg', 'pathLength', '200'); >+ path.setAttributeNS('http://www.w3.org/2000/svg', 'pathlength', '200'); >+ >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ debug('...pathLength should be received.'); >+ >+ shouldBe('mutations.length', '1'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].attributeName', '"pathLength"'); >+ shouldBe('mutations[0].attributeNamespace', '"http://www.w3.org/2000/svg"'); >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ >+function testAttributeFilterNonHTMLDocument() { >+ var svgDoc, div, path; >+ var observer; >+ >+ function start() { >+ debug('Testing that attributeFilter respects case with non-HTML elements.'); >+ >+ svgDoc = document.implementation.createDocument('http://www.w3.org/2000/svg', 'svg', 'svg'); >+ mutations = null; >+ observer = new WebKitMutationObserver(function(m) { >+ mutations = m; >+ }); >+ >+ div = svgDoc.createElement('div'); >+ observer.observe(div, { attributes: true, attributeFilter: ['ID', 'id', 'booM'] }); >+ div.setAttribute('ID', 'ID'); >+ div.setAttribute('id', 'id'); >+ div.setAttribute('baz', 'baz'); >+ div.setAttribute('booM', 'boom'); >+ div.setAttribute('BOOm', 'boom'); >+ >+ path = svgDoc.createElementNS('http://www.w3.org/2000/svg', 'path'); >+ observer.observe(path, { attributes: true, attributeFilter: ['pathLength'] }); >+ path.setAttributeNS('http://www.w3.org/2000/svg', 'pathLength', '200'); >+ path.setAttributeNS('http://www.w3.org/2000/svg', 'pathlength', '200'); >+ >+ setTimeout(finish, 0); >+ } >+ >+ function finish() { >+ debug('...only ID, id, booM, pathLength should be received.'); >+ >+ shouldBe('mutations.length', '4'); >+ shouldBe('mutations[0].type', '"attributes"'); >+ shouldBe('mutations[0].attributeName', '"ID"'); >+ shouldBe('mutations[0].attributeNamespace', 'null'); >+ shouldBe('mutations[1].type', '"attributes"'); >+ shouldBe('mutations[1].attributeName', '"id"'); >+ shouldBe('mutations[1].attributeNamespace', 'null'); >+ shouldBe('mutations[2].type', '"attributes"'); >+ shouldBe('mutations[2].attributeName', '"booM"'); >+ shouldBe('mutations[2].attributeNamespace', 'null'); >+ shouldBe('mutations[3].type', '"attributes"'); >+ shouldBe('mutations[3].attributeName', '"pathLength"'); >+ shouldBe('mutations[3].attributeNamespace', '"http://www.w3.org/2000/svg"'); >+ >+ observer.disconnect(); >+ debug(''); >+ runNextTest(); >+ } >+ >+ start(); >+} >+ > var tests = [ > testBasic, > testWrongType, >@@ -446,7 +649,11 @@ var tests = [ > testOldValue, > testOldValueAsRequested, > testOldValueUnionMultipleObservations, >- testIDLAttribute >+ testIDLAttribute, >+ testAttributeFilter, >+ testAttributeFilterSubtree, >+ testAttributeFilterNonHTMLElement, >+ testAttributeFilterNonHTMLDocument > ]; > var testIndex = 0; >
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 70860
:
112960
|
113083
|
113366
|
113582
|
113602
|
113748
|
114168