12

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

  1. “白名单”没有按我预期的方式工作。由于所有提要都显示在“feed://”协议下,我试图在白名单中将其捕获为“feed://*/*”(黑名单中没有任何内容),但我最终收到了一个请求我无法理解的循环。如果我设置“ http://*/* ”和“ https://*/* ”的黑名单值,一切都会按预期工作。
  2. 我不知道如何从注入的脚本中访问我的设置。该脚本创建了一个beforeload事件处理程序,但无法使用safari.extension.settings文档中指示的路径访问我的设置。

我在 Apple 的文档中没有发现任何内容表明我的脚本中不应提供设置。由于扩展是一个新功能,即使是谷歌也返回有限的相关结果,其中大部分来自官方文档。

我错过了什么?

更新 所以我希望文档不完整,因为它非常糟糕,但我已经了解了一些关于设置的知识。事实证明,从注入脚本中,该SafariExtensionSettings对象不可用。注入脚本只能访问该SafariContentExtension对象(这根本没有用),但它的别名方式完全相同(safari.extension.settings)——IMO 是个坏主意。如注入脚本文档中所述:

重要提示:当您在注入脚本中使用 safari.extension 时,您并没有解决 SafariExtension 类。您正在解决 SafariContentExtension 类。

您必须使用消息系统与可以访问设置的全局 HTML 文件对话。这有点循环,但是我有一条消息被发送到一个global.html文件中,该文件检索设置,一旦我弄清楚如何去做,就会将一条消息发送回我的注入脚本。

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

4

4 回答 4

6

像此时的其他人一样,我仍在攀登学习曲线,但我是这样处理这个问题的:

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

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

代理.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>

脚本.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" );
}() )
于 2010-06-14T03:56:28.647 回答
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元素)。错误或预期的功能,还有待弄清楚。

于 2010-06-12T13:06:06.463 回答
2

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

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

反过来,我的全局 HTML 文件将这些设置返回为:

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

msgEvent.message = settings;

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

于 2010-06-13T21:58:39.913 回答
1

遇到同样的问题,但答案比您想象的要容易:将脚本包含在您的全局 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);

依靠这个苹果文档

于 2012-01-22T21:14:23.057 回答