我正在构建我的第一个Safari扩展 - 一个非常简单的扩展 - 但我遇到了一些问题。扩展名归结为单个注入脚本,该脚本尝试绕过本机Feed处理程序并重定向到http:// URI。到目前为止,我的问题有两个:
beforeload
事件处理程序,但无法使用文档中指示的safari.extension.settings
路径访问我的设置。我在Apple的文档中没有找到任何内容,表明我的脚本不应该提供设置。由于扩展功能是一项新功能,因此即使是Google也会返回有限的相关结果,其中大部分都来自官方文档。
我错过了什么?
感谢。
更新
所以我希望文档不完整,因为它的边界非常糟糕,但我已经了解了一些设置。事实证明,从注入脚本,SafariExtensionSettings
对象不可用。注入脚本只能访问SafariContentExtension
对象(完全没用),但它的别名方式完全相同(safari.extension.settings
) - 不好主意,IMO。如injection script documentation中所述:
重要提示:当您在注入的脚本中使用safari.extension时,您不会处理SafariExtension类。您正在处理SafariContentExtension类。
您必须使用消息传递系统与可以访问设置的全局HTML文件进行通信。它有点循环,但我有一条消息被发送到global.html
文件,它检索设置,并在我弄清楚如何去做这件事后立即将消息发送回我的注入脚本。
由于我在文档加载之前完成了所有工作,所以我发现发送消息的的所有方法都依赖于我没有的页面对象。
答案 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可以getItem
和setItem
按预期进行。
我的结论是,由于某种原因,注入的脚本无法访问设置(实际上,它们甚至似乎无法访问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文档