您的位置:首页 > 移动开发 > Objective-C

WebKit之addToJavaScriptWindowObject()分析

2015-11-29 22:45 555 查看
## Qt暴露QObject给JSC引擎的API源码

void QWebFrameAdapter::addToJavaScriptWindowObject(const QString& name, QObject* object, ValueOwnership ownership)
{
if (!pageAdapter->settings->testAttribute(QWebSettings::JavascriptEnabled))
return;
JSC::Bindings::QtInstance::ValueOwnership valueOwnership = static_cast<JSC::Bindings::QtInstance::ValueOwnership>(ownership);
JSDOMWindow* window = toJSDOMWindow(frame, mainThreadNormalWorld());
JSC::Bindings::RootObject* root;
if (valueOwnership == JSC::Bindings::QtInstance::QtOwnership)
root = frame->script()->cacheableBindingRootObject();
else
root = frame->script()->bindingRootObject();

if (!window) {
qDebug() << "Warning: couldn't get window object";
return;
}
if (!root) {
qDebug() << "Warning: couldn't get root object";
return;
}

JSC::ExecState* exec = window->globalExec();
JSC::JSLockHolder lock(exec);

JSC::JSObject* runtimeObject = JSC::Bindings::QtInstance::getQtInstance(object, root, valueOwnership)->createRuntimeObject(exec);

JSC::PutPropertySlot slot;
window->methodTable()->put(window, exec, JSC::Identifier(&exec->vm(), reinterpret_cast_ptr<const UChar*>(name.constData()), name.length()), runtimeObject, slot);
}


## JSC桥实例的创建源码

#include "config.h"
#include "BridgeJSC.h"

#include "JSDOMWindowBase.h"
#include "runtime_object.h"
#include "runtime_root.h"
#include "runtime/JSLock.h"
#include "runtime/ObjectPrototype.h"

#if PLATFORM(QT)
#include "qt_instance.h"
#endif

namespace JSC {

namespace Bindings {

Array::Array(PassRefPtr<RootObject> rootObject)
: m_rootObject(rootObject)
{
ASSERT(m_rootObject);
}

Array::~Array()
{
}

Instance::Instance(PassRefPtr<RootObject> rootObject)
: m_rootObject(rootObject)
{
ASSERT(m_rootObject);
}

Instance::~Instance()
{
ASSERT(!m_runtimeObject);
}

void Instance::begin()
{
virtualBegin();
}

void Instance::end()
{
virtualEnd();
}

JSObject* Instance::createRuntimeObject(ExecState* exec)
{
ASSERT(m_rootObject);
ASSERT(m_rootObject->isValid());
if (RuntimeObject* existingObject = m_runtimeObject.get())
return existingObject;

JSLockHolder lock(exec);
RuntimeObject* newObject = newRuntimeObject(exec);
m_runtimeObject = PassWeak<RuntimeObject>(newObject);
m_rootObject->addRuntimeObject(exec->vm(), newObject);
return newObject;
}

RuntimeObject* Instance::newRuntimeObject(ExecState* exec)
{
JSLockHolder lock(exec);

// FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
// We need to pass in the right global object for "i".
return RuntimeObject::create(exec, exec->lexicalGlobalObject(), WebCore::deprecatedGetDOMStructure<RuntimeObject>(exec), this);
}

void Instance::willInvalidateRuntimeObject()
{
m_runtimeObject.clear();
}

RootObject* Instance::rootObject() const
{
return m_rootObject && m_rootObject->isValid() ? m_rootObject.get() : 0;
}


## Qt基于JSC内定的bridge实例进行继承和扩展(为qt平台方便访问)

class QtInstance : public Instance {
public:
enum ValueOwnership {
QtOwnership,
ScriptOwnership,
AutoOwnership
};

~QtInstance();

virtual Class* getClass() const;
virtual RuntimeObject* newRuntimeObject(ExecState*);

virtual void begin();
virtual void end();

virtual JSValue valueOf(ExecState*) const;
virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;

virtual JSValue getMethod(ExecState*, PropertyName);
virtual JSValue invokeMethod(ExecState*, RuntimeMethod*);

virtual void getPropertyNames(ExecState*, PropertyNameArray&);

JSValue stringValue(ExecState* exec) const;
JSValue numberValue(ExecState* exec) const;
JSValue booleanValue() const;

QObject* getObject() const { return m_object.data(); }
QObject* hashKey() const { return m_hashkey; }

static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, ValueOwnership);

virtual bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
virtual void put(JSObject*, ExecState*, PropertyName, JSValue, PutPropertySlot&);

static QtInstance* getInstance(JSObject*);

private:
static PassRefPtr<QtInstance> create(QObject *instance, PassRefPtr<RootObject> rootObject, ValueOwnership ownership)
{
return adoptRef(new QtInstance(instance, rootObject, ownership));
}

friend class QtClass;
friend class QtField;
friend class QtRuntimeMethod;
QtInstance(QObject*, PassRefPtr<RootObject>, ValueOwnership); // Factory produced only..
mutable QtClass* m_class;
QPointer<QObject> m_object;
QObject* m_hashkey;
mutable QHash<QByteArray, QtRuntimeMethod*> m_methods;
mutable QHash<QString, QtField*> m_fields;
ValueOwnership m_ownership;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: