Changeset 87315 in webkit
- Timestamp:
- May 25, 2011 12:28:22 PM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r87313 r87315 1 2011-05-25 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 Reviewed by Andreas Kling. 4 5 [Qt] JSC bridge: implement __qt_sender__ without using Scope Chain 6 https://bugs.webkit.org/show_bug.cgi?id=61343 7 8 Create a stack to keep track of the sender objects. This is simpler than 9 the similar mechanism in QObject (C++ API), that keeps a stack per-object. 10 11 Since we do not support multiple threads, one static stack will be enough for 12 handling the behavior. 13 14 This behavior is covered by the tst_QWebFrame::connectAndDisconnect() auto test. 15 16 * bridge/qt/qt_instance.cpp: 17 (JSC::Bindings::QtInstance::qtSenderStack): 18 We have one static stack of QObject*. The top of the stack contains the 19 last object that emitted signal that called a JavaScript function. 20 21 * bridge/qt/qt_instance.h: 22 (JSC::Bindings::QtInstance::QtSenderStack::top): 23 (JSC::Bindings::QtInstance::QtSenderStack::push): 24 (JSC::Bindings::QtInstance::QtSenderStack::pop): 25 Minimal functionality to manipulate the sender stack. 26 27 * bridge/qt/qt_runtime.cpp: 28 (JSC::Bindings::QtConnectionObject::execute): 29 Remove the previous code that modified the scope chain. Push the sender object 30 to the stack before calling the JavaScript function (the "slot" in Qt-speak) and 31 pop it afterwards. 32 1 33 2011-05-25 Sheriff Bot <webkit.review.bot@gmail.com> 2 34 -
trunk/Source/WebCore/bridge/qt/qt_instance.cpp
r84556 r87315 45 45 static QObjectInstanceMap cachedInstances; 46 46 47 // Used for implementing '__qt_sender__'. 48 Q_GLOBAL_STATIC(QtInstance::QtSenderStack, senderStack) 49 47 50 // Derived RuntimeObject 48 51 class QtRuntimeObject : public RuntimeObject { … … 322 325 } 323 326 327 QtInstance::QtSenderStack* QtInstance::qtSenderStack() 328 { 329 return senderStack(); 330 } 331 324 332 // In qt_runtime.cpp 325 333 JSValue convertQVariantToValue(ExecState*, PassRefPtr<RootObject> root, const QVariant& variant); -
trunk/Source/WebCore/bridge/qt/qt_instance.h
r84556 r87315 23 23 #include "BridgeJSC.h" 24 24 #include "runtime_root.h" 25 #include <QStack> 25 26 #include <QtScript/qscriptengine.h> 26 27 #include <qhash.h> … … 72 73 static QtInstance* getInstance(JSObject*); 73 74 75 class QtSenderStack { 76 public: 77 QObject* top() const { return m_stack.isEmpty() ? 0 : m_stack.top(); } 78 void push(QObject* object) { m_stack.push(object); } 79 void pop() { Q_ASSERT(!m_stack.isEmpty()); m_stack.pop(); } 80 private: 81 QStack<QObject*> m_stack; 82 }; 83 84 // Used to implement '__qt_sender__'. 85 static QtSenderStack* qtSenderStack(); 86 74 87 private: 75 88 static PassRefPtr<QtInstance> create(QObject *instance, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership) -
trunk/Source/WebCore/bridge/qt/qt_runtime.cpp
r86758 r87315 1839 1839 } 1840 1840 } 1841 // Stuff in the __qt_sender property, if we can 1842 ScopeChainNode* oldsc = 0; 1843 JSFunction* fimp = 0; 1844 if (m_funcObject->inherits(&JSFunction::s_info)) { 1845 fimp = static_cast<JSFunction*>(m_funcObject.get()); 1846 1847 JSObject* qt_sender = QtInstance::getQtInstance(sender(), ro, QScriptEngine::QtOwnership)->createRuntimeObject(exec); 1848 JSObject* wrapper = constructEmptyObject(exec, createEmptyObjectStructure(exec->globalData(), jsNull())); 1849 PutPropertySlot slot; 1850 wrapper->put(exec, Identifier(exec, "__qt_sender__"), qt_sender, slot); 1851 oldsc = fimp->scope(); 1852 fimp->setScope(exec->globalData(), oldsc->push(wrapper)); 1853 } 1841 1842 const bool withQtSenderStack = m_funcObject->inherits(&JSFunction::s_info); 1843 if (withQtSenderStack) 1844 QtInstance::qtSenderStack()->push(QObject::sender()); 1854 1845 1855 1846 CallData callData; … … 1857 1848 call(exec, m_funcObject.get(), callType, callData, m_thisObject.get(), l); 1858 1849 1859 if ( fimp)1860 fimp->setScope(exec->globalData(), oldsc);1850 if (withQtSenderStack) 1851 QtInstance::qtSenderStack()->pop(); 1861 1852 } 1862 1853 } -
trunk/Source/WebKit/qt/Api/qwebframe.cpp
r86949 r87315 23 23 24 24 #if USE(JSC) 25 #include "APICast.h" 25 26 #include "BridgeJSC.h" 26 27 #include "CallFrame.h" … … 50 51 #include "InspectorController.h" 51 52 #if USE(JSC) 53 #include "JavaScript.h" 52 54 #include "JSDOMBinding.h" 53 55 #include "JSDOMWindowBase.h" 54 56 #include "JSLock.h" 55 57 #include "JSObject.h" 58 #include "JSRetainPtr.h" 59 #include "OpaqueJSString.h" 56 60 #elif USE(V8) 57 61 #include "V8DOMWrapper.h" … … 472 476 #endif 473 477 } 478 479 void QWebFramePrivate::didClearWindowObject() 480 { 481 #if USE(JSC) 482 if (page->settings()->testAttribute(QWebSettings::JavascriptEnabled)) 483 addQtSenderToGlobalObject(); 484 #endif 485 emit q->javaScriptWindowObjectCleared(); 486 } 487 488 #if USE(JSC) 489 static JSValueRef qtSenderCallback(JSContextRef context, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*) 490 { 491 QObject* sender = JSC::Bindings::QtInstance::qtSenderStack()->top(); 492 if (!sender) 493 return JSValueMakeUndefined(context); 494 495 JSC::ExecState* exec = ::toJS(context); 496 RefPtr<JSC::Bindings::RootObject> rootObject = JSC::Bindings::findRootObject(exec->dynamicGlobalObject()); 497 JSC::JSObject* jsSender = JSC::Bindings::QtInstance::getQtInstance(sender, rootObject, QScriptEngine::QtOwnership)->createRuntimeObject(exec); 498 return ::toRef(jsSender); 499 } 500 501 void QWebFramePrivate::addQtSenderToGlobalObject() 502 { 503 JSC::JSLock lock(JSC::SilenceAssertionsOnly); 504 505 JSDOMWindow* window = toJSDOMWindow(frame, mainThreadNormalWorld()); 506 Q_ASSERT(window); 507 508 JSC::ExecState* exec = window->globalExec(); 509 Q_ASSERT(exec); 510 511 JSContextRef context = ::toRef(exec); 512 JSRetainPtr<JSStringRef> propertyName(Adopt, JSStringCreateWithUTF8CString("__qt_sender__")); 513 JSObjectRef function = JSObjectMakeFunctionWithCallback(context, propertyName.get(), qtSenderCallback); 514 515 // JSC public API doesn't support setting a Getter for a property of a given object, https://bugs.webkit.org/show_bug.cgi?id=61374. 516 window->defineGetter(exec, propertyName.get()->identifier(&exec->globalData()), ::toJS(function), 517 JSC::ReadOnly | JSC::DontEnum | JSC::DontDelete); 518 } 519 #endif 520 474 521 /*! 475 522 \class QWebFrame -
trunk/Source/WebKit/qt/Api/qwebframe_p.h
r86276 r87315 109 109 void _q_orientationChanged(); 110 110 111 void didClearWindowObject(); 112 111 113 QWebFrame *q; 112 114 Qt::ScrollBarPolicy horizontalScrollBarPolicy; … … 127 129 #if ENABLE(ORIENTATION_EVENTS) && ENABLE(DEVICE_ORIENTATION) 128 130 QtMobility::QOrientationSensor m_orientation; 131 #endif 132 133 private: 134 #if USE(JSC) 135 void addQtSenderToGlobalObject(); 129 136 #endif 130 137 }; -
trunk/Source/WebKit/qt/ChangeLog
r87312 r87315 1 2011-05-25 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> 2 3 Reviewed by Andreas Kling. 4 5 [Qt] JSC bridge: implement __qt_sender__ without using Scope Chain 6 https://bugs.webkit.org/show_bug.cgi?id=61343 7 8 Create a '__qt_sender__' property in the global object, that returns the top of 9 the qtSenderStack. This is an alternative implementation for the feature of 10 providing a way for a function (acting as a Qt 'slot') discover which object 11 emitted the signal that caused it to be executed. 12 13 This reduces the coupling of the Qt bridge and JSC internal implementation. The 14 patch tries to use as much JSC public API as possible. 15 16 This behavior is covered by the tst_QWebFrame::connectAndDisconnect() auto test. 17 18 * WebCoreSupport/FrameLoaderClientQt.cpp: 19 (WebCore::FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld): 20 Instead of emitting the QWebPage::javaScriptWindowObjectCleared() directly, calls 21 a QWebPagePrivate function to do it. 22 23 * Api/qwebframe_p.h: 24 * Api/qwebframe.cpp: 25 (QWebFramePrivate::didClearedWindowObject): 26 Before emitting the signal mentioned, adds the '__qt_sender__' to the fresh 27 global object. 28 29 (qtSenderCallback): 30 Returns the JSObjectRef corresponding to the top of qtSenderStack. 31 32 (QWebFramePrivate::addQtSenderToGlobalObject): 33 Create a property with a qtSenderCallback as getter function in the global object. 34 1 35 2011-05-25 Alexis Menard <alexis.menard@openbossa.org> 2 36 -
trunk/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
r87260 r87315 764 764 765 765 if (m_webFrame) 766 emit m_webFrame->javaScriptWindowObjectCleared();766 m_webFrame->d->didClearWindowObject(); 767 767 } 768 768
Note: See TracChangeset
for help on using the changeset viewer.