Safari扩展问题

时间:2010-06-11 22:38:22

标签: safari safari-extension

我正在构建我的第一个Safari扩展 - 一个非常简单的扩展 - 但我遇到了一些问题。扩展名归结为单个注入脚本,该脚本尝试绕过本机Feed处理程序并重定向到http:// URI。到目前为止,我的问题有两个:

  1. “白名单”并没有像我期望的那样发挥作用。由于所有Feed都显示在“feed://”协议下,因此我尝试将其作为“feed:// * / *”(黑名单中没有任何内容)在白名单中捕获,但我最终在请求中循环,我无法理解。如果我将黑名单值设置为“http://*/*”和“https://*/*”,则一切正常。
  2. 我无法弄清楚如何从我注入的脚本中访问我的设置。该脚本会创建一个beforeload事件处理程序,但无法使用文档中指示的safari.extension.settings路径访问我的设置。
  3. 我在Apple的文档中没有找到任何内容,表明我的脚本不应该提供设置。由于扩展功能是一项新功能,因此即使是Google也会返回有限的相关结果,其中大部分都来自官方文档。

    我错过了什么?

    感谢。

    更新 所以我希望文档不完整,因为它的边界非常糟糕,但我已经了解了一些设置。事实证明,从注入脚本,SafariExtensionSettings对象不可用。注入脚本只能访问SafariContentExtension对象(完全没用),但它的别名方式完全相同(safari.extension.settings) - 不好主意,IMO。如injection script documentation中所述:

      

    重要提示:当您在注入的脚本中使用safari.extension时,您不会处理SafariExtension类。您正在处理SafariContentExtension类。

    您必须使用消息传递系统与可以访问设置的全局HTML文件进行通信。它有点循环,但我有一条消息被发送到global.html文件,它检索设置,并在我弄清楚如何去做这件事后立即将消息发送回我的注入脚本。

    由于我在文档加载之前完成了所有工作,所以我发现发送消息的所有方法都依赖于我没有的页面对象。

4 个答案:

答案 0 :(得分:6)

就像其他人一样,我仍然在攀登学习曲线,但这就是我如何处理这个问题:

我有一个简单的扩展,没有chrome和一个注入的结束脚本(script.js)。为了加载设置,我添加了一个简单的全局页面(proxy.html)。注入script.js时,它会向proxy.html发送getSettings消息。 proxy.html以setSettings消息响应,并且script.js继续初始化。

我在这个主题的文档中找到的最有用的页面是Messages and Proxies

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" );
}() )

答案 1 :(得分:3)

编辑:就像您在初次更新后所说的那样,注入的脚本与全局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可以getItemsetItem按预期进行。

我的结论是,由于某种原因,注入的脚本无法访问设置(实际上,它们甚至似乎无法访问safari元素)。错误或预期的功能,剩下要弄清楚了。

答案 2 :(得分:2)

我花了几天时间,但我认为我找到了一个使用canLoad()消息传递方法的可行解决方案。我的注入脚本通过调用全局HTML页面来检索设置,如下所示:

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

我的全局HTML文件又将这些设置返回为:

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

msgEvent.message = settings;

它仍然比我想要的更“hacky”。我似乎无法简单地返回设置对象本身,因此我必须通过手动检索每个设置来编译新对象。不理想,但似乎确实有效。

答案 3 :(得分:1)

遇到同样的问题,但答案比你想象的要容易:在全局html中加入脚本。

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

然后您可以按照文档safari.extension.settings.myKey

中的说明访问设置

你也可以赞成@Travis,因为我从his post

得到了这个想法

//编辑:
实际上我真的不知道什么是错的。将设置作为第一个命令调用有效,但不会在以后进行。此外,它似乎在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);

依赖this Apple文档