首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在firefox中,JSAPI将不被识别

在firefox中,JSAPI将不被识别
EN

Stack Overflow用户
提问于 2013-03-08 04:00:51
回答 1查看 379关注 0票数 5

首先是一些关于我正在做的与火呼吸有关的背景。

  1. 我正在开发一个渲染浏览器插件,在浏览器中使用防火墙。
  2. 我在插件中定义了两个MIME类型,一个用于主查看器,另一个用于2D计划视图。
  3. 在每个页面中,只允许一个主查看器,但可以有多个2D计划视图。它们都共享在主查看器中打开的相同的模型文档。
  4. 因此,在实例化2D计划视图之后,我需要将document对象(一个消防JSAPI)传递给2d计划视图。

然后,假设主查看器和计划视图都被加载为“主查看器”和“planview”,我将按下面的方式将文档插入计划查看器,

代码语言:javascript
复制
planview.attach(mainviewer.doc); 
(the signature is "bool attach(const FB::JSObjectPtr& myDoc)" and 
The mainviewer.doc is just a firebreath JSAPI)

问题是,在firefox中,通过调用

代码语言:javascript
复制
FB::JSAPIPtr jsAPI = myDoc->getJSAPI(); // THIS WILL RETURN **NULL**.
m_main_doc = FB::ptr_cast<LcFbViewerDocumentAPI>(jsAPI); // Cast to my document API.

只有当主机浏览器是firefox时才会出现此问题,IE/Chrome运行良好。

那么,当使用firefox时,通过的JSAPI发生了什么变化呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-08 05:53:34

事实证明,大多数浏览器(包括FireFox)在允许将它们传递到另一个函数调用之前对NPObjects进行包装;因此,您无法获得最初传递给浏览器的底层C++类。因为FireBreath无法访问真正的JSAPI ( FireBreath用来包装JSAPI对象给浏览器的NPObject ),所以也不能访问原始的JSAPI对象。

考虑为JSAPI对象的每个实例创建一个静态id。然后,您可以将instance_id公开为JSAPI属性,然后创建一个全局std::map,用于存储映射以获取对象。

代码语言:javascript
复制
// in the class def
static int counter;
int instance_id;

// In the .cpp file
int MyPluginAPI::counter(0);

std::map<int, FB::JSAPIWeakPtr> apiMap;
FB::JSAPIPtr getJSAPIObjectById(int id) {
    std::map<int, FB::JSAPIWeakPtr> fnd = apiMap.find(id);
    if (fnd != apiMap.end()) {
        return fnd.second->lock(); // it's a weak pointer, lock to get the shared_ptr
    } else {
        return FB::JSAPIPtr(); // Alternately throw an exception
    }
}

MyPluginAPI::MyPluginAPI() {
    instance_id = counter++;
    // Note that you can't get at the shared_ptr in the constructor,
    // so you'll have to call an init function after creating the JSAPI object

    registerProperty("instance_id",
                 make_property(this,
                    &FBTestPluginAPI::get_instId));
}

int MyPluginAPI::get_instId() { return instance_id; }

void MyPluginAPI::init() {
    apiMap[instance_id] = shared_from_this();
}

当然,这最终会泄漏少量的内存,如果你从来没有经过地图和清除过期的弱ptrs,但它应该给你所需要的。当您得到一个应该是JSAPIPtr对象的对象时,您可以期望它是一个JSObjectPtr。

代码语言:javascript
复制
void doSomethingWithAnAPI(const FB::JSObjectPtr& obj) {
    if (obj) {
        int id = obj->GetProperty("instance_id");
        FB::JSAPIPtr ptr = getJSAPIObjectById(id);
        if (ptr) {
            // Hurray! We have the object
        }
    }
}

我还没有测试过上面的代码,但是应该非常接近。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15286464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档