Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145838
  • 博文数量: 124
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 1745
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-24 13:49
文章分类

全部博文(124)

文章存档

2011年(55)

2010年(14)

2009年(30)

2008年(25)

我的朋友

分类: WINDOWS

2011-05-19 11:24:00

最精由于工作缘故需要解决一个问题。

或许大家都知道,在js中,如果你想使用其他窗口的domwindow那么需要满足一些条件,比如
大家出于同一个parent下,或者你是被parent打开的。


我由于工作需要,需要访问某个特定窗口的domwindow,因为那个窗口管理了很多数据对象,这些数据对象可供其他窗口使用。


由于js或者说浏览器不支持这个能力,因此需要自己添加。

大家或许注意到了js中 window 这个是一个内置对象,你是可以直接访问的。

或者说一旦你可以拿到另外一个窗口的window对象,不管是通过opener,还是frames那么久意味着你可以拿那个窗口的数据,或者呼叫它的函数。


因此我解决的第一个问题是,寻找window对象是如何生效的。

我这儿采用的是qt、qtwebkit架构研究的。

我去年工作时候搞过一段时间v8+webkit架构,http://blog.sunchrome.com/?p=33(不是我写的);


因此首先在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。

   






阅读(442) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~