Вопросы по расширению Safari - PullRequest
12 голосов
/ 12 июня 2010

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

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

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

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

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

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

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

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

Ответы [ 4 ]

6 голосов
/ 14 июня 2010

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

У меня есть простое расширение без 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 голосов
/ 12 июня 2010

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

Код введенного скрипта:

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) из введенного скрипта. В моем случае скрипт загружается после загрузки страницы, но я не могу использовать safari.extension.settings.

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

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

2 голосов
/ 14 июня 2010

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

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

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

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

msgEvent.message = settings;

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

1 голос
/ 23 января 2012

сталкивается с той же проблемой, но ответ проще, чем вы можете себе представить: включите скрипт в глобальный 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

...