使用 C++ 访问 Firefox 上的选项卡XPCOM 扩展

发布于 08-11 18:51 字数 97 浏览 8 评论 0原文

我应该使用什么 XPCOM 接口来检测选项卡的打开、关闭和切换,并从 Firefox 扩展获取其关联的 URL? 我见过在 JS 中管理选项卡的代码实例,但是在 C++ 中怎么样?

What XPCOM interfaces should I use to detect opening, closing and switching of tabs and also get their associated URL from a firefox extension?
I have seen instances of code that manage tabs in JS, but how about from C++ ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖上的星空2024-08-18 18:51:25

您可以编写小型 JS 组件,使用 nsIObserverService 将选项卡事件重新路由到 C++ 组件。

在 C++ 代码中,您可以使用此代码片段将组件注册为用于重新路由选项卡事件的用户定义事件的观察者。

NS_IMETHODIMP MyCppComponent::Observe(nsISupports *aSubject,
    const char *aTopic,
    const PRUnichar *aData)
{
    if( !strcmp( aTopic, "xpcom-startup" ) )
    {
        nsCOMPtr<nsIObserverService> observerService = 
            do_GetService( "@mozilla.org/observer-service;1" );
        observerService->AddObserver( this, "my-tab-open", false );
        observerService->AddObserver( this, "my-tab-close", false );
        observerService->AddObserver( this, "my-tab-select", false );
    }
    else if( !strcmp( aTopic, "my-tab-open" ) )
    {
        /* . . . */
    }
    else if( !strcmp( aTopic, "my-tab-close" ) )
    {
        /* . . . */
    }
    else if( !strcmp( aTopic, "my-tab-select" ) )
    {
        /* . . . */
    }

    /* . . . */
}

在 helper JS 组件中,您应该订阅选项卡事件,在事件处理程序中,您可以提取所需的数据并引发用户定义的事件来执行 C++ 代码。

function tabOpened(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-open", "some data");
}

function tabClosed(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-close", "some data");
}

function tabSelected(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-select", "some data");
}

function contentWndLoad(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    var browser = getMostRecentBrowserWindow().getBrowser();

    browser.tabContainer.addEventListener("TabOpen", tabOpened, false);
    browser.tabContainer.addEventListener("TabClose", tabClosed, false);
    browser.tabContainer.addEventListener("TabSelect", tabSelected, false);
}

MyJsComponent.prototype = {

    /* . . . */

    observe: function(aSubject, aTopic, aData) {
        switch(aTopic) {
            case "xpcom-startup":
                var obsSvc = CC["@mozilla.org/observer-service;1"].
                    getService(CI.nsIObserverService);
                obsSvc.addObserver(this, "toplevel-window-ready", false);
                break;

            case "toplevel-window-ready":
                aSubject.addEventListener("load", contentWndLoad, false);
                break;
        }
    }

    /* . . . */
}

此外,您还应该添加一些额外的代码来处理特定情况。例如,当用户关闭浏览器窗口时,您将不会收到该窗口中打开的选项卡的 TabClos​​e 事件...并且当您不再需要观察者时,不要忘记取消注册它们。

You can write small JS component that will reroute tab events to your C++ component using nsIObserverService.

In C++ code you can use this snippet to register your component as observer to user defined events that is used for rerouting tab events.

NS_IMETHODIMP MyCppComponent::Observe(nsISupports *aSubject,
    const char *aTopic,
    const PRUnichar *aData)
{
    if( !strcmp( aTopic, "xpcom-startup" ) )
    {
        nsCOMPtr<nsIObserverService> observerService = 
            do_GetService( "@mozilla.org/observer-service;1" );
        observerService->AddObserver( this, "my-tab-open", false );
        observerService->AddObserver( this, "my-tab-close", false );
        observerService->AddObserver( this, "my-tab-select", false );
    }
    else if( !strcmp( aTopic, "my-tab-open" ) )
    {
        /* . . . */
    }
    else if( !strcmp( aTopic, "my-tab-close" ) )
    {
        /* . . . */
    }
    else if( !strcmp( aTopic, "my-tab-select" ) )
    {
        /* . . . */
    }

    /* . . . */
}

And in helper JS component you should to subscribe to tab events and in event handlers you can extract desired data and raise user defined events to execute C++ code.

function tabOpened(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-open", "some data");
}

function tabClosed(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-close", "some data");
}

function tabSelected(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
        "my-tab-select", "some data");
}

function contentWndLoad(event) {
    var obsSvc = CC["@mozilla.org/observer-service;1"].
        getService(CI.nsIObserverService);
    var browser = getMostRecentBrowserWindow().getBrowser();

    browser.tabContainer.addEventListener("TabOpen", tabOpened, false);
    browser.tabContainer.addEventListener("TabClose", tabClosed, false);
    browser.tabContainer.addEventListener("TabSelect", tabSelected, false);
}

MyJsComponent.prototype = {

    /* . . . */

    observe: function(aSubject, aTopic, aData) {
        switch(aTopic) {
            case "xpcom-startup":
                var obsSvc = CC["@mozilla.org/observer-service;1"].
                    getService(CI.nsIObserverService);
                obsSvc.addObserver(this, "toplevel-window-ready", false);
                break;

            case "toplevel-window-ready":
                aSubject.addEventListener("load", contentWndLoad, false);
                break;
        }
    }

    /* . . . */
}

Also there are some additional code that you should add to handle specific cases. For instance when user close browser window you won't receive TabClose events for opened tabs in that window... And don’t forget to unregister your observers when you longer need them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文