2010-06-11 14 views
12

Estoy en el proceso de crear mi primera extensión de Safari, una muy simple, pero me he encontrado con un par de problemas. La extensión se reduce a una única secuencia de comandos inyectada que intenta eludir el controlador de fuente nativo y redirigir a un URI http: //. Mis problemas hasta ahora son dobles:Preguntas de extensión de Safari

  1. La "lista blanca" no funciona de la manera que esperaría. Dado que todos los feeds se muestran bajo el protocolo "feed: //", intenté capturar eso en la lista blanca como "feed: // */*" (sin nada en la lista negra), pero termino en una solicitud loop que no puedo entender Si configuro lista negra valores de "http://*/*" y "https://*/*", todo funciona como se esperaba.
  2. No puedo encontrar la manera de acceder a mi configuración desde mi script insertado. La secuencia de comandos crea un controlador de eventos beforeload, pero no puede acceder a mi configuración mediante la ruta safari.extension.settings indicada en la documentación.

No he encontrado nada en la documentación de Apple que indique que la configuración no debería estar disponible en mi script. Dado que las extensiones son una característica tan nueva, incluso Google arroja resultados relevantes limitados y la mayoría proviene de la documentación oficial.

¿Qué me estoy perdiendo?

Gracias.

ACTUALIZACIÓN así que espero que la documentación es incompleta porque es limítrofe abismal, pero he aprendido un poco acerca de la configuración. Resulta que, a partir de scripts de inyección, el objeto SafariExtensionSettings no está disponible. Los scripts de inyección solo tienen acceso al objeto SafariContentExtension (que no es útil en absoluto), pero tiene un alias exactamente de la misma manera (safari.extension.settings) - mala idea, IMO. Como se indica en la injection script documentation:

Importante: Cuando se utiliza safari.extension desde dentro de un script inyectado, no se está dirigiendo a la clase SafariExtension. Te estás dirigiendo a la clase SafariContentExtension.

Debe usar el sistema de mensajería para hablar con un archivo HTML global que tenga acceso a la configuración. Es un poco raro, pero tengo un mensaje que se envía a un archivo global.html que recupera la configuración y enviará un mensaje a mi script de inyección tan pronto como sepa cómo hacerlo.

Como estoy haciendo todo mi trabajo antes de cargar el documento, todos los métodos que he encontrado para enviar el mensaje atrás dependen de un objeto de página que no tengo.

Respuesta

2

Me tomó varios días, pero creo que encontré una solución viable usando el método de mensajería canLoad(). Mi script de inyección recupera la configuración llamando a la página HTML mundial como esto:

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

mi archivo HTML mundial, a su vez, devuelve los ajustes como:

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

msgEvent.message = settings; 

Es todavía un poco más "hacky" de Me gustaría. Parece que no puedo simplemente devolver el objeto de configuración en sí, así que tengo que compilar un nuevo objeto recuperando cada configuración manualmente. No es ideal, pero parece ser efectivo.

3

EDIT: Como dijiste en tu actualización inicial de la publicación, la secuencia de comandos inyectada no tiene el mismo tipo de acceso que tendría una página HTML global. Esta es mi solución de trabajo, imagine que desea conocer el valor de ajuste de "foo" en el guión inyectada:

inyectado código de 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 

código HTML Global:

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

Esperanza esto ayuda !


mensaje inicial: Estoy teniendo el mismo segundo problema que tú, no puede acceder a la configuración de mi (o secureSettings) desde un script inyectado. En mi caso, el script se carga después de cargar la página, pero incluso así no puedo usar safari.extension.settings.

La única forma en que funciona es con una barra de herramientas/botón, el HTML detrás de ese elemento puede getItem y setItem como se esperaba.

Mi conclusión es que, por alguna razón, los scripts inyectados no pueden acceder a la configuración (en realidad, ni siquiera parecen tener acceso al elemento safari). Error o característica prevista, eso queda por descubrir.

+0

Eche un vistazo a las actualizaciones que he agregado anteriormente. Ahora sé por qué no puede acceder a las configuraciones e incluso ha indicado cómo llegar a ellas (a pesar de que no funciona para mí por otros motivos). –

+0

Acabo de encontrar una solución para mi problema, se publicó anteriormente para usted o cualquier otra persona con el mismo problema. ¡Tal vez puedas adaptarlo para tu caso! – Mars

+0

Gracias por la actualización. En mi caso, todo el trabajo se está realizando 'beforeload', por lo que el objeto de la página no está definido, lo que parece significar que el método' dispatchMessage() 'no está disponible. Todavía estoy buscando una solución a eso. –

6

Como todo el mundo en este momento, todavía estoy subiendo la curva de aprendizaje, pero aquí es como me he manejado este problema:

que tienen una extensión simple sin cromo y un script final inyectada (guión. js). Para cargar la configuración, agregué una página global simple (proxy.html). Cuando se inyecta script.js, envía un mensaje getSettings a proxy.html. proxy.html responde con un mensaje setSettings y script.js continúa la inicialización.

La página más útil que he encontrado en los documentos sobre este tema es 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"); 
}()) 
+0

Rick, eres un salvavidas! Muchas gracias por esto. –

1

topado con el mismo problema, pero la respuesta es más fácil que se puede imaginar: incluyen la secuencia de comandos en su html global.

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

entonces se puede acceder a la configuración como se describe en la documentación safari.extension.settings.myKey

también puede upvote @Travis, porque tengo la idea de his post

// EDIT:
realidad yo no' Realmente sé qué está mal. Llamar a la configuración como el primer comando funciona, pero no en un momento posterior. Además, parece corromper mi secuencia de comandos completa después de la 2. inyección. Necesita verificación si solo está en mi script (¿es difícil?)

// Edit2:
ahora tengo que trabajar para volver a la configuración del objeto a través de dispatchMessage()

en su 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"); 

y en global.html

switch (event.name) { 
case "getSettings": 
    // send the settings data 
    event.target.page.dispatchMessage("SETTINGS", safari.extension.settings); 

depender de this apple documentation

Cuestiones relacionadas