最精由于工作缘故需要解决一个问题。
或许大家都知道,在js中,如果你想使用其他窗口的domwindow那么需要满足一些条件,比如
大家出于同一个parent下,或者你是被parent打开的。
我由于工作需要,需要访问某个特定窗口的domwindow,因为那个窗口管理了很多数据对象,这些数据对象可供其他窗口使用。
由于js或者说浏览器不支持这个能力,因此需要自己添加。
大家或许注意到了js中 window 这个是一个内置对象,你是可以直接访问的。
或者说一旦你可以拿到另外一个窗口的window对象,不管是通过opener,还是frames那么久意味着你可以拿那个窗口的数据,或者呼叫它的函数。
因此我解决的第一个问题是,寻找window对象是如何生效的。
我这儿采用的是qt、qtwebkit架构研究的。
因此首先在qtwebkit代码中查找"window" 这个关键字,比较容易找到2个地方。
JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr structure, PassRefPtr window, JSDOMWindowShell* shell)
: JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell)
{
GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly)
};
addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
}
jsdomwindow.cpp
{ "defaultstatus", DontDelete, (intptr_t)static_cast
(jsDOMWindowDefaultstatus), (intptr_t)setJSDOMWindowDefaultstatus }, { "self", DontDelete, (intptr_t)static_cast
(jsDOMWindowSelf), (intptr_t)setJSDOMWindowSelf }, { "window", DontDelete|ReadOnly, (intptr_t)static_cast
(jsDOMWindowWindow), (intptr_t)0 }, { "frames", DontDelete, (intptr_t)static_cast
(jsDOMWindowFrames), (intptr_t)setJSDOMWindowFrames }, { "opener", DontDelete, (intptr_t)static_cast
(jsDOMWindowOpener), (intptr_t)setJSDOMWindowOpener }, { "parent", DontDelete, (intptr_t)static_cast
(jsDOMWindowParent), (intptr_t)setJSDOMWindowParent }, { "top", DontDelete, (intptr_t)static_cast
(jsDOMWindowTop), (intptr_t)setJSDOMWindowTop },
很简单写个例子debug一下就会发现前者实际上就是事实上的window对象关联。
这样一来就发现实际上window对象对应的是domwindowshell对象。
因此接下来事情就比较简单了
1. void JSDOMWindowBase::regDOMWindow(const String& name,JSDOMWindowBaseData* pd)
{
GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo(Identifier(globalExec(), name), pd->shell, DontDelete | ReadOnly)
};
addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
}
2. void QWebFrame::addDOMWindowToJavaScriptWindowObject(const QString &name, QWebFrame *object)
{
if (!page()->settings()->testAttribute(QWebSettings::JavascriptEnabled))
return;
JSC::JSLock lock(JSC::SilenceAssertionsOnly);
JSDOMWindow* selfWindow = toJSDOMWindow(d->frame, mainThreadNormalWorld());
JSDOMWindow* targetWindow = toJSDOMWindow(object->getPrivateData()->frame, mainThreadNormalWorld());
selfWindow->regDOMWindow(WebCore::String(name.toStdString().c_str()),targetWindow->d());
}
3. 在自己的demo代码中
// 将globalctx的js含义domwindow对象默认暴露给每个普通的hostwnd
ImHostWnd* pGlobalWndHost = qobject_cast(it->data());
if(pGlobalWndHost)
{
ui.webView->page()->mainFrame()->addDOMWindowToJavaScriptWindowObject(key, pGlobalWndHost->GetWebFrame());
}
这样用qtwebkit加载的也米娜,就可以访问globalctx这个对象,而这个对象实际上是一个全局webpage。
阅读(1356) | 评论(0) | 转发(0) |