Safari扩展:全新标签的活动? [英] Safari extension: Event for a completely new tab?

查看:189
本文介绍了Safari扩展:全新标签的活动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将Safari中的新标签重定向到某个网址,实质上是更改默认的新标签页。但是,我不想重定向通过以下链接打开的新标签。

I'm looking to redirect new tabs in Safari to a certain URL, in essence changing the default new tab page. However, I do not want to redirect new tabs that are opened by following links.

Windows和Tabs API 描述了标签开放事件,但这些事件在任何打开新选项卡(包括从链接打开的新选项卡)。

The Windows and Tabs API describes tab "open" events, but these are fired when any new tab opens (including new tabs opened from links).

是否有办法仅为通过单击新选项卡创建的选项卡捕获新选项卡事件按钮?

Is there a way to catch a new tab event for only those tabs that are created by clicking the new tab button?

提前致谢!

推荐答案

在你的打开事件处理程序,首先检查事件目标是否为选项卡。如果是,请在该选项卡上为 beforeNavigate 事件注册事件处理程序。如果 beforeNavigate 事件未在50毫秒内触发,也设置超时以取消注册处理程序。例如:

In your open event handler, first check if the event target is a tab. If it is, register an event handler for the beforeNavigate event on that tab. Also set a timeout to deregister the handler if the beforeNavigate event does not fire within, say, 50 milliseconds. For example:

function handleOpen(e) {
    if (e.target instanceof SafariBrowserTab) {
        e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false);
        setTimeout(function () {
            e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
        }, 50);
    }
}

现在,有三个相关的可能结果<选项卡打开事件后code> beforeNavigate 事件。

Now, there are three relevant possible outcomes for the beforeNavigate event following a tab open event.

案例1 beforeNavigate 事件不会在超时内触发。这通常意味着选项卡为空。空标签不能是链接点击的结果,所以我们可以在超时功能中放入一些代码来做我们喜欢的任何事情:

Case 1: The beforeNavigate event will not fire within the timeout. This usually means that the tab is empty. An empty tab cannot be the result of a link click, so we can put some code in the timeout function to do whatever we like with it:

function handleOpen(e) {
    if (e.target instanceof SafariBrowserTab) {
        e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false);
        setTimeout(function () {
            e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
            takeOverTab();
        }, 50);
    }
}

案例2 beforeNavigate 事件将触发,其 url 属性的值为 null 。这意味着该选项卡将加载热门站点页面或书签页面(两个特殊的Safari页面,这些页面是新选项卡的选项之一)。就像一个空标签一样,这样的标签不可能是链接点击的结果,所以我们可以用标签做我们喜欢的事情。例如:

Case 2: The beforeNavigate event will fire, and its url property will have a value of null. This means that the tab will load either the Top Sites page or the Bookmarks page (two special Safari pages that are among the options for new tabs). Like an empty tab, such a tab cannot possibly be the result of a link click, so we can do what we like with the tab. For example:

function handleBeforeNavigate(e) {
    e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
    if (e.url === null) {
        takeOverTab();
    }
}

案例3 :将触发 beforeNavigate ,并且其 url 值将为非空字符串:即实际URL。这是一个棘手的情况,因为选项卡可能来自链接点击,new-tab命令(如果用户已配置Safari以打开其主页的新选项卡),或另一个应用程序或扩展的操作。让我们调用选项卡是链接点击案例3A的结果的情况;案例3B,它是new-tab命令的结果;和其他应用案例,案例3C。

Case 3: The beforeNavigate will fire, and its url value will be a non-empty string: that is, an actual URL. This is the tricky case, since the tab could have resulted from either a link click, the new-tab command (if the user has configured Safari to open new tabs to his home page), or the action of another app or extension. Let's call the case where the tab was the result of a link click Case 3A; the case where it was the result of the new-tab command, Case 3B; and the other-app case, Case 3C.

我想不出区分3B和3C的方法。如果真的没有办法区分这两种情况,那么对你的应用来说可能非常糟糕,因为你可能不想重定向其他应用程序打开的标签。

I can't think of a way to distinguish between 3B and 3C. If there really isn't a way to distinguish these two cases, it could be very bad for your app, since you presumably don't want to redirect tabs that are opened by other apps.

如果您不关心您的应用程序是否干扰3C选项卡,则至少有一种方法可以告知3B / 3C选项卡中的3A选项卡。这就是我发生的方式:

If you don't care whether your app interferes with 3C tabs, there is at least one way to tell 3A tabs from 3B/3C tabs. This is the way that occurs to me:


  • 在每个页面中使用注入的脚本来监听链接点击。单击链接时,将URL和点击时间转发到全局页面,这将记住它们以供将来参考。例如:

  • Use an injected script in every page to listen for link clicks. When a link is clicked, relay the URL and the time of the click to the global page, which will remember them for future reference. For example:

function handleMessage(e) {
    if (e.name === 'linkClicked') {
        lastClickedLinkUrl = e.message.url;
        lastLinkClickTime = e.message.clickTime;
    }
}


  • 中beforeNavigate handler,测试事件的 url 值是否与上次单击的链接的URL不同。如果是,则新选项卡不是由该链接单击产生的,因此它可能不是由任何链接点击产生的。如果两个URL相同,请检查自上次链接点击以来是否超过100毫秒。如果是这种情况,那么URL可能只是巧合,因此您可以再次推断新选项卡不是来自链接点击。例如:

  • In your beforeNavigate handler, test whether the event's url value is different from the URL of the last-clicked link. If it is, the new tab did not result from that link click, and thus it probably did not result from any link click. If the two URLs are the same, check whether more than, say, 100 milliseconds have elapsed since the last link click. If that's the case, it's probably just a coincidence that the URLs are the same, and so again you can infer that the new tab did not result from a link click. For example:

    function handleBeforeNavigate(e) {
        e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
        if (e.url === null) {
            takeOverTab();
        } else if (e.url !== lastClickedLinkUrl || (new Date) - lastLinkClickTime > 100) {
            takeOverTab();
        }
    }
    


  • 请注意,这种检测方法并非万无一失。可能有很多方法可能会出错。不过,我希望这会有所帮助。

    Note that this detection method is not foolproof. There are probably a number of ways it could go wrong. Still, I hope this helps.

    这篇关于Safari扩展:全新标签的活动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆