Diff
Modified: trunk/LayoutTests/ChangeLog (200551 => 200552)
--- trunk/LayoutTests/ChangeLog 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/LayoutTests/ChangeLog 2016-05-08 06:39:23 UTC (rev 200552)
@@ -1,3 +1,14 @@
+2016-05-07 Darin Adler <[email protected]>
+
+ Change MutationObserver::observe to take an IDL dictionary, rather than WebCore::Dictionary
+ https://bugs.webkit.org/show_bug.cgi?id=157456
+
+ Reviewed by Chris Dumez.
+
+ * fast/dom/MutationObserver/observe-exceptions-expected.txt: Updated to expect
+ the specific TypeError generated by the bindings code rather than the generic
+ TypeError we got before generated inside the C++ DOM.
+
2016-05-07 Joanmarie Diggs <[email protected]>
REGRESSION(r196222): [AX][GTK] accessibility/gtk/caret-offsets.html failing
Modified: trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt (200551 => 200552)
--- trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt 2016-05-08 06:39:23 UTC (rev 200552)
@@ -7,8 +7,8 @@
PASS observer.observe(null) threw exception TypeError: Not enough arguments.
PASS observer.observe(undefined) threw exception TypeError: Not enough arguments.
PASS observer.observe(document.body) threw exception TypeError: Not enough arguments.
-PASS observer.observe(document.body, null) threw exception TypeError: Type error.
-PASS observer.observe(document.body, undefined) threw exception TypeError: Type error.
+PASS observer.observe(document.body, null) threw exception TypeError: null is not an object (evaluating 'observer.observe(document.body, null)').
+PASS observer.observe(document.body, undefined) threw exception TypeError: undefined is not an object (evaluating 'observer.observe(document.body, undefined)').
PASS observer.observe(null, {attributes: true}) threw exception TypeError: Type error.
PASS observer.observe(undefined, {attributes: true}) threw exception TypeError: Type error.
PASS observer.observe(document.body, {subtree: true}) threw exception TypeError: Type error.
Modified: trunk/Source/WebCore/ChangeLog (200551 => 200552)
--- trunk/Source/WebCore/ChangeLog 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/ChangeLog 2016-05-08 06:39:23 UTC (rev 200552)
@@ -1,3 +1,49 @@
+2016-05-07 Darin Adler <[email protected]>
+
+ Change MutationObserver::observe to take an IDL dictionary, rather than WebCore::Dictionary
+ https://bugs.webkit.org/show_bug.cgi?id=157456
+
+ Reviewed by Chris Dumez.
+
+ * bindings/js/JSDOMConvert.h:
+ (WebCore::convertOptional): Use a specific Optional null rather than Nullopt so we
+ can compile the ternary operator.
+ (WebCore::convert<bool>): Added.
+ (WebCore::convert<Vector<String>>): Added. Later we probably need to change convert to use
+ a member function of a class template rather than a function template so we can make partial
+ specialization work and do this just once for all Vector<T>.
+
+ * bindings/js/JSMutationObserverCustom.cpp:
+ (WebCore::JSMutationObserverOwner::isReachableFromOpaqueRoots): Streamlined code and removed
+ some local variables. Changed to call the new observedNodes rather than getObservedNodes.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateDictionaryImplementationContent): Fixed bug where we tried to call the version of
+ the convert function with a default value even when there was none.
+
+ * bindings/scripts/test/TestObj.idl: Added a test case basically identical to what's needed
+ in MutationObserver.idl.
+ * bindings/scripts/test/JS/JSTestObj.cpp: Regenerated.
+
+ * dom/MutationObserver.cpp:
+ (WebCore::MutationObserver::observe): Chagned function to take a MutationObserver::Init
+ instead of a Dictionary.
+ (WebCore::MutationObserver::observationStarted): Changed argument type to a reference.
+ (WebCore::MutationObserver::observationEnded): Ditto.
+ (WebCore::MutationObserverMicrotask): Removed unneeded explicit constructor and destructor.
+ (WebCore::queueMutationObserverCompoundMicrotask): Got rid of unnneeded local variable.
+ (WebCore::MutationObserver::observedNodes): Renamed to remove the "get" prefix.
+
+ * dom/MutationObserver.h: Reduced includes. Added MutationObserver::Init struct and
+ used it for the type of the argument to the observe function. Changed a few argument
+ types and removed unused forward declarations.
+
+ * dom/MutationObserver.idl: Added MutationObserverInit and used it instead of Dictionary.
+
+ * dom/MutationObserverRegistration.cpp:
+ (WebCore::MutationObserverRegistration::MutationObserverRegistration): Pass a reference.
+ (WebCore::MutationObserverRegistration::~MutationObserverRegistration): Ditto.
+
2016-05-07 Chris Dumez <[email protected]>
Reduce special handling of XPathNSResolver type in the bindings
Modified: trunk/Source/WebCore/bindings/js/JSDOMConvert.h (200551 => 200552)
--- trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvert.h 2016-05-08 06:39:23 UTC (rev 200552)
@@ -40,7 +40,7 @@
template<typename T> Optional<T> inline convertOptional(JSC::ExecState& state, JSC::JSValue value)
{
- return value.isUndefined() ? Nullopt : convert<T>(state, value);
+ return value.isUndefined() ? Optional<T>() : convert<T>(state, value);
}
template<typename T, typename U> inline T convertOptional(JSC::ExecState& state, JSC::JSValue value, U&& defaultValue)
@@ -48,6 +48,11 @@
return value.isUndefined() ? std::forward<U>(defaultValue) : convert<T>(state, value);
}
+template<> inline bool convert<bool>(JSC::ExecState& state, JSC::JSValue value)
+{
+ return value.toBoolean(&state);
+}
+
template<> inline String convert<String>(JSC::ExecState& state, JSC::JSValue value)
{
return value.toWTFString(&state);
@@ -62,4 +67,25 @@
return static_cast<T>(number);
}
+template<> Vector<String> convert<Vector<String>>(JSC::ExecState& state, JSC::JSValue value)
+{
+ // FIXME: This code has a lot in common with toNativeArray.
+ // Should find a way to share code.
+ unsigned length;
+ auto* object = toJSSequence(&state, value, length);
+ if (state.hadException())
+ return { };
+ Vector<String> vector;
+ vector.reserveInitialCapacity(length);
+ for (unsigned i = 0 ; i < length; ++i) {
+ auto itemValue = object->get(&state, i);
+ if (state.hadException())
+ return { };
+ vector.uncheckedAppend(convert<String>(state, itemValue));
+ if (state.hadException())
+ return { };
+ }
+ return vector;
}
+
+}
Modified: trunk/Source/WebCore/bindings/js/JSMutationObserverCustom.cpp (200551 => 200552)
--- trunk/Source/WebCore/bindings/js/JSMutationObserverCustom.cpp 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/bindings/js/JSMutationObserverCustom.cpp 2016-05-08 06:39:23 UTC (rev 200552)
@@ -29,7 +29,6 @@
*/
#include "config.h"
-
#include "JSMutationObserver.h"
#include "ExceptionCode.h"
@@ -63,10 +62,8 @@
bool JSMutationObserverOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
- MutationObserver& observer = jsCast<JSMutationObserver*>(handle.slot()->asCell())->wrapped();
- auto observedNodes = observer.getObservedNodes();
- for (auto it = observedNodes.begin(), end = observedNodes.end(); it != end; ++it) {
- if (visitor.containsOpaqueRoot(root(*it)))
+ for (auto* node : jsCast<JSMutationObserver*>(handle.slot()->asCell())->wrapped().observedNodes()) {
+ if (visitor.containsOpaqueRoot(root(node)))
return true;
}
return false;
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (200551 => 200552)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-05-08 06:39:23 UTC (rev 200552)
@@ -968,7 +968,7 @@
}
# FIXME: Eventually we will want this to call JSValueToNative.
my $function = $member->isOptional ? "convertOptional" : "convert";
- my $defaultValueWithLeadingComma = $member->isOptional ? ", " . $member->default : "";
+ my $defaultValueWithLeadingComma = $member->isOptional && defined $member->default ? ", " . $member->default : "";
$result .= " auto " . $member->name . " = " . $function . "<" . GetNativeTypeFromSignature($interface, $member) . ">"
. "(state, propertyValue(state, value, \"" . $member->name . "\")" . $defaultValueWithLeadingComma . ");\n";
$needExceptionCheck = 1;
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200551 => 200552)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2016-05-08 06:39:23 UTC (rev 200552)
@@ -495,20 +495,20 @@
auto style = convertOptional<String>(state, propertyValue(state, value, "style"), "normal");
if (UNLIKELY(state.hadException()))
return { };
- auto weight = convertOptional<String>(state, propertyValue(state, value, "weight"), "normal");
- if (UNLIKELY(state.hadException()))
- return { };
- auto stretch = convertOptional<String>(state, propertyValue(state, value, "stretch"), "normal");
- if (UNLIKELY(state.hadException()))
- return { };
auto unicodeRange = convertOptional<String>(state, propertyValue(state, value, "unicodeRange"), "U+0-10FFFF");
+ return { WTFMove(style), WTFMove(unicodeRange) };
+}
+
+template<> TestObj::MutationObserverInit convert<TestObj::MutationObserverInit>(ExecState& state, JSValue value)
+{
+ auto childList = convertOptional<bool>(state, propertyValue(state, value, "childList"), false);
if (UNLIKELY(state.hadException()))
return { };
- auto variant = convertOptional<String>(state, propertyValue(state, value, "variant"), "normal");
+ auto attributes = convertOptional<bool>(state, propertyValue(state, value, "attributes"));
if (UNLIKELY(state.hadException()))
return { };
- auto featureSettings = convertOptional<String>(state, propertyValue(state, value, "featureSettings"), "normal");
- return { WTFMove(style), WTFMove(weight), WTFMove(stretch), WTFMove(unicodeRange), WTFMove(variant), WTFMove(featureSettings) };
+ auto attributeFilter = convertOptional<Vector<String>>(state, propertyValue(state, value, "attributeFilter"));
+ return { WTFMove(childList), WTFMove(attributes), WTFMove(attributeFilter) };
}
// Functions
Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (200551 => 200552)
--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2016-05-08 06:39:23 UTC (rev 200552)
@@ -386,9 +386,11 @@
dictionary FontFaceDescriptors {
DOMString style = "normal";
- DOMString weight = "normal";
- DOMString stretch = "normal";
DOMString unicodeRange = "U+0-10FFFF";
- DOMString variant = "normal";
- DOMString featureSettings = "normal";
};
+
+dictionary MutationObserverInit {
+ boolean childList = false;
+ boolean attributes;
+ sequence<DOMString> attributeFilter;
+};
Modified: trunk/Source/WebCore/dom/MutationObserver.cpp (200551 => 200552)
--- trunk/Source/WebCore/dom/MutationObserver.cpp 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/dom/MutationObserver.cpp 2016-05-08 06:39:23 UTC (rev 200552)
@@ -71,34 +71,30 @@
&& ((options & CharacterData) || !(options & CharacterDataOldValue));
}
-void MutationObserver::observe(Node& node, const Dictionary& optionsDictionary, ExceptionCode& ec)
+void MutationObserver::observe(Node& node, const Init& init, ExceptionCode& ec)
{
- static const struct {
- const char* name;
- MutationObserverOptions value;
- } booleanOptions[] = {
- { "childList", ChildList },
- { "subtree", Subtree },
- { "attributeOldValue", AttributeOldValue },
- { "characterDataOldValue", CharacterDataOldValue }
- };
MutationObserverOptions options = 0;
- bool value = false;
- for (auto& booleanOption : booleanOptions) {
- if (optionsDictionary.get(booleanOption.name, value) && value)
- options |= booleanOption.value;
- }
+ if (init.childList)
+ options |= ChildList;
+ if (init.subtree)
+ options |= Subtree;
+ if (init.attributeOldValue.valueOr(false))
+ options |= AttributeOldValue;
+ if (init.characterDataOldValue.valueOr(false))
+ options |= CharacterDataOldValue;
+
HashSet<AtomicString> attributeFilter;
- if (optionsDictionary.get("attributeFilter", attributeFilter))
+ if (init.attributeFilter) {
+ for (auto& value : init.attributeFilter.value())
+ attributeFilter.add(value);
options |= AttributeFilter;
+ }
- bool attributesOptionIsSet = optionsDictionary.get("attributes", value);
- if ((attributesOptionIsSet && value) || (!attributesOptionIsSet && (options & (AttributeFilter | AttributeOldValue))))
+ if (init.attributes ? init.attributes.value() : (options & (AttributeFilter | AttributeOldValue)))
options |= Attributes;
- bool characterDataOptionIsSet = optionsDictionary.get("characterData", value);
- if ((characterDataOptionIsSet && value) || (!characterDataOptionIsSet && (options & CharacterDataOldValue)))
+ if (init.characterData ? init.characterData.value() : (options & CharacterDataOldValue))
options |= CharacterData;
if (!validateOptions(options)) {
@@ -124,16 +120,16 @@
MutationObserverRegistration::unregisterAndDelete(registration);
}
-void MutationObserver::observationStarted(MutationObserverRegistration* registration)
+void MutationObserver::observationStarted(MutationObserverRegistration& registration)
{
- ASSERT(!m_registrations.contains(registration));
- m_registrations.add(registration);
+ ASSERT(!m_registrations.contains(®istration));
+ m_registrations.add(®istration);
}
-void MutationObserver::observationEnded(MutationObserverRegistration* registration)
+void MutationObserver::observationEnded(MutationObserverRegistration& registration)
{
- ASSERT(m_registrations.contains(registration));
- m_registrations.remove(registration);
+ ASSERT(m_registrations.contains(®istration));
+ m_registrations.remove(®istration);
}
typedef HashSet<RefPtr<MutationObserver>> MutationObserverSet;
@@ -154,22 +150,11 @@
class MutationObserverMicrotask final : public Microtask {
WTF_MAKE_FAST_ALLOCATED;
-public:
- MutationObserverMicrotask()
- {
- }
-
- virtual ~MutationObserverMicrotask()
- {
- }
-
private:
- Result run() override
+ Result run() final
{
mutationObserverCompoundMicrotaskQueuedFlag = false;
-
MutationObserver::deliverAllMutations();
-
return Result::Done;
}
};
@@ -179,9 +164,7 @@
if (mutationObserverCompoundMicrotaskQueuedFlag)
return;
mutationObserverCompoundMicrotaskQueuedFlag = true;
-
- auto microtask = std::make_unique<MutationObserverMicrotask>();
- MicrotaskQueue::mainThreadQueue().append(WTFMove(microtask));
+ MicrotaskQueue::mainThreadQueue().append(std::make_unique<MutationObserverMicrotask>());
}
void MutationObserver::enqueueMutationRecord(Ref<MutationRecord>&& mutation)
@@ -201,7 +184,7 @@
queueMutationObserverCompoundMicrotask();
}
-HashSet<Node*> MutationObserver::getObservedNodes() const
+HashSet<Node*> MutationObserver::observedNodes() const
{
HashSet<Node*> observedNodes;
for (auto* registration : m_registrations)
Modified: trunk/Source/WebCore/dom/MutationObserver.h (200551 => 200552)
--- trunk/Source/WebCore/dom/MutationObserver.h 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/dom/MutationObserver.h 2016-05-08 06:39:23 UTC (rev 200552)
@@ -31,17 +31,14 @@
#ifndef MutationObserver_h
#define MutationObserver_h
-#include <wtf/HashMap.h>
+#include <wtf/Forward.h>
#include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/Optional.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/text/AtomicString.h>
-#include <wtf/text/AtomicStringHash.h>
+#include <wtf/Vector.h>
namespace WebCore {
-class Dictionary;
class MutationCallback;
class MutationObserverRegistration;
class MutationRecord;
@@ -77,20 +74,29 @@
~MutationObserver();
- void observe(Node&, const Dictionary&, ExceptionCode&);
+ struct Init {
+ bool childList;
+ Optional<bool> attributes;
+ Optional<bool> characterData;
+ bool subtree;
+ Optional<bool> attributeOldValue;
+ Optional<bool> characterDataOldValue;
+ Optional<Vector<String>> attributeFilter;
+ };
+
+ void observe(Node&, const Init&, ExceptionCode&);
Vector<Ref<MutationRecord>> takeRecords();
void disconnect();
- void observationStarted(MutationObserverRegistration*);
- void observationEnded(MutationObserverRegistration*);
+
+ void observationStarted(MutationObserverRegistration&);
+ void observationEnded(MutationObserverRegistration&);
void enqueueMutationRecord(Ref<MutationRecord>&&);
void setHasTransientRegistration();
bool canDeliver();
- HashSet<Node*> getObservedNodes() const;
+ HashSet<Node*> observedNodes() const;
private:
- struct ObserverLessThan;
-
explicit MutationObserver(Ref<MutationCallback>&&);
void deliver();
Modified: trunk/Source/WebCore/dom/MutationObserver.idl (200551 => 200552)
--- trunk/Source/WebCore/dom/MutationObserver.idl 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/dom/MutationObserver.idl 2016-05-08 06:39:23 UTC (rev 200552)
@@ -33,7 +33,17 @@
CustomIsReachable,
ImplementationLacksVTable,
] interface MutationObserver {
- [RaisesException] void observe(Node target, Dictionary options);
+ [RaisesException] void observe(Node target, MutationObserverInit options);
sequence<MutationRecord> takeRecords();
void disconnect();
};
+
+dictionary MutationObserverInit {
+ boolean childList = false;
+ boolean attributes;
+ boolean characterData;
+ boolean subtree = false;
+ boolean attributeOldValue;
+ boolean characterDataOldValue;
+ sequence<DOMString> attributeFilter;
+};
Modified: trunk/Source/WebCore/dom/MutationObserverRegistration.cpp (200551 => 200552)
--- trunk/Source/WebCore/dom/MutationObserverRegistration.cpp 2016-05-08 04:57:09 UTC (rev 200551)
+++ trunk/Source/WebCore/dom/MutationObserverRegistration.cpp 2016-05-08 06:39:23 UTC (rev 200552)
@@ -43,13 +43,13 @@
, m_options(options)
, m_attributeFilter(attributeFilter)
{
- m_observer->observationStarted(this);
+ m_observer->observationStarted(*this);
}
MutationObserverRegistration::~MutationObserverRegistration()
{
clearTransientRegistrations();
- m_observer->observationEnded(this);
+ m_observer->observationEnded(*this);
}
void MutationObserverRegistration::resetObservation(MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)