Skip to content

Commit

Permalink
Implementing GM_watchValue and GM_unwatchValue
Browse files Browse the repository at this point in the history
  • Loading branch information
supahgreg committed Sep 23, 2012
1 parent 241a764 commit 4d3e46e
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 6 deletions.
2 changes: 2 additions & 0 deletions extension/locale/de/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Bitte erst den bevorzugten Texteditor wählen
editor.useScratchpad= editor.useScratchpad=
editor.useScratchpad.no= editor.useScratchpad.no=
editor.useScratchpad.yes= editor.useScratchpad.yes=
error.api.badArguments=
error.api.clipboard.type=ist kein von GM_setClipboard unterstützter Typ. error.api.clipboard.type=ist kein von GM_setClipboard unterstützter Typ.
error.api.noResourceWithName=Keine Resource mit dem Namen error.api.noResourceWithName=Keine Resource mit dem Namen
error.api.noSecondArgValue=Zweites Argument nicht spezifiziert: Value error.api.noSecondArgValue=Zweites Argument nicht spezifiziert: Value
error.api.prefNotFound=
error.api.reqURL=Ungültige URL error.api.reqURL=Ungültige URL
error.api.reqURL.scheme=Verbotenes Schema (Protokoll) in URL error.api.reqURL.scheme=Verbotenes Schema (Protokoll) in URL
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/en-US/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Please choose your preferred text editor first
editor.useScratchpad=Do you want to use Scratchpad as your editor? editor.useScratchpad=Do you want to use Scratchpad as your editor?
editor.useScratchpad.no=No (I will pick my own) editor.useScratchpad.no=No (I will pick my own)
editor.useScratchpad.yes=Yes editor.useScratchpad.yes=Yes
error.api.badArguments=Invalid or insufficient arguments were passed to a GM_ function.
error.api.clipboard.type=is not a type that is supported by GM_setClipboard. error.api.clipboard.type=is not a type that is supported by GM_setClipboard.
error.api.noResourceWithName=No resource with name error.api.noResourceWithName=No resource with name
error.api.noSecondArgValue=Second argument not specified: Value error.api.noSecondArgValue=Second argument not specified: Value
error.api.prefNotFound=An invalid or non-existent preference name was passed to a GM_ function.
error.api.reqURL=Invalid URL error.api.reqURL=Invalid URL
error.api.reqURL.scheme=Disallowed scheme in URL error.api.reqURL.scheme=Disallowed scheme in URL
error.api.safeHTMLParser.url=The "URL" argument of GM_safeHTMLParser could not be parsed error.api.safeHTMLParser.url=The "URL" argument of GM_safeHTMLParser could not be parsed
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/es-ES/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Por favor, elija antes su editor de texto favorito
editor.useScratchpad=¿Desea usar Scratchpad como su editor? editor.useScratchpad=¿Desea usar Scratchpad como su editor?
editor.useScratchpad.no=No (yo seleccionaré el mío) editor.useScratchpad.no=No (yo seleccionaré el mío)
editor.useScratchpad.yes=Sí editor.useScratchpad.yes=Sí
error.api.badArguments=
error.api.clipboard.type=no es un tipo soportado por GM_setClipboard. error.api.clipboard.type=no es un tipo soportado por GM_setClipboard.
error.api.noResourceWithName=No hay recursos con ese nombre error.api.noResourceWithName=No hay recursos con ese nombre
error.api.noSecondArgValue=Segundo argumento no especificado: Valor error.api.noSecondArgValue=Segundo argumento no especificado: Valor
error.api.prefNotFound=
error.api.reqURL=URL no válido error.api.reqURL=URL no válido
error.api.reqURL.scheme=Esquema no permitido en URL error.api.reqURL.scheme=Esquema no permitido en URL
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/he/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=אנא בחר תחילה את עורך הטקסט המועדף ע
editor.useScratchpad=האם ברצונך להשתמש ב־Scratchpad כעורך הטקסט שלך? editor.useScratchpad=האם ברצונך להשתמש ב־Scratchpad כעורך הטקסט שלך?
editor.useScratchpad.no=לא (אני אבחר בעצמי) editor.useScratchpad.no=לא (אני אבחר בעצמי)
editor.useScratchpad.yes=כן editor.useScratchpad.yes=כן
error.api.badArguments=
error.api.clipboard.type=אינו מסוג שנתמך ע"י GM_setClipboard. error.api.clipboard.type=אינו מסוג שנתמך ע"י GM_setClipboard.
error.api.noResourceWithName=לא קיים משאב בעל שם error.api.noResourceWithName=לא קיים משאב בעל שם
error.api.noSecondArgValue=לא צוין ערך שני: ערך error.api.noSecondArgValue=לא צוין ערך שני: ערך
error.api.prefNotFound=
error.api.reqURL=כתובת URL לא חוקית error.api.reqURL=כתובת URL לא חוקית
error.api.reqURL.scheme=ערכה לא מורשת בכתובת URL error.api.reqURL.scheme=ערכה לא מורשת בכתובת URL
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/hu/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Kérem először válassza ki az Ön által preferált szerkesztő
editor.useScratchpad=A Scratchpad-et szeretné használni szerkesztőként? editor.useScratchpad=A Scratchpad-et szeretné használni szerkesztőként?
editor.useScratchpad.no=Nem (kiválasztok egy sajátot) editor.useScratchpad.no=Nem (kiválasztok egy sajátot)
editor.useScratchpad.yes=Igen editor.useScratchpad.yes=Igen
error.api.badArguments=
error.api.clipboard.type=a GM_setClipboard által nem támogatott típus. error.api.clipboard.type=a GM_setClipboard által nem támogatott típus.
error.api.noResourceWithName=Nincs erőforrás ezen a néven: error.api.noResourceWithName=Nincs erőforrás ezen a néven:
error.api.noSecondArgValue=Második argumentum nincs meghatározva: Érték error.api.noSecondArgValue=Második argumentum nincs meghatározva: Érték
error.api.prefNotFound=
error.api.reqURL=Érvénytelen URL error.api.reqURL=Érvénytelen URL
error.api.reqURL.scheme=Az URL formátuma érvénytelen error.api.reqURL.scheme=Az URL formátuma érvénytelen
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/ja-JP/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=エディタを選択してください
editor.useScratchpad=エディタとしてスクラッチパッドを使用しますか? editor.useScratchpad=エディタとしてスクラッチパッドを使用しますか?
editor.useScratchpad.no=No(自分でエディタを指定) editor.useScratchpad.no=No(自分でエディタを指定)
editor.useScratchpad.yes=Yes editor.useScratchpad.yes=Yes
error.api.badArguments=
error.api.clipboard.type=は GM_setClipboard がサポートしていない型(type)です error.api.clipboard.type=は GM_setClipboard がサポートしていない型(type)です
error.api.noResourceWithName=名前付きリソースが見つかりません error.api.noResourceWithName=名前付きリソースが見つかりません
error.api.noSecondArgValue=2番目の引数が指定されていません:Value error.api.noSecondArgValue=2番目の引数が指定されていません:Value
error.api.prefNotFound=
error.api.reqURL=不正な URL です error.api.reqURL=不正な URL です
error.api.reqURL.scheme=許可されていないスキーム(scheme)を URL で指定しています error.api.reqURL.scheme=許可されていないスキーム(scheme)を URL で指定しています
error.api.safeHTMLParser.url=GM_safeHTMLParser の引数 "URL" をパース(parse)できません error.api.safeHTMLParser.url=GM_safeHTMLParser の引数 "URL" をパース(parse)できません
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/pl/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Najpierw proszę wybrać swój preferowany edytor tekstu
editor.useScratchpad=Czy chcesz użyć Scratchpad-a jako edytor? editor.useScratchpad=Czy chcesz użyć Scratchpad-a jako edytor?
editor.useScratchpad.no=Nie ( sam wybiorę ) editor.useScratchpad.no=Nie ( sam wybiorę )
editor.useScratchpad.yes=Tak editor.useScratchpad.yes=Tak
error.api.badArguments=
error.api.clipboard.type=nie jest to typ wspierany przez GM_setClipboard. error.api.clipboard.type=nie jest to typ wspierany przez GM_setClipboard.
error.api.noResourceWithName=Brak źródeł z nazwą error.api.noResourceWithName=Brak źródeł z nazwą
error.api.noSecondArgValue=Drugi argument nie został określony: Wartość error.api.noSecondArgValue=Drugi argument nie został określony: Wartość
error.api.prefNotFound=
error.api.reqURL=Błędny URL error.api.reqURL=Błędny URL
error.api.reqURL.scheme=Niedozwolony schemat URL error.api.reqURL.scheme=Niedozwolony schemat URL
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/pt-BR/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Escolha seu editor de texto preferido
editor.useScratchpad=Você gostaria de usar o Scratchpad como seu editor? editor.useScratchpad=Você gostaria de usar o Scratchpad como seu editor?
editor.useScratchpad.no=Não (eu vou escolher outro) editor.useScratchpad.no=Não (eu vou escolher outro)
editor.useScratchpad.yes=Sim editor.useScratchpad.yes=Sim
error.api.badArguments=
error.api.clipboard.type=não é um tipo suportado por GM_setClipboard. error.api.clipboard.type=não é um tipo suportado por GM_setClipboard.
error.api.noResourceWithName=Nenhum recurso com o nome error.api.noResourceWithName=Nenhum recurso com o nome
error.api.noSecondArgValue=Segundo argumento não especificado: Valor error.api.noSecondArgValue=Segundo argumento não especificado: Valor
error.api.prefNotFound=
error.api.reqURL=Endereço inválido error.api.reqURL=Endereço inválido
error.api.reqURL.scheme=Esquema não permitido em URL error.api.reqURL.scheme=Esquema não permitido em URL
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/ru-RU/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Пожалуйста, выберите ваш любимый ре
editor.useScratchpad=Вы хотите использовать Scratchpad в качестве редактора? editor.useScratchpad=Вы хотите использовать Scratchpad в качестве редактора?
editor.useScratchpad.no=Нет (я выберу свой​​) editor.useScratchpad.no=Нет (я выберу свой​​)
editor.useScratchpad.yes=Да editor.useScratchpad.yes=Да
error.api.badArguments=
error.api.clipboard.type=Тип данных не подходит для GM_setClipboard. error.api.clipboard.type=Тип данных не подходит для GM_setClipboard.
error.api.noResourceWithName=Нет ресурса с таким именем error.api.noResourceWithName=Нет ресурса с таким именем
error.api.noSecondArgValue=Второй аргумент - значение - не задан error.api.noSecondArgValue=Второй аргумент - значение - не задан
error.api.prefNotFound=
error.api.reqURL=Неверный URL error.api.reqURL=Неверный URL
error.api.reqURL.scheme=Запрещённая схема в URL error.api.reqURL.scheme=Запрещённая схема в URL
error.api.safeHTMLParser.url=Не удалось разобрать аргумент «URL» из GM_safeHTMLParser error.api.safeHTMLParser.url=Не удалось разобрать аргумент «URL» из GM_safeHTMLParser
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/sv-SE/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=Var vänlig välj först det textredigeringsprogram du föredrar
editor.useScratchpad=Vill du använda Scratchpad som din textredigerare? editor.useScratchpad=Vill du använda Scratchpad som din textredigerare?
editor.useScratchpad.no=Nej, jag väljer min egen editor.useScratchpad.no=Nej, jag väljer min egen
editor.useScratchpad.yes=Ja editor.useScratchpad.yes=Ja
error.api.badArguments=
error.api.clipboard.type=är inte en typ som stöds av GM_setClipboard. error.api.clipboard.type=är inte en typ som stöds av GM_setClipboard.
error.api.noResourceWithName=Det finns ingen resurs med namnet error.api.noResourceWithName=Det finns ingen resurs med namnet
error.api.noSecondArgValue=Det andra argumentet har inte angivits: Värde error.api.noSecondArgValue=Det andra argumentet har inte angivits: Värde
error.api.prefNotFound=
error.api.reqURL=Ogiltig URL error.api.reqURL=Ogiltig URL
error.api.reqURL.scheme=Otillåtet schema i URL error.api.reqURL.scheme=Otillåtet schema i URL
error.api.safeHTMLParser.url=Argumentet "URL" för GM_safeHTMLParser kunde inte parsas error.api.safeHTMLParser.url=Argumentet "URL" för GM_safeHTMLParser kunde inte parsas
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/zh-CN/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=请选择您喜欢的文本编辑器
editor.useScratchpad=您想使用暂存器作为您的编辑器吗? editor.useScratchpad=您想使用暂存器作为您的编辑器吗?
editor.useScratchpad.no=不(我要选择我自己喜欢的) editor.useScratchpad.no=不(我要选择我自己喜欢的)
editor.useScratchpad.yes=是 editor.useScratchpad.yes=是
error.api.badArguments=
error.api.clipboard.type=不是 GM_setClipboard 所支持的类型。 error.api.clipboard.type=不是 GM_setClipboard 所支持的类型。
error.api.noResourceWithName=没有该名称的资源 error.api.noResourceWithName=没有该名称的资源
error.api.noSecondArgValue=第二个参数未指定:值 error.api.noSecondArgValue=第二个参数未指定:值
error.api.prefNotFound=
error.api.reqURL=无效的 URL error.api.reqURL=无效的 URL
error.api.reqURL.scheme=不允许在 URL 中出现 scheme error.api.reqURL.scheme=不允许在 URL 中出现 scheme
error.api.safeHTMLParser.url=无法解释 GM_safeHTMLParser 函数的中的 URL参数 error.api.safeHTMLParser.url=无法解释 GM_safeHTMLParser 函数的中的 URL参数
Expand Down
2 changes: 2 additions & 0 deletions extension/locale/zh-TW/scriptish.properties
Expand Up @@ -9,9 +9,11 @@ editor.prompt=請先選擇您常用的文字編輯器
editor.useScratchpad=您想使用程式碼片段速記本作為您的編輯器嗎? editor.useScratchpad=您想使用程式碼片段速記本作為您的編輯器嗎?
editor.useScratchpad.no=不(我要自己選擇) editor.useScratchpad.no=不(我要自己選擇)
editor.useScratchpad.yes=是 editor.useScratchpad.yes=是
error.api.badArguments=
error.api.clipboard.type=不是 GM_setClipboard 所支援的類型。 error.api.clipboard.type=不是 GM_setClipboard 所支援的類型。
error.api.noResourceWithName=沒有該名稱的資源 error.api.noResourceWithName=沒有該名稱的資源
error.api.noSecondArgValue=第二個參數未指定:值 error.api.noSecondArgValue=第二個參數未指定:值
error.api.prefNotFound=
error.api.reqURL=無效的網址 error.api.reqURL=無效的網址
error.api.reqURL.scheme=網址中有不支援的協定 error.api.reqURL.scheme=網址中有不支援的協定
error.api.safeHTMLParser.url= error.api.safeHTMLParser.url=
Expand Down
16 changes: 15 additions & 1 deletion extension/modules/api.js
Expand Up @@ -78,7 +78,7 @@ function GM_API(options) {
return new GM_xmlhttpRequester(aUnsafeContentWin, aURL, aScript); return new GM_xmlhttpRequester(aUnsafeContentWin, aURL, aScript);
}); });
lazy(lazyLoaders, "storage", function() { lazy(lazyLoaders, "storage", function() {
return new GM_ScriptStorage(aScript); return new GM_ScriptStorage(aScript, aSafeWin);
}); });
lazy(lazyLoaders, "resources", function() { lazy(lazyLoaders, "resources", function() {
return new GM_Resources(aScript); return new GM_Resources(aScript);
Expand Down Expand Up @@ -152,6 +152,20 @@ function GM_API(options) {
if (!GM_apiLeakCheck("GM_deleteValue")) return; if (!GM_apiLeakCheck("GM_deleteValue")) return;
return lazyLoaders.storage.deleteValue.apply(lazyLoaders.storage, arguments); return lazyLoaders.storage.deleteValue.apply(lazyLoaders.storage, arguments);
}; };
this.GM_watchValue = function GM_watchValue(aName, aListener) {
if (!GM_apiLeakCheck("GM_watchValue")) return;
let listener = null;
if ("function" === typeof aListener) {
listener = function(aEvent) {
GM_apiSafeCallback(aSafeWin, aScript, null, aListener, [aEvent]);
};
}
return lazyLoaders.storage.watchValue.call(lazyLoaders.storage, aName, listener);
}
this.GM_unwatchValue = function GM_unwatchValue() {
if (!GM_apiLeakCheck("GM_unwatchValue")) return;
return lazyLoaders.storage.unwatchValue.apply(lazyLoaders.storage, arguments);
}
this.GM_listValues = function GM_listValues() { this.GM_listValues = function GM_listValues() {
if (!GM_apiLeakCheck("GM_listValues")) return; if (!GM_apiLeakCheck("GM_listValues")) return;
return lazyLoaders.storage.listValues.apply(lazyLoaders.storage, arguments); return lazyLoaders.storage.listValues.apply(lazyLoaders.storage, arguments);
Expand Down
104 changes: 99 additions & 5 deletions extension/modules/api/GM_ScriptStorage.js
@@ -1,11 +1,26 @@
var EXPORTED_SYMBOLS = ["GM_ScriptStorage"]; var EXPORTED_SYMBOLS = ["GM_ScriptStorage"];


const Cu = Components.utils; Components.utils.import("resource://scriptish/constants.js");
Cu.import("resource://scriptish/prefmanager.js");
Cu.import("resource://scriptish/utils/Scriptish_stringBundle.js");


function GM_ScriptStorage(script) { lazyImport(this, "resource://scriptish/prefmanager.js", ["Scriptish_PrefManager"]);
this.prefMan = new Scriptish_PrefManager(script.prefroot);
lazyUtil(this, "getWindowIDs");
lazyUtil(this, "stringBundle");
lazyUtil(this, "windowUnloader");

function GM_ScriptStorage(aScript, aSafeWin) {
this.prefMan = new Scriptish_PrefManager(aScript.prefroot);
this._watchedPrefs = Object.create(null);

// Be sure to remove any watchers when the window unloads
let winID = Scriptish_getWindowIDs(aSafeWin).innerID;
Scriptish_windowUnloader(function() {
let prefChanged = this._prefChanged.bind(this);
for (let name in this._watchedPrefs) {
this.prefMan.unwatch(name, prefChanged);
delete this._watchedPrefs[name];
}
}.bind(this), winID);
} }


GM_ScriptStorage.prototype.setValue = function(name, val) { GM_ScriptStorage.prototype.setValue = function(name, val) {
Expand All @@ -24,6 +39,85 @@ GM_ScriptStorage.prototype.deleteValue = function(name) {
return this.prefMan.remove(name); return this.prefMan.remove(name);
}; };


// Notifies any script watchers of a preference change
GM_ScriptStorage.prototype._prefChanged = function(aName) {
if (!(aName in this._watchedPrefs)) {
return;
}
let newValue = this.getValue(aName);
let watchers = this._watchedPrefs[aName].watchers;
for (let i = 0, e = watchers.length; i < e; ++i) {
watchers[i].notify({
__exposedProps__: {
name: "r",
oldValue: "r",
newValue: "r"
},
"name": aName,
"oldValue": this._watchedPrefs[aName].currentValue,
"newValue": newValue
});
}
this._watchedPrefs[aName].currentValue = newValue;
}

GM_ScriptStorage.prototype.watchValue = function(aName, aListener) {
// Make sure we were passed everything
if (!(aName && aListener && "function" === typeof aListener)) {
throw new Error(Scriptish_stringBundle("error.api.badArguments"));
}

// Nothing to do if the preference doesn't exist
if (!this.prefMan.exists(aName)) {
throw new Error(Scriptish_stringBundle("error.api.prefNotFound"));
}

// Generate a UUID for the watcher so it can be unwatched by the user
let uuid = Services.uuid.generateUUID().toString();
let watcher = {"notify": aListener, "uuid": uuid};

// Add to existing watchers, or set up a new pref watcher
if (aName in this._watchedPrefs) {
this._watchedPrefs[aName].watchers.push(watcher);
}
else {
this._watchedPrefs[aName] = {
"currentValue": this.getValue(aName),
"watchers": [watcher]
};

// Start watching the pref
this.prefMan.watch(aName, this._prefChanged.bind(this));
}

// Return the watcher's UUID so it can be unwatched by the user
return uuid;
};

GM_ScriptStorage.prototype.unwatchValue = function(aName, aUUID) {
// Nothing to do if the preference doesn't exist or isn't watched
if (!(aName in this._watchedPrefs && this.prefMan.exists(aName))) {
return false;
}

let watchers = this._watchedPrefs[aName].watchers;

// If given a UUID, only remove the specified watcher
if (aUUID) {
for (let i = 0, e = watchers.length; i < e; ++i) {
if (aUUID === watchers[i].uuid) {
watchers.splice(i, 1);
return true;
}
}
return false;
}

// Otherwise remove all watchers for the preference
watchers.length = 0;
return true;
}

GM_ScriptStorage.prototype.listValues = function() { GM_ScriptStorage.prototype.listValues = function() {
return this.prefMan.listValues(); return this.prefMan.listValues();
}; };

0 comments on commit 4d3e46e

Please sign in to comment.