从浏览器插件(NPAPI)生成异步Javascript事件

时间:2009-12-19 03:48:35

标签: javascript browser plugins npapi

我正在编写一个网络浏览器插件(NPAPI。)

我的插件启动了一个工作线程,随着工作人员的进展,我想将事件传回Javascript。但是由于NPAPI线程模型,工作线程直接回调到NPAPI是不合法的,因此工作线程不能调用Javascript。

对此的一个解决方案是NPN_PluginThreadAsyncCall函数。但这是一个相对较新的功能。例如,它仅受Firefox 3支持。

有没有办法在不使用NPN_PluginThreadAsyncCall的情况下从NPAPI插件中获取异步事件传递/ javascript执行?在添加此功能之前,人们做了什么?

1 个答案:

答案 0 :(得分:5)

答案是肯定的......没有......

如果您需要支持旧浏览器(pre firefox 3),您可以自己实现NPN_PluginThreadAsyncCall功能。在Windows上,您可以通过创建一个可以保存函数指针和void * opaque指针的数据结构来完成此操作,然后使用指向您的数据结构的指针将自定义消息发布到主窗口作为LPARAM。

主窗口WINPPROC在UI线程上运行,这是可以与Javascript通信的线程。因此,当您在WINPROC中获取该消息时,只需将LPARAM转换回指针,使用不透明数据调用该方法,然后释放数据结构。

在Mac上,您可以使用队列来执行类似的事情来存储事件,然后执行NULL事件(由Mac OS发送每个tick),检查是否有任何内容。如果是这样,请将其弹出,调用方法,释放它,继续前进。

也许有一种方法可以在linux上进行,但我不知道它是什么。

您可以在firebreath project中找到Windows版本的示例。

winproc消息的处理在此文件中: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

事件和数据结构在其头文件中定义: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

触发该事件的方法如下:

void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData)
{
    if (m_hWnd != NULL) 
        ::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL, 
            (LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData));
}