Подтвердить что ты не робот

Вопросы расширения Safari

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

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

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

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

ОБНОВЛЕНИЕ Итак, я надеюсь, что документация неполная, потому что она ужасна, но я немного узнал о настройках. Оказывается, что из сценариев SafariExtensionSettings объект SafariExtensionSettings недоступен. Инъекционные сценарии имеют доступ только к объекту SafariContentExtension (который вообще бесполезен), но он имеет псевдоним точно таким же образом (safari.extension.settings) --bad, IMO. Как указано в документации сценария внедрения:

Важное замечание: Когда вы используете safari.extension из внедренного скрипта, вы не обращаетесь к классу SafariExtension. Вы обращаетесь к классу SafariContentExtension.

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

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

4b9b3361

Ответ 1

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

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

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

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

msgEvent.message = settings;

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

Ответ 2

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

У меня есть простое расширение без Chrome и один введенный скрипт конца (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" );
}() )

Ответ 3

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

Введенный script код:

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);

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


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

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

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

Ответ 4

запускается в ту же проблему, но ответ проще, чем вы можете себе представить: включите script в свой глобальный html.

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

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

вы также можете повысить @Travis, потому что я получил идею от своего сообщения

//EDIT:
на самом деле я действительно не знаю, что случилось. Вызов настроек в качестве первой команды работает, но не позднее. Кроме того, это похоже на развращение моего полного script после 2. инъекции. Нужна проверка, если это только в моей (трудной?) script.

//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);

полагаясь на эту документацию по яблоко