Доступ к вкладкам в Firefox с расширением C ++ XPCOM - PullRequest
3 голосов
/ 18 ноября 2009

Какие интерфейсы XPCOM я должен использовать для обнаружения открытия, закрытия и переключения вкладок, а также для получения связанных с ними URL-адресов из расширения Firefox? Я видел примеры кода, который управляет вкладками в JS, но как насчет C ++?

1 Ответ

5 голосов
/ 20 ноября 2009

Вы можете написать небольшой компонент JS, который будет перенаправлять события табуляции на ваш компонент C ++, используя nsIObserverService.

В коде 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" ) )
    {
        /* . . . */
    }

    /* . . . */
}

А в вспомогательном 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;
        }
    }

    /* . . . */
}

Также есть несколько дополнительных кодов, которые вы должны добавить для обработки конкретных случаев. Например, когда пользователь закрывает окно браузера, вы не будете получать события TabClose для открытых вкладок в этом окне ... И не забывайте отменять регистрацию ваших наблюдателей, когда они вам больше не нужны.

...