Changeset 145379 in webkit
- Timestamp:
- Mar 11, 2013 12:16:01 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r145378 r145379 1 2013-03-11 Adam Klein <adamk@chromium.org> 2 3 MutationCallback should be a WebIDL 'callback', not a [Callback] interface 4 https://bugs.webkit.org/show_bug.cgi?id=91406 5 6 Reviewed by Adam Barth. 7 8 * fast/dom/MutationObserver/mutation-observer-constructor-expected.txt: 9 * fast/dom/MutationObserver/mutation-observer-constructor.html: Add test for TypeError-throwing. 10 Note that the Number and String cases already threw before this patch. 11 1 12 2013-03-11 Julien Chaffraix <jchaffraix@webkit.org> 2 13 -
trunk/LayoutTests/fast/dom/MutationObserver/mutation-observer-constructor-expected.txt
r137662 r145379 9 9 PASS typeof observer.observe is "function" 10 10 PASS typeof observer.disconnect is "function" 11 PASS new MutationObserver({ handleEvent: function() {} }) threw exception TypeError: Callback argument must be a function. 12 PASS new MutationObserver({}) threw exception TypeError: Callback argument must be a function. 13 PASS new MutationObserver(42) threw exception TypeError: Callback argument must be a function. 14 PASS new MutationObserver("foo") threw exception TypeError: Callback argument must be a function. 11 15 PASS successfullyParsed is true 12 16 -
trunk/LayoutTests/fast/dom/MutationObserver/mutation-observer-constructor.html
r143386 r145379 1 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 2 <body> 5 3 <script src="../../js/resources/js-test-pre.js"></script> 6 <title></title>7 </head>8 <body>9 <p id=description></p>10 <div id="console"></div>11 4 <script> 12 13 function runTest() {14 shouldBeNonNull('window.WebKitMutationObserver');15 shouldBeEqualToString('typeof WebKitMutationObserver.prototype.observe', 'function');16 shouldBeEqualToString('typeof WebKitMutationObserver.prototype.disconnect', 'function');17 window.observer = new MutationObserver(function(mutations) { });18 shouldBeEqualToString('typeof observer.observe', 'function');19 shouldBeEqualToString('typeof observer.disconnect', 'function');20 }21 22 5 description('Test the constructor of WebKitMutationObserver'); 23 6 24 runTest(); 7 shouldBeNonNull('window.WebKitMutationObserver'); 8 shouldBeEqualToString('typeof WebKitMutationObserver.prototype.observe', 'function'); 9 shouldBeEqualToString('typeof WebKitMutationObserver.prototype.disconnect', 'function'); 10 window.observer = new MutationObserver(function(mutations) { }); 11 shouldBeEqualToString('typeof observer.observe', 'function'); 12 shouldBeEqualToString('typeof observer.disconnect', 'function'); 13 14 shouldThrow('new MutationObserver({ handleEvent: function() {} })'); 15 shouldThrow('new MutationObserver({})'); 16 shouldThrow('new MutationObserver(42)'); 17 shouldThrow('new MutationObserver("foo")'); 25 18 </script> 26 19 <script src="../../js/resources/js-test-post.js"></script> 27 20 </body> 28 </html> -
trunk/Source/WebCore/ChangeLog
r145378 r145379 1 2013-03-11 Adam Klein <adamk@chromium.org> 2 3 MutationCallback should be a WebIDL 'callback', not a [Callback] interface 4 https://bugs.webkit.org/show_bug.cgi?id=91406 5 6 Reviewed by Adam Barth. 7 8 Spec: http://dom.spec.whatwg.org/#mutationcallback 9 10 Besides no longer calling handleEvent methods on passed-in objects, 11 throw a TypeError if a non-function is passed to the MutationObserver constructor. 12 This is per WebIDL: http://www.w3.org/TR/WebIDL/#es-callback-function 13 14 Updated MutationObserver constructor tests to exercise TypeError-throwing behavior. 15 16 * bindings/js/JSMutationCallback.cpp: 17 (WebCore::JSMutationCallback::call): Call the callback directly instead of handing off to JSCallbackData; make return value void. 18 Use jsArray() to convert from WTF::Vector -> JSArray. 19 * bindings/js/JSMutationCallback.h: 20 (JSMutationCallback): Rename handleEvent() to call(), make it void. 21 * bindings/js/JSMutationObserverCustom.cpp: 22 (WebCore::JSMutationObserverConstructor::constructJSMutationObserver): Throw if passed a non-function. 23 * bindings/v8/V8MutationCallback.cpp: 24 (WebCore::V8MutationCallback::V8MutationCallback): Take a v8::Function instead of a v8::Object. 25 (WebCore::V8MutationCallback::call): Call the callback directly instead of handing off to invokeCallback(); make return value void. 26 Use v8Array() to convert form WTF::Vector -> JSArray. 27 * bindings/v8/V8MutationCallback.h: 28 (WebCore::V8MutationCallback::create): Take a v8::Function instead of a v8::Object. 29 (V8MutationCallback): ditto 30 * bindings/v8/custom/V8MutationObserverCustom.cpp: 31 (WebCore::V8MutationObserver::constructorCustom): Throw if passed a non-function, cast to a v8::Function when constructing callback. 32 * dom/MutationCallback.h: 33 (WebCore): Remove unnecessary typedef. 34 (MutationCallback): Rename handleEvent() to call(), make it void. 35 * dom/MutationObserver.cpp: 36 (WebCore::MutationObserver::deliver): Update MutationCallback method name. 37 1 38 2013-03-11 Julien Chaffraix <jchaffraix@webkit.org> 2 39 -
trunk/Source/WebCore/bindings/js/JSMutationCallback.cpp
r141296 r145379 28 28 #include "JSMutationCallback.h" 29 29 30 #include "JSDOMGlobalObject.h" 31 #include "JSMainThreadExecState.h" 30 32 #include "JSMutationObserver.h" 31 33 #include "JSMutationRecord.h" … … 48 50 } 49 51 50 bool JSMutationCallback::handleEvent(MutationRecordArray*mutations, MutationObserver* observer)52 void JSMutationCallback::call(const Vector<RefPtr<MutationRecord> >& mutations, MutationObserver* observer) 51 53 { 52 54 if (!canInvokeCallback()) 53 return true;55 return; 54 56 55 57 RefPtr<JSMutationCallback> protect(this); … … 58 60 59 61 if (!m_callback) 60 return false; 62 return; 63 64 JSValue callback = m_callback.get(); 65 CallData callData; 66 CallType callType = getCallData(callback, callData); 67 if (callType == CallTypeNone) { 68 ASSERT_NOT_REACHED(); 69 return; 70 } 61 71 62 72 ScriptExecutionContext* context = scriptExecutionContext(); 63 73 if (!context) 64 return false; 74 return; 75 ASSERT(context->isDocument()); 65 76 66 77 JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, m_isolatedWorld.get()); 67 78 ExecState* exec = globalObject->globalExec(); 68 79 69 MarkedArgumentBuffer mutationList;70 for (size_t i = 0; i < mutations->size(); ++i)71 mutationList.append(toJS(exec, globalObject, mutations->at(i).get()));72 73 80 JSValue jsObserver = toJS(exec, globalObject, observer); 74 81 75 82 MarkedArgumentBuffer args; 76 args.append( constructArray(exec, 0, globalObject, mutationList));83 args.append(jsArray(exec, globalObject, mutations)); 77 84 args.append(jsObserver); 78 85 79 bool raisedException = false; 80 // FIXME: Extract invokeCallback() method. 81 JSCallbackData(m_callback.get(), globalObject).invokeCallback(jsObserver, args, &raisedException); 82 return !raisedException; 86 globalObject->globalData().timeoutChecker.start(); 87 InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData); 88 89 JSMainThreadExecState::call(exec, callback, callType, callData, jsObserver, args); 90 91 InspectorInstrumentation::didCallFunction(cookie); 92 globalObject->globalData().timeoutChecker.stop(); 93 94 if (exec->hadException()) 95 reportCurrentException(exec); 83 96 } 84 97 -
trunk/Source/WebCore/bindings/js/JSMutationCallback.h
r141296 r145379 28 28 29 29 #include "ActiveDOMCallback.h" 30 #include " JSCallbackData.h"30 #include "DOMWrapperWorld.h" 31 31 #include "MutationCallback.h" 32 #include <heap/Weak.h> 33 #include <runtime/JSObject.h> 32 34 #include <wtf/Forward.h> 33 35 34 36 namespace WebCore { 37 38 class JSDOMGlobalObject; 35 39 36 40 class JSMutationCallback : public MutationCallback, public ActiveDOMCallback { … … 43 47 virtual ~JSMutationCallback(); 44 48 45 virtual bool handleEvent(MutationRecordArray* mutations, MutationObserver*) OVERRIDE;49 virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) OVERRIDE; 46 50 47 51 virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE { return ContextDestructionObserver::scriptExecutionContext(); } -
trunk/Source/WebCore/bindings/js/JSMutationObserverCustom.cpp
r143863 r145379 50 50 51 51 JSObject* object = exec->argument(0).getObject(); 52 if (!object) { 53 setDOMException(exec, TYPE_MISMATCH_ERR); 54 return JSValue::encode(jsUndefined()); 55 } 52 CallData callData; 53 if (!object || object->methodTable()->getCallData(object, callData) == CallTypeNone) 54 return throwVMError(exec, createTypeError(exec, "Callback argument must be a function")); 56 55 57 56 JSMutationObserverConstructor* jsConstructor = jsCast<JSMutationObserverConstructor*>(exec->callee()); -
trunk/Source/WebCore/bindings/v8/V8MutationCallback.cpp
r144592 r145379 27 27 #include "V8MutationCallback.h" 28 28 29 #include "ScriptController.h" 29 30 #include "ScriptExecutionContext.h" 30 31 #include "V8Binding.h" 31 #include "V8Callback.h"32 32 #include "V8MutationObserver.h" 33 33 #include "V8MutationRecord.h" … … 36 36 namespace WebCore { 37 37 38 V8MutationCallback::V8MutationCallback(v8::Handle<v8:: Object> callback, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate)38 V8MutationCallback::V8MutationCallback(v8::Handle<v8::Function> callback, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate) 39 39 : ActiveDOMCallback(context) 40 40 , m_callback(callback) … … 45 45 } 46 46 47 bool V8MutationCallback::handleEvent(MutationRecordArray*mutations, MutationObserver* observer)47 void V8MutationCallback::call(const Vector<RefPtr<MutationRecord> >& mutations, MutationObserver* observer) 48 48 { 49 ASSERT(mutations);50 if (!mutations)51 return true;52 53 49 if (!canInvokeCallback()) 54 return true;50 return; 55 51 56 52 v8::HandleScope handleScope; … … 58 54 v8::Handle<v8::Context> v8Context = toV8Context(scriptExecutionContext(), m_world.get()); 59 55 if (v8Context.IsEmpty()) 60 return true;56 return; 61 57 62 58 v8::Context::Scope scope(v8Context); 59 v8::Isolate* isolate = v8Context->GetIsolate(); 63 60 64 v8::Local<v8::Array> mutationsArray = v8::Array::New(mutations->size()); 65 for (size_t i = 0; i < mutations->size(); ++i) 66 mutationsArray->Set(v8Integer(i, v8Context->GetIsolate()), toV8(mutations->at(i).get(), v8::Handle<v8::Object>(), v8Context->GetIsolate())); 61 v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New(isolate, m_callback.get()); 67 62 68 v8::Handle<v8::Value> observerHandle = toV8(observer, v8::Handle<v8::Object>(), v8Context->GetIsolate());63 v8::Handle<v8::Value> observerHandle = toV8(observer, v8::Handle<v8::Object>(), isolate); 69 64 if (observerHandle.IsEmpty()) { 70 65 if (!isScriptControllerTerminating()) 71 66 CRASH(); 72 return true;67 return; 73 68 } 74 69 75 70 if (!observerHandle->IsObject()) 76 return true;71 return; 77 72 78 v8::Handle<v8::Value> argv[] = { 79 mutationsArray, 80 observerHandle 81 }; 73 v8::Handle<v8::Object> thisObject = v8::Handle<v8::Object>::Cast(observerHandle); 74 v8::Handle<v8::Value> argv[] = { v8Array(mutations, isolate), observerHandle }; 82 75 83 bool callbackReturnValue = false; 84 return !invokeCallback(m_callback.get(), v8::Handle<v8::Object>::Cast(observerHandle), 2, argv, callbackReturnValue, scriptExecutionContext()); 76 v8::TryCatch exceptionCatcher; 77 exceptionCatcher.SetVerbose(true); 78 ScriptController::callFunctionWithInstrumentation(scriptExecutionContext(), callback, thisObject, 2, argv); 85 79 } 86 80 -
trunk/Source/WebCore/bindings/v8/V8MutationCallback.h
r144522 r145379 40 40 class V8MutationCallback : public MutationCallback, public ActiveDOMCallback { 41 41 public: 42 static PassRefPtr<V8MutationCallback> create(v8::Handle<v8:: Value> value, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate)42 static PassRefPtr<V8MutationCallback> create(v8::Handle<v8::Function> callback, ScriptExecutionContext* context, v8::Handle<v8::Object> owner, v8::Isolate* isolate) 43 43 { 44 ASSERT(value->IsObject());45 44 ASSERT(context); 46 return adoptRef(new V8MutationCallback( v8::Handle<v8::Object>::Cast(value), context, owner, isolate));45 return adoptRef(new V8MutationCallback(callback, context, owner, isolate)); 47 46 } 48 47 49 virtual bool handleEvent(MutationRecordArray*, MutationObserver*) OVERRIDE;48 virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) OVERRIDE; 50 49 virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE { return ContextDestructionObserver::scriptExecutionContext(); } 51 50 52 51 private: 53 V8MutationCallback(v8::Handle<v8:: Object>, ScriptExecutionContext*, v8::Handle<v8::Object>, v8::Isolate*);52 V8MutationCallback(v8::Handle<v8::Function>, ScriptExecutionContext*, v8::Handle<v8::Object>, v8::Isolate*); 54 53 55 54 static void weakCallback(v8::Isolate* isolate, v8::Persistent<v8::Value> wrapper, void* parameter) … … 59 58 } 60 59 61 ScopedPersistent<v8:: Object> m_callback;60 ScopedPersistent<v8::Function> m_callback; 62 61 RefPtr<DOMWrapperWorld> m_world; 63 62 }; -
trunk/Source/WebCore/bindings/v8/custom/V8MutationObserverCustom.cpp
r143851 r145379 48 48 49 49 v8::Local<v8::Value> arg = args[0]; 50 if (!arg->Is Object())51 return setDOMException(TYPE_MISMATCH_ERR, args.GetIsolate());50 if (!arg->IsFunction()) 51 return throwTypeError("Callback argument must be a function", args.GetIsolate()); 52 52 53 53 ScriptExecutionContext* context = getScriptExecutionContext(); 54 54 v8::Handle<v8::Object> wrapper = args.Holder(); 55 55 56 RefPtr<MutationCallback> callback = V8MutationCallback::create( arg, context, wrapper, args.GetIsolate());56 RefPtr<MutationCallback> callback = V8MutationCallback::create(v8::Handle<v8::Function>::Cast(arg), context, wrapper, args.GetIsolate()); 57 57 RefPtr<MutationObserver> observer = MutationObserver::create(callback.release()); 58 58 -
trunk/Source/WebCore/dom/MutationCallback.h
r138811 r145379 41 41 class MutationObserver; 42 42 43 typedef Vector<RefPtr<MutationRecord> > MutationRecordArray;44 45 43 class MutationCallback : public RefCounted<MutationCallback> { 46 44 public: 47 45 virtual ~MutationCallback() { } 48 46 49 virtual bool handleEvent(MutationRecordArray*, MutationObserver*) = 0;47 virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) = 0; 50 48 virtual ScriptExecutionContext* scriptExecutionContext() const = 0; 51 49 }; -
trunk/Source/WebCore/dom/MutationObserver.cpp
r138811 r145379 205 205 records.swap(m_records); 206 206 207 m_callback-> handleEvent(&records, this);207 m_callback->call(records, this); 208 208 } 209 209
Note: See TracChangeset
for help on using the changeset viewer.