开发者

Safari 5 Extension: How can I detect when a window's current tab has changed?

开发者 https://www.devze.com 2023-01-12 09:37 出处:网络
I have a Safari 5 extension that contains a toolbar. Whenever the current tab changes, that toolbar should be updated. I would like to do something like this from my bar\'s开发者_如何学C script:

I have a Safari 5 extension that contains a toolbar. Whenever the current tab changes, that toolbar should be updated. I would like to do something like this from my bar's开发者_如何学C script:

safari.self.browserWindow.addEventListener("activeTab", tabChanged, false);

However, that doesn't seem to work. I have tried a number of other event names as well:

  • activeTab
  • activeTabChanged
  • onActiveTab
  • onActiveTabChanged
  • tab
  • tabChanged
  • onTab
  • onTabChanged
  • selectionChanged
  • onSelectionChanged

Does anybody know how to detect when the active tab changes?

Not that this is in any way related, but it looks like I would do this in Chrome with:

 chrome.tabs.onSelectionChanged.addListener(tabChanged);


Safari 5.1 has several new events for extensions, including an "activate" event that fires when a window or tab is focused.

https://developer.apple.com/documentation/safariextensions/safariactivateevent


That's the event you are looking for. I'm not sure, but i think is a new addition to the extensions api. You can put in global.html or in the popover.html

safari.application.addEventListener("activate", activateHandler, true);

function activateHandler(event) {
    safari.application.activeBrowserWindow.activeTab.page.dispatchMessage('someId', false);
}


I agree with @imiaou 's answer: from looking at Apple's docs there doesn't seem to be a way to do this :(.

Since I needed to detect tab changes for my extension (which I'm porting over from Chrome), I did the following polling-based workaround which seems to be working fine (in my global page):

var prevActiveTab;

setInterval("poorMansOnTabChange()", 1500); //poll every 1.5 sec

function poorMansOnTabChange() {
    var curTab = safari.application.activeBrowserWindow.activeTab;
    if (curTab != prevActiveTab) {
        prevActiveTab= curTab;
        console.log("active tab changed!");
        //do work here
    }
}

I'm unhappy with constantly polling the browser, but I see no other way around this until Apple adds support for these tab-events. If your extension can live with a relatively relaxed tab-switch event trigger latency then this could be a reasonable workaround for now (1.5 sec. max latency is acceptable for my extension, and it doesn't feel like its slowing down the browser).


While Safari doesn't have Chrome's specific tab-related API, it does have a perfect solution to this problem.

@Galt was 99% of the way there, with the idea to add an event listener to your injected JavaScript and to dispatchMessage that information to your extension.

The event handler you're looking for is named focus, and gets fired every time a tab or window gets selected.

In your injected code:

var tabInFocus = function( event )
{
 safari.self.tab.dispatchMessage("tabFocusSwitched","");
}

window.addEventListener("focus", tabInFocus, false);

You can then update your extension's UI, with the data relevant to safari.application.activeBrowserWindow.activeTab


I found this method works better than focus event, it can be managed in the background page:

safari.application.addEventListener("validate", PopUp.validateCommand, false);

var PopUp = {

    activeTab : null,

    // commands are validated before being excecuted
    validateCommand : function(aEvent) {

        // this is a hack for detecting tab switches, safari does not have a dedicated API like Chrome 
        if(PopUp.activeTab !== null){
            if(PopUp.activeTab !== safari.application.activeBrowserWindow.activeTab){
                $.each(safari.application.browserWindows, function(aIndex, aWindow) {
                    $.each(aWindow.tabs, function(aIndex, aTab) {
                        //  message all tabs about the focus switch event
                        if (aTab !== safari.application.activeBrowserWindow.activeTab && aTab.page) {
                            aTab.page.dispatchMessage("tabUnfocused");
                        }else{
                            aTab.page.dispatchMessage("tabFocused");
                        }
                    });
                });
            }
        }
        // set the new active tab
        PopUp.activeTab = safari.application.activeBrowserWindow.activeTab;
    }
}


This code will help to trace the change in URL :- Write this code Inject.js , in side function


function trackURL() {

    alert("beforeNavigate "+safari.application.activeBrowserWindow.activeTab.url);
        setTimeout(function() {
            alert("afterNavigate "+safari.application.activeBrowserWindow.activeTab.url);

            }, 500);
    }
    safari.application.addEventListener("beforeNavigate", trackURL, true);


It seems Apple doesn't provide much API for us manipulating tabs like Chrome does. Currently, there is no way to detect tab event.


Unlike chrome which provides a special API for events like window and tab changes, you can still do it with safari extensions.

You simply have to have your injected javascript set up event listeners for the events that you want.

Then if that info is needed by global or other parts of the extension, you can pass the info in messages using the postMessage command.

injected.js:

window.addEventListener("load", loaded, false); safari.self.tab.dispatchMessage("somethinghappened","load");

0

精彩评论

暂无评论...
验证码 换一张
取 消