Вопрос

Я в процессе создания моего первого расширения Safari - очень простой - но я столкнулся с парой проблем. Расширение сводится к одному, введенному скрипту, которое пытается обойти собственный обработчик подачи и перенаправить на http: // uri. Мои проблемы до сих пор находятся в два года:

  1. «Белом» не работает так, как я ожидал. Поскольку все каналы отображаются в протоколе «Feed: //», я пытался запечатлеть, что в белом виде как «кормить: // * / *» (ничем в черный список), но я в конечном итоге в запросе петля, которую я не могу понять. Если я установил черный список ценности "http: // * / *" а также "https: // * / *«Все работает, как ожидалось.
  2. Я не могу понять, как получить доступ к моим настройкам из моего введенного скрипта. Сценарий создает beforeload Обработчик событий, но не могу получить доступ к моим настройкам, используя safari.extension.settings Путь указан в документации.

Я ничего не нашел в документации Apple, чтобы указать, что настройки не должны быть доступны из моего сценария. Поскольку расширения являются такими новыми функциями, даже Google возвращает ограниченные соответствующие результаты и большинство из них из официальной документации.

Что мне не хватает?

ОБНОВИТЬПоэтому я надеюсь, что документация неполна, потому что это пограничная Abysmal, но я немного узнал о настройках. Оказывается, от впрыска сценариев, SafariExtensionSettings Объект не доступен. Сценарии впрыска имеют доступ только к SafariContentExtension объект (который вообще не полезен), но он псевдонится точно так же (safari.extension.settings) - Плохая идея, ИМО. Как указано в Документация в инъекционном скрипте:

Важно: при использовании Safari.extension из вводного скрипта вы не обращаетесь к классу Safariextension. Вы обращаетесь к классу SafaricontentExtension.

Вы должны использовать систему обмена сообщениями, чтобы поговорить с глобальным HTML-файлом, который имеет доступ к настройкам. Это вроде лозы, но у меня есть сообщение отправляется на global.html Файл, который извлекает настройки и отправит сообщение обратно в моем скрипте впрыска, как только я выясню, как сделать это.

Поскольку я делаю всю свою работу до нагрузки документов, все методы, которые я нашел, чтобы отправить сообщение назад полагаться на объект страницы, который у меня нет.

Это было полезно?

Решение 3

Мне потребовалось несколько дней, но я думаю, что нашел работоспособное решение, используя canLoad() Метод обмена сообщениями. Мой сценарий для инъекций извлекает настройки, позвонив на глобальную страницу HTML, как это:

settings = safari.self.tab.canLoad( event );

Мой глобальный файл HTML, в свою очередь, возвращает эти настройки как:

settings = {
  'setting1': safari.extension.settings.getItem( 'setting1' )
}

msgEvent.message = settings;

Это все еще немного больше «хаки», чем я хотел бы. Я не могу просто вернуть себе объект настроек, поэтому я должен скомпилировать новый объект, извлекая каждый настроек вручную. Не идеально, но это, кажется, эффективно.

Другие советы

Как и все остальные в этот момент, я все еще поднимаюсь на кривую обучения, но вот как я справлялся с этой проблемой:

У меня простое расширение без хрома и один впрыскиваемый конечный скрипт (Script.js). Для целей настроек загрузки я добавил простую глобальную страницу (Proxy.html). Когда Script.js вводится, он отправляет getSettings сообщение для proxy.html. proxy.html отвечает setSettings Сообщение и Script.js продолжают инициализацию.

Самая полезная страница, которую я нашел в документах на эту тему, Сообщения и прокси.

Proxy.html:

<!doctype html>
<html lang="en">
<head>
  <script type="text/javascript">
    safari.application.addEventListener( "message", function( e ) {
      if( e.name === "getSettings" ) {
        e.target.page.dispatchMessage( "setSettings", {
          sort_keys: safari.extension.settings.getItem( "sort_keys" )
        } );
      }
    }, false );
  </script>
</head>
<body></body>
</html>

Script.js:

( function() {
  var settings, init = function() {
    // do extension stuff
  };

  // listen for an incoming setSettings message
  safari.self.addEventListener( "message", function( e ) {
    if( e.name === "setSettings" ) {
      settings = e.message;
      init();
    }
  }, false );

  // ask proxy.html for settings
  safari.self.tab.dispatchMessage( "getSettings" );
}() )

РЕДАКТИРОВАТЬ: Как вы сказали в вашем первоначальном обновлении после сообщения, введенный скрипт не имеет такого же доступа к тому же доступе, что будет иметь глобальную HTML-страницу. Это мое рабочее решение, представьте, что вы хотите узнать ценность настройки «FO» в введенном скрипте:

Инъекционный код сценария:

function getMessage(msgEvent) {

    if (msgEvent.name == "settingValueIs")
        alert("Value for asked setting is: " + msgEvent.message);

}

safari.self.tab.dispatchMessage("getSettingValue", "foo"); // ask for value
safari.self.addEventListener("message", getMessage, false); // wait for reply

Глобальный HTML-код:

function respondToMessage(messageEvent) {

    if (messageEvent.name == "getSettingValue") {

           // getItem("foo");
        var value = safari.extension.settings.getItem(messageEvent.message);
        // return value of foo to injected script
           safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("settingValueIs", value);

    } 

}

safari.application.addEventListener("message",respondToMessage,false);

Надеюсь это поможет !


Начальный пост: У меня такая же 2-я проблема, что и вы, я не могу получить доступ к моим настройкам (или креплениям) из вводящего скрипта. В моем случае скрипт загружен после нагрузки страницы, но даже таким образом я не могу использовать safari.extension.settings.

Единственный способ работает, это с панелью инструментов / кнопки, HTML за этим элементом может getItem а также setItem как и ожидалось.

Мой вывод заключается в том, что по какой-то причине введенные скрипты не могут получить доступ к настройкам (на самом деле, они даже не имеют доступа к safari элемент). Ошибка или предполагаемая особенность, это осталось выяснить.

Бегите в ту же проблему, но ответ проще, чем вы можете себе представить: включить сценарий в глобальном HTML.

<!DOCTYPE HTML>
<script type="text/javascript" src="cleanup.js"></script>
<script>
…
</script>

Затем вы можете получить доступ к настройкам, как описано в документации safari.extension.settings.myKey

Вы также можете повысить @travis, потому что я получил идею от его пост

//РЕДАКТИРОВАТЬ:
На самом деле я не знаю, что не так. Призывая настройки как первая команда работает, но не позднее. Дополнительно это, кажется, повреждает мой полный скрипт после 2. инъекции. Нужна проверка, если это только в моем (сложном?) Скрипте.

// edit2:
Теперь я получил его на работу, чтобы вернуть объект настроек через dispatchMessage()

в твоем injected.js

function gotSettings(msgEvent) {
   if (msgEvent.name === "SETTINGS") {
      setts = msgEvent.message;
      alert(setts.mySetting1);
      // run the programm
   }
}

safari.self.addEventListener("message", gotSettings, false);
safari.self.tab.dispatchMessage("getSettings");

И в global.html

switch (event.name) {
case "getSettings":
   // send the settings data
   event.target.page.dispatchMessage("SETTINGS", safari.extension.settings);

полагаясь на это Документация Apple

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top