2012-04-13 2 views
3

Я ищу, чтобы перенаправить новые вкладки в Safari на определенный URL, по существу изменяя новую вкладку по умолчанию. Однако я не хочу перенаправлять новые вкладки, которые открываются по следующим ссылкам.Расширение Safari: событие для совершенно новой вкладки?

Windows and Tabs API описывает вкладки «открытые» события, но они запускаются, когда любое открытие (включая новые вкладки, открытые из ссылок).

Есть ли способ поймать новое событие табуляции только для тех вкладок, которые создаются нажатием кнопки новой вкладки?

Заранее благодарен!

ответ

6

В обработчике событий open сначала проверьте, является ли цель события табуляцией. Если это так, зарегистрируйте обработчик событий для события beforeNavigate на этой вкладке. Также установите тайм-аут, чтобы отменить регистрацию обработчика, если событие beforeNavigate не срабатывает, скажем, 50 миллисекунд. Например:

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

Теперь, есть три соответствующие возможные исходов для beforeNavigate события следующих вкладок события открытия.

Дело 1: Событие beforeNavigate не срабатывает в течение таймаута. Обычно это означает, что вкладка пуста. Вкладка пустая, не может быть результатом ссылки клик, поэтому мы можем положить некоторый код в функции тайм-аута, чтобы делать то, что нам нравится с ним:

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, которые входят в число опций для новых вкладок). Подобно пустой вкладке, такая вкладка не может быть результатом щелчка ссылки, поэтому мы можем делать то, что нам нравится с вкладкой. Например:

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

Случай 3: beforeNavigate будет срабатывать, и его значение url будет непустая строка: то есть, фактический URL. Это сложный случай, поскольку вкладка могла быть результатом щелчка ссылки, команды новой вкладки (если пользователь настроил Safari для открытия новых вкладок на своей домашней странице) или действия другого приложения или расширения. Назовем случай, когда вкладка была результатом ссылки, нажмите «Случай 3A»; случай, когда он был результатом команды new-tab, Case 3B; и случае другого приложения, Case 3C.

Я не могу придумать способ различать 3B и 3C. Если действительно невозможно отличить эти два случая, это может быть очень плохо для вашего приложения, поскольку вы, по-видимому, не хотите перенаправлять вкладки, открытые другими приложениями.

Если вам не важно, вмешивается ли ваше приложение в закладки 3C, есть хотя бы один способ рассказать вкладки 3A из вкладок 3B/3C. Это так происходит со мной:

  • Использовать встраиваемый скрипт на каждой странице, чтобы прослушивать ссылки. При щелчке ссылки вы можете перенаправить URL-адрес и время клика на глобальную страницу, которая будет помнить их для использования в будущем.Например:

    function handleMessage(e) { 
        if (e.name === 'linkClicked') { 
         lastClickedLinkUrl = e.message.url; 
         lastLinkClickTime = e.message.clickTime; 
        } 
    } 
    
  • В вашем beforeNavigate обработчика, тест отличается ли от URL последней щелкнули ссылку значения мероприятия url. Если это так, новая вкладка не была получена из этой ссылки, и, следовательно, она, вероятно, не вызвана ни одним нажатием ссылки. Если оба URL одинаковы, проверьте, прошло ли больше, чем, скажем, 100 миллисекунд, с момента последнего щелчка ссылки. Если это так, вероятно, просто совпадение, что URL-адреса одинаковы, и поэтому вы можете сделать вывод, что новая вкладка не была вызвана щелчком ссылки. Например:

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

Следует отметить, что этот метод обнаружения не является надежным. Возможно, есть несколько способов, по которым это может пойти не так. Тем не менее, я надеюсь, что это поможет.

+0

Большое спасибо! Я сделаю это и дам вам знать, как это происходит. – Kevin

+0

Еще раз спасибо! Ваш код был очень полезен, особенно идея записи кликов (случай 3A). – Kevin

+0

Можете ли вы показать, как мне слушать клики в injected.js? – itzhar

Смежные вопросы