1/*
2 This file is part of the WebKit open source project.
3 This file has been generated by generate-bindings.pl. DO NOT MODIFY!
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "config.h"
22#include "JSMutationObserver.h"
23
24#include "JSDOMBinding.h"
25#include "JSDOMConstructor.h"
26#include "JSDOMConvertBoolean.h"
27#include "JSDOMConvertCallbacks.h"
28#include "JSDOMConvertInterface.h"
29#include "JSDOMConvertSequences.h"
30#include "JSDOMConvertStrings.h"
31#include "JSDOMExceptionHandling.h"
32#include "JSDOMGlobalObject.h"
33#include "JSDOMOperation.h"
34#include "JSDOMWrapperCache.h"
35#include "JSMutationCallback.h"
36#include "JSMutationRecord.h"
37#include "JSNode.h"
38#include "ScriptExecutionContext.h"
39#include <JavaScriptCore/FunctionPrototype.h>
40#include <JavaScriptCore/HeapSnapshotBuilder.h>
41#include <JavaScriptCore/JSArray.h>
42#include <JavaScriptCore/JSCInlines.h>
43#include <wtf/GetPtr.h>
44#include <wtf/PointerPreparations.h>
45#include <wtf/URL.h>
46
47
48namespace WebCore {
49using namespace JSC;
50
51template<> MutationObserver::Init convertDictionary<MutationObserver::Init>(ExecState& state, JSValue value)
52{
53 VM& vm = state.vm();
54 auto throwScope = DECLARE_THROW_SCOPE(vm);
55 bool isNullOrUndefined = value.isUndefinedOrNull();
56 auto* object = isNullOrUndefined ? nullptr : value.getObject();
57 if (UNLIKELY(!isNullOrUndefined && !object)) {
58 throwTypeError(&state, throwScope);
59 return { };
60 }
61 MutationObserver::Init result;
62 JSValue attributeFilterValue;
63 if (isNullOrUndefined)
64 attributeFilterValue = jsUndefined();
65 else {
66 attributeFilterValue = object->get(&state, Identifier::fromString(&state, "attributeFilter"));
67 RETURN_IF_EXCEPTION(throwScope, { });
68 }
69 if (!attributeFilterValue.isUndefined()) {
70 result.attributeFilter = convert<IDLSequence<IDLDOMString>>(state, attributeFilterValue);
71 RETURN_IF_EXCEPTION(throwScope, { });
72 }
73 JSValue attributeOldValueValue;
74 if (isNullOrUndefined)
75 attributeOldValueValue = jsUndefined();
76 else {
77 attributeOldValueValue = object->get(&state, Identifier::fromString(&state, "attributeOldValue"));
78 RETURN_IF_EXCEPTION(throwScope, { });
79 }
80 if (!attributeOldValueValue.isUndefined()) {
81 result.attributeOldValue = convert<IDLBoolean>(state, attributeOldValueValue);
82 RETURN_IF_EXCEPTION(throwScope, { });
83 }
84 JSValue attributesValue;
85 if (isNullOrUndefined)
86 attributesValue = jsUndefined();
87 else {
88 attributesValue = object->get(&state, Identifier::fromString(&state, "attributes"));
89 RETURN_IF_EXCEPTION(throwScope, { });
90 }
91 if (!attributesValue.isUndefined()) {
92 result.attributes = convert<IDLBoolean>(state, attributesValue);
93 RETURN_IF_EXCEPTION(throwScope, { });
94 }
95 JSValue characterDataValue;
96 if (isNullOrUndefined)
97 characterDataValue = jsUndefined();
98 else {
99 characterDataValue = object->get(&state, Identifier::fromString(&state, "characterData"));
100 RETURN_IF_EXCEPTION(throwScope, { });
101 }
102 if (!characterDataValue.isUndefined()) {
103 result.characterData = convert<IDLBoolean>(state, characterDataValue);
104 RETURN_IF_EXCEPTION(throwScope, { });
105 }
106 JSValue characterDataOldValueValue;
107 if (isNullOrUndefined)
108 characterDataOldValueValue = jsUndefined();
109 else {
110 characterDataOldValueValue = object->get(&state, Identifier::fromString(&state, "characterDataOldValue"));
111 RETURN_IF_EXCEPTION(throwScope, { });
112 }
113 if (!characterDataOldValueValue.isUndefined()) {
114 result.characterDataOldValue = convert<IDLBoolean>(state, characterDataOldValueValue);
115 RETURN_IF_EXCEPTION(throwScope, { });
116 }
117 JSValue childListValue;
118 if (isNullOrUndefined)
119 childListValue = jsUndefined();
120 else {
121 childListValue = object->get(&state, Identifier::fromString(&state, "childList"));
122 RETURN_IF_EXCEPTION(throwScope, { });
123 }
124 if (!childListValue.isUndefined()) {
125 result.childList = convert<IDLBoolean>(state, childListValue);
126 RETURN_IF_EXCEPTION(throwScope, { });
127 } else
128 result.childList = false;
129 JSValue subtreeValue;
130 if (isNullOrUndefined)
131 subtreeValue = jsUndefined();
132 else {
133 subtreeValue = object->get(&state, Identifier::fromString(&state, "subtree"));
134 RETURN_IF_EXCEPTION(throwScope, { });
135 }
136 if (!subtreeValue.isUndefined()) {
137 result.subtree = convert<IDLBoolean>(state, subtreeValue);
138 RETURN_IF_EXCEPTION(throwScope, { });
139 } else
140 result.subtree = false;
141 return result;
142}
143
144// Functions
145
146JSC::EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionObserve(JSC::ExecState*);
147JSC::EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionDisconnect(JSC::ExecState*);
148JSC::EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionTakeRecords(JSC::ExecState*);
149
150// Attributes
151
152JSC::EncodedJSValue jsMutationObserverConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
153bool setJSMutationObserverConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
154
155class JSMutationObserverPrototype : public JSC::JSNonFinalObject {
156public:
157 using Base = JSC::JSNonFinalObject;
158 static JSMutationObserverPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
159 {
160 JSMutationObserverPrototype* ptr = new (NotNull, JSC::allocateCell<JSMutationObserverPrototype>(vm.heap)) JSMutationObserverPrototype(vm, globalObject, structure);
161 ptr->finishCreation(vm);
162 return ptr;
163 }
164
165 DECLARE_INFO;
166 static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
167 {
168 return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
169 }
170
171private:
172 JSMutationObserverPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
173 : JSC::JSNonFinalObject(vm, structure)
174 {
175 }
176
177 void finishCreation(JSC::VM&);
178};
179
180using JSMutationObserverConstructor = JSDOMConstructor<JSMutationObserver>;
181
182template<> EncodedJSValue JSC_HOST_CALL JSMutationObserverConstructor::construct(ExecState* state)
183{
184 VM& vm = state->vm();
185 auto throwScope = DECLARE_THROW_SCOPE(vm);
186 UNUSED_PARAM(throwScope);
187 auto* castedThis = jsCast<JSMutationObserverConstructor*>(state->jsCallee());
188 ASSERT(castedThis);
189 if (UNLIKELY(state->argumentCount() < 1))
190 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
191 auto callback = convert<IDLCallbackFunction<JSMutationCallback>>(*state, state->uncheckedArgument(0), *castedThis->globalObject(), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentMustBeFunctionError(state, scope, 0, "callback", "MutationObserver", nullptr); });
192 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
193 auto object = MutationObserver::create(callback.releaseNonNull());
194 return JSValue::encode(toJSNewlyCreated<IDLInterface<MutationObserver>>(*state, *castedThis->globalObject(), WTFMove(object)));
195}
196
197template<> JSValue JSMutationObserverConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
198{
199 UNUSED_PARAM(vm);
200 return globalObject.functionPrototype();
201}
202
203template<> void JSMutationObserverConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
204{
205 putDirect(vm, vm.propertyNames->prototype, JSMutationObserver::prototype(vm, globalObject), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
206 putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String("MutationObserver"_s)), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
207 putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
208}
209
210template<> const ClassInfo JSMutationObserverConstructor::s_info = { "MutationObserver", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMutationObserverConstructor) };
211
212/* Hash table for prototype */
213
214static const HashTableValue JSMutationObserverPrototypeTableValues[] =
215{
216 { "constructor", static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMutationObserverConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMutationObserverConstructor) } },
217 { "observe", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMutationObserverPrototypeFunctionObserve), (intptr_t) (1) } },
218 { "disconnect", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMutationObserverPrototypeFunctionDisconnect), (intptr_t) (0) } },
219 { "takeRecords", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(jsMutationObserverPrototypeFunctionTakeRecords), (intptr_t) (0) } },
220};
221
222const ClassInfo JSMutationObserverPrototype::s_info = { "MutationObserverPrototype", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMutationObserverPrototype) };
223
224void JSMutationObserverPrototype::finishCreation(VM& vm)
225{
226 Base::finishCreation(vm);
227 reifyStaticProperties(vm, JSMutationObserver::info(), JSMutationObserverPrototypeTableValues, *this);
228}
229
230const ClassInfo JSMutationObserver::s_info = { "MutationObserver", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMutationObserver) };
231
232JSMutationObserver::JSMutationObserver(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MutationObserver>&& impl)
233 : JSDOMWrapper<MutationObserver>(structure, globalObject, WTFMove(impl))
234{
235}
236
237void JSMutationObserver::finishCreation(VM& vm)
238{
239 Base::finishCreation(vm);
240 ASSERT(inherits(vm, info()));
241
242}
243
244JSObject* JSMutationObserver::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
245{
246 return JSMutationObserverPrototype::create(vm, &globalObject, JSMutationObserverPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype()));
247}
248
249JSObject* JSMutationObserver::prototype(VM& vm, JSDOMGlobalObject& globalObject)
250{
251 return getDOMPrototype<JSMutationObserver>(vm, globalObject);
252}
253
254JSValue JSMutationObserver::getConstructor(VM& vm, const JSGlobalObject* globalObject)
255{
256 return getDOMConstructor<JSMutationObserverConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
257}
258
259void JSMutationObserver::destroy(JSC::JSCell* cell)
260{
261 JSMutationObserver* thisObject = static_cast<JSMutationObserver*>(cell);
262 thisObject->JSMutationObserver::~JSMutationObserver();
263}
264
265template<> inline JSMutationObserver* IDLOperation<JSMutationObserver>::cast(ExecState& state)
266{
267 return jsDynamicCast<JSMutationObserver*>(state.vm(), state.thisValue());
268}
269
270EncodedJSValue jsMutationObserverConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
271{
272 VM& vm = state->vm();
273 auto throwScope = DECLARE_THROW_SCOPE(vm);
274 auto* prototype = jsDynamicCast<JSMutationObserverPrototype*>(vm, JSValue::decode(thisValue));
275 if (UNLIKELY(!prototype))
276 return throwVMTypeError(state, throwScope);
277 return JSValue::encode(JSMutationObserver::getConstructor(state->vm(), prototype->globalObject()));
278}
279
280bool setJSMutationObserverConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
281{
282 VM& vm = state->vm();
283 auto throwScope = DECLARE_THROW_SCOPE(vm);
284 auto* prototype = jsDynamicCast<JSMutationObserverPrototype*>(vm, JSValue::decode(thisValue));
285 if (UNLIKELY(!prototype)) {
286 throwVMTypeError(state, throwScope);
287 return false;
288 }
289 // Shadowing a built-in constructor
290 return prototype->putDirect(vm, vm.propertyNames->constructor, JSValue::decode(encodedValue));
291}
292
293static inline JSC::EncodedJSValue jsMutationObserverPrototypeFunctionObserveBody(JSC::ExecState* state, typename IDLOperation<JSMutationObserver>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
294{
295 UNUSED_PARAM(state);
296 UNUSED_PARAM(throwScope);
297 auto& impl = castedThis->wrapped();
298 if (UNLIKELY(state->argumentCount() < 1))
299 return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
300 auto target = convert<IDLInterface<Node>>(*state, state->uncheckedArgument(0), [](JSC::ExecState& state, JSC::ThrowScope& scope) { throwArgumentTypeError(state, scope, 0, "target", "MutationObserver", "observe", "Node"); });
301 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
302 auto options = convert<IDLDictionary<MutationObserver::Init>>(*state, state->argument(1));
303 RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
304 propagateException(*state, throwScope, impl.observe(*target, WTFMove(options)));
305 return JSValue::encode(jsUndefined());
306}
307
308EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionObserve(ExecState* state)
309{
310 return IDLOperation<JSMutationObserver>::call<jsMutationObserverPrototypeFunctionObserveBody>(*state, "observe");
311}
312
313static inline JSC::EncodedJSValue jsMutationObserverPrototypeFunctionDisconnectBody(JSC::ExecState* state, typename IDLOperation<JSMutationObserver>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
314{
315 UNUSED_PARAM(state);
316 UNUSED_PARAM(throwScope);
317 auto& impl = castedThis->wrapped();
318 impl.disconnect();
319 return JSValue::encode(jsUndefined());
320}
321
322EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionDisconnect(ExecState* state)
323{
324 return IDLOperation<JSMutationObserver>::call<jsMutationObserverPrototypeFunctionDisconnectBody>(*state, "disconnect");
325}
326
327static inline JSC::EncodedJSValue jsMutationObserverPrototypeFunctionTakeRecordsBody(JSC::ExecState* state, typename IDLOperation<JSMutationObserver>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
328{
329 UNUSED_PARAM(state);
330 UNUSED_PARAM(throwScope);
331 auto& impl = castedThis->wrapped();
332 auto implResult = impl.takeRecords();
333 return JSValue::encode(toJS<IDLSequence<IDLInterface<MutationRecord>>>(*state, *castedThis->globalObject(), WTFMove(implResult.records)));
334}
335
336EncodedJSValue JSC_HOST_CALL jsMutationObserverPrototypeFunctionTakeRecords(ExecState* state)
337{
338 return IDLOperation<JSMutationObserver>::call<jsMutationObserverPrototypeFunctionTakeRecordsBody>(*state, "takeRecords");
339}
340
341void JSMutationObserver::visitChildren(JSCell* cell, SlotVisitor& visitor)
342{
343 auto* thisObject = jsCast<JSMutationObserver*>(cell);
344 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
345 Base::visitChildren(thisObject, visitor);
346 thisObject->visitAdditionalChildren(visitor);
347}
348
349void JSMutationObserver::visitOutputConstraints(JSCell* cell, SlotVisitor& visitor)
350{
351 auto* thisObject = jsCast<JSMutationObserver*>(cell);
352 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
353 Base::visitOutputConstraints(thisObject, visitor);
354 thisObject->visitAdditionalChildren(visitor);
355}
356
357void JSMutationObserver::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
358{
359 auto* thisObject = jsCast<JSMutationObserver*>(cell);
360 builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
361 if (thisObject->scriptExecutionContext())
362 builder.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string());
363 Base::heapSnapshot(cell, builder);
364}
365
366void JSMutationObserverOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
367{
368 auto* jsMutationObserver = static_cast<JSMutationObserver*>(handle.slot()->asCell());
369 auto& world = *static_cast<DOMWrapperWorld*>(context);
370 uncacheWrapper(world, &jsMutationObserver->wrapped(), jsMutationObserver);
371}
372
373JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<MutationObserver>&& impl)
374{
375 // If you hit this failure the interface definition has the ImplementationLacksVTable
376 // attribute. You should remove that attribute. If the class has subclasses
377 // that may be passed through this toJS() function you should use the SkipVTableValidation
378 // attribute to MutationObserver.
379 static_assert(!std::is_polymorphic<MutationObserver>::value, "MutationObserver is polymorphic but the IDL claims it is not");
380 return createWrapper<MutationObserver>(globalObject, WTFMove(impl));
381}
382
383JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, MutationObserver& impl)
384{
385 return wrap(state, globalObject, impl);
386}
387
388MutationObserver* JSMutationObserver::toWrapped(JSC::VM& vm, JSC::JSValue value)
389{
390 if (auto* wrapper = jsDynamicCast<JSMutationObserver*>(vm, value))
391 return &wrapper->wrapped();
392 return nullptr;
393}
394
395}
396