2010-06-11 9 views
12

Sono in procinto di costruire la mia prima estensione di Safari - una molto semplice - ma ho incontrato un paio di problemi. L'estensione si riduce a un singolo script iniettato che tenta di ignorare il gestore di feed nativo e reindirizzare a un URI http: //. I miei problemi finora sono due:Domande sull'estensione del Safari

  1. La "whitelist" non funziona come mi aspetterei. Poiché tutti i feed sono mostrati sotto il protocollo "feed: //", ho cercato di catturarlo nella whitelist come "feed: // */*" (senza nulla nella blacklist), ma alla fine trovo una richiesta loop che non riesco a capire. Se imposto i valori della lista nera di "http://*/*" e "https://*/*", tutto funziona come previsto.
  2. Non riesco a capire come accedere alle mie impostazioni dal mio script immesso. Lo script crea un gestore di eventi beforeload, ma non può accedere alle mie impostazioni utilizzando il percorso safari.extension.settings indicato nella documentazione.

non ho trovato nulla nella documentazione di Apple per indicare che le impostazioni non dovrebbero essere disponibili dal mio script. Poiché le estensioni sono una funzionalità così nuova, anche Google restituisce risultati rilevanti limitati e la maggior parte di questi proviene dalla documentazione ufficiale.

Cosa mi manca?

Grazie.

UPDATE quindi spero che la documentazione è incompleta perché è borderline abissale, ma ho imparato un po 'preoccupare delle impostazioni. Si scopre che, dagli script di iniezione, l'oggetto SafariExtensionSettings non è disponibile. Gli script di iniezione hanno accesso solo all'oggetto SafariContentExtension (che non è affatto utile), ma è aliasato esattamente nello stesso modo (safari.extension.settings) - cattiva idea, IMO. Come indicato nel injection script documentation:

Importante: Quando si utilizza safari.extension dall'interno di uno script iniettato, non si sta affrontando la classe SafariExtension. Stai indirizzando la classe SafariContentExtension.

È necessario utilizzare il sistema di messaggistica per parlare con un file HTML globale che ha accesso alle impostazioni. È un po 'complicato, ma ho un messaggio che viene inviato a un file global.html che recupera le impostazioni e invierà un messaggio al mio script di iniezione non appena ho capito come fare per farlo.

Poiché eseguo tutto il mio lavoro prima che il documento venga caricato, tutti i metodi che ho trovato per inviare il messaggio indietro a si basano su un oggetto di pagina che non ho.

risposta

2

Mi ci sono voluti diversi giorni, ma credo di aver trovato una soluzione praticabile utilizzando il metodo canLoad() messaggistica. Il mio script iniezione recupera impostazioni chiamando la pagina HTML globale come questo:

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

Il mio file HTML globale, a sua volta, restituisce le impostazioni come:

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

msgEvent.message = settings; 

E 'ancora un po' di più "hacky" di Mi piacerebbe. Non riesco a restituire semplicemente l'oggetto delle impostazioni stesso, quindi devo compilare un nuovo oggetto recuperando ogni impostazione manualmente. Non ideale, ma sembra essere efficace.

3

EDIT: come hai detto nel tuo post iniziale di aggiornamento, lo script iniettato non ha lo stesso tipo di accesso che una pagina HTML globale avrebbe. Questa è la mia soluzione di lavoro, immaginare che si desidera conoscere il valore di impostazione "pippo" nello script iniettato:

codice di script iniettato:

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 

codice HTML globale:

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

Speranza questo aiuta !


post iniziale: Sto avendo lo stesso secondo problema come voi, io non è possibile accedere le mie impostazioni (o secureSettings) da uno script iniettato. Nel mio caso lo script viene caricato dopo il caricamento della pagina, ma anche in questo modo non posso usare safari.extension.settings.

L'unico modo in cui funziona è con una barra degli strumenti/pulsante, l'HTML dietro quell'elemento può getItem e setItem come previsto.

La mia conclusione è che, per qualche motivo, gli script iniettati non possono accedere alle impostazioni (in realtà, sembra che non abbiano nemmeno accesso all'elemento safari). Bug o funzione prevista, che resta da capire.

+0

Dai un'occhiata agli aggiornamenti che ho aggiunto sopra. Ora so che _per_ non puoi accedere alle impostazioni e hai persino indicato come raggiungerle (anche se non funziona per me per altri motivi). –

+0

Ho appena trovato una soluzione per il mio problema, è pubblicato sopra per voi o per chiunque altro con lo stesso problema. Forse puoi adattarlo per il tuo caso! – Mars

+0

Grazie per l'aggiornamento. Nel mio caso, tutto il lavoro viene eseguito 'beforeload', quindi l'oggetto della pagina non è definito, il che sembra significare che il metodo' dispatchMessage() 'non è disponibile. Sto ancora cercando una soluzione alternativa. –

6

Come tutti gli altri, a questo punto, sto ancora salire la curva di apprendimento, ma ecco come ho gestito questo problema:

Ho un semplice estensione senza cromo e uno script di fine iniezione (script. js). Ai fini del caricamento delle impostazioni ho aggiunto una semplice pagina globale (proxy.html). Quando viene iniettato script.js, invia un messaggio getSettings a proxy.html. proxy.html risponde con un messaggio setSettings e script.js continua l'inizializzazione.

La pagina più utile che ho trovato nella documentazione su questo argomento è 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, sei un vero toccasana! Grazie mille per questo. –

1

esecuzione nello stesso problema, ma la risposta è più facile di quanto si possa immaginare: comprendono lo script nel tuo html globale.

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

quindi è possibile accedere alle impostazioni come descritto nella documentazione safari.extension.settings.myKey

si può anche upvote @Travis, perché ho avuto l'idea da his post

// EDIT:
realtà I don' so davvero cosa c'è di sbagliato. Chiamare le impostazioni come primo comando funziona, ma non in un secondo momento. Inoltre sembra corrompere il mio copione completo dopo l'iniezione 2.. Hai bisogno di verifica se è solo nella mia (difficile?) Sceneggiatura.

// EDIT2:
ora ho preso a lavorare per tornare alle impostazioni oggetto tramite dispatchMessage()

nel vostro 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"); 

e in global.html

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

basandosi su this documentazione apple