mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 11:27:58 +01:00
Add a storage module to persistently store, and share between windows, quickmarks, command/search history, and option values.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
# Firefox
|
# Firefox
|
||||||
content vimperator content/
|
content vimperator content/
|
||||||
locale vimperator en-US locale/en-US/
|
resource vimperator content/
|
||||||
|
locale vimperator en-US locale/en-US/
|
||||||
skin vimperator classic/1.0 skin/
|
skin vimperator classic/1.0 skin/
|
||||||
overlay chrome://browser/content/browser.xul chrome://vimperator/content/vimperator.xul
|
overlay chrome://browser/content/browser.xul chrome://vimperator/content/vimperator.xul
|
||||||
|
|||||||
@@ -790,15 +790,8 @@ liberator.QuickMarks = function () //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
var qmarks = {};
|
liberator.storage.newObject("quickmarks", true);
|
||||||
// TODO: move to a storage module
|
var qmarks = liberator.storage.quickmarks;
|
||||||
var savedMarks = liberator.options.getPref("extensions.vimperator.quickmarks", "").split("\n");
|
|
||||||
|
|
||||||
// load the saved quickmarks
|
|
||||||
for (var i = 0; i < savedMarks.length - 1; i += 2)
|
|
||||||
{
|
|
||||||
qmarks[savedMarks[i]] = savedMarks[i + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// MAPPINGS ////////////////////////////////////////////////
|
////////////////////// MAPPINGS ////////////////////////////////////////////////
|
||||||
@@ -899,28 +892,28 @@ liberator.QuickMarks = function () //{{{
|
|||||||
|
|
||||||
add: function (qmark, location)
|
add: function (qmark, location)
|
||||||
{
|
{
|
||||||
qmarks[qmark] = location;
|
qmarks.set(qmark, location);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function (filter)
|
remove: function (filter)
|
||||||
{
|
{
|
||||||
var pattern = new RegExp("[" + filter.replace(/\s+/g, "") + "]");
|
var pattern = new RegExp("[" + filter.replace(/\s+/g, "") + "]");
|
||||||
|
|
||||||
for (var qmark in qmarks)
|
for (var [qmark,] in qmarks)
|
||||||
{
|
{
|
||||||
if (pattern.test(qmark))
|
if (pattern.test(qmark))
|
||||||
delete qmarks[qmark];
|
qmarks.remove(qmark);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeAll: function ()
|
removeAll: function ()
|
||||||
{
|
{
|
||||||
qmarks = {};
|
qmarks.clear();
|
||||||
},
|
},
|
||||||
|
|
||||||
jumpTo: function (qmark, where)
|
jumpTo: function (qmark, where)
|
||||||
{
|
{
|
||||||
var url = qmarks[qmark];
|
var url = qmarks.get(qmark);
|
||||||
|
|
||||||
if (url)
|
if (url)
|
||||||
liberator.open(url, where);
|
liberator.open(url, where);
|
||||||
@@ -934,7 +927,7 @@ liberator.QuickMarks = function () //{{{
|
|||||||
var uppercaseMarks = [];
|
var uppercaseMarks = [];
|
||||||
var numberMarks = [];
|
var numberMarks = [];
|
||||||
|
|
||||||
for (var qmark in qmarks)
|
for (var [qmark,] in qmarks)
|
||||||
{
|
{
|
||||||
if (/[a-z]/.test(qmark))
|
if (/[a-z]/.test(qmark))
|
||||||
lowercaseMarks.push(qmark);
|
lowercaseMarks.push(qmark);
|
||||||
@@ -972,28 +965,13 @@ liberator.QuickMarks = function () //{{{
|
|||||||
for (var i = 0; i < marks.length; i++)
|
for (var i = 0; i < marks.length; i++)
|
||||||
{
|
{
|
||||||
list += "<tr><td> " + marks[i] +
|
list += "<tr><td> " + marks[i] +
|
||||||
"</td><td style=\"color: green;\">" + liberator.util.escapeHTML(qmarks[marks[i]]) + "</td></tr>";
|
"</td><td style=\"color: green;\">" + liberator.util.escapeHTML(qmarks.get(marks[i])) + "</td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
list += "</table>";
|
list += "</table>";
|
||||||
|
|
||||||
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function ()
|
|
||||||
{
|
|
||||||
// save the quickmarks
|
|
||||||
var savedQuickMarks = "";
|
|
||||||
|
|
||||||
for (var i in qmarks)
|
|
||||||
{
|
|
||||||
savedQuickMarks += i + "\n";
|
|
||||||
savedQuickMarks += qmarks[i] + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
liberator.options.setPref("extensions.vimperator.quickmarks", savedQuickMarks);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
//}}}
|
//}}}
|
||||||
}; //}}}
|
}; //}}}
|
||||||
|
|||||||
@@ -1095,12 +1095,11 @@ const liberator = (function () //{{{
|
|||||||
{
|
{
|
||||||
liberator.autocommands.trigger(liberator.config.name + "LeavePre", "");
|
liberator.autocommands.trigger(liberator.config.name + "LeavePre", "");
|
||||||
|
|
||||||
|
liberator.storage.saveAll();
|
||||||
|
|
||||||
// save our preferences
|
// save our preferences
|
||||||
liberator.commandline.destroy();
|
|
||||||
liberator.options.destroy();
|
liberator.options.destroy();
|
||||||
liberator.events.destroy();
|
liberator.events.destroy();
|
||||||
if (liberator.has("quickmarks"))
|
|
||||||
liberator.quickmarks.destroy();
|
|
||||||
if (liberator.has("bookmarks"))
|
if (liberator.has("bookmarks"))
|
||||||
liberator.bookmarks.destroy();
|
liberator.bookmarks.destroy();
|
||||||
|
|
||||||
@@ -1167,6 +1166,8 @@ const liberator = (function () //{{{
|
|||||||
//}}}
|
//}}}
|
||||||
})(); //}}}
|
})(); //}}}
|
||||||
|
|
||||||
|
Components.utils.import("resource://vimperator/storage.jsi", liberator);
|
||||||
|
|
||||||
// called when the chrome is fully loaded and before the main window is shown
|
// called when the chrome is fully loaded and before the main window is shown
|
||||||
window.addEventListener("load", liberator.startup, false);
|
window.addEventListener("load", liberator.startup, false);
|
||||||
window.addEventListener("unload", liberator.shutdown, false);
|
window.addEventListener("unload", liberator.shutdown, false);
|
||||||
|
|||||||
@@ -36,17 +36,17 @@ liberator.Option = function (names, description, type, defaultValue, extraInfo)
|
|||||||
if (!extraInfo)
|
if (!extraInfo)
|
||||||
extraInfo = {};
|
extraInfo = {};
|
||||||
|
|
||||||
var value = null;
|
let cannonName = names[0];
|
||||||
|
this.name = cannonName;
|
||||||
this.name = names[0];
|
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.scope = (extraInfo.scope & liberator.options.OPTION_SCOPE_BOTH) || liberator.options.OPTION_SCOPE_GLOBAL; // XXX set to BOTH by default someday? - kstep
|
this.scope = (extraInfo.scope & liberator.options.OPTION_SCOPE_BOTH) ||
|
||||||
|
liberator.options.OPTION_SCOPE_GLOBAL;
|
||||||
|
// XXX set to BOTH by default someday? - kstep
|
||||||
this.description = description || "";
|
this.description = description || "";
|
||||||
|
|
||||||
// "", 0 are valid default values
|
// "", 0 are valid default values
|
||||||
this.defaultValue = (defaultValue === undefined) ? null : defaultValue;
|
this.defaultValue = (defaultValue === undefined) ? null : defaultValue;
|
||||||
value = this.defaultValue;
|
|
||||||
|
|
||||||
this.setter = extraInfo.setter || null;
|
this.setter = extraInfo.setter || null;
|
||||||
this.getter = extraInfo.getter || null;
|
this.getter = extraInfo.getter || null;
|
||||||
@@ -68,6 +68,10 @@ liberator.Option = function (names, description, type, defaultValue, extraInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.__defineGetter__("globalvalue", function() liberator.options.store.get(cannonName));
|
||||||
|
this.__defineSetter__("globalvalue", function(val) liberator.options.store.set(cannonName, val));
|
||||||
|
this.globalvalue = this.defaultValue;
|
||||||
|
|
||||||
this.get = function (scope)
|
this.get = function (scope)
|
||||||
{
|
{
|
||||||
if (scope)
|
if (scope)
|
||||||
@@ -85,7 +89,7 @@ liberator.Option = function (names, description, type, defaultValue, extraInfo)
|
|||||||
if (liberator.has("tabs") && (scope & liberator.options.OPTION_SCOPE_LOCAL))
|
if (liberator.has("tabs") && (scope & liberator.options.OPTION_SCOPE_LOCAL))
|
||||||
aValue = liberator.tabs.options[this.name];
|
aValue = liberator.tabs.options[this.name];
|
||||||
if ((scope & liberator.options.OPTION_SCOPE_GLOBAL) && (aValue == undefined))
|
if ((scope & liberator.options.OPTION_SCOPE_GLOBAL) && (aValue == undefined))
|
||||||
aValue = value;
|
aValue = this.globalvalue;
|
||||||
|
|
||||||
if (this.getter)
|
if (this.getter)
|
||||||
this.getter.call(this, aValue);
|
this.getter.call(this, aValue);
|
||||||
@@ -120,7 +124,7 @@ liberator.Option = function (names, description, type, defaultValue, extraInfo)
|
|||||||
if (liberator.has("tabs") && (scope & liberator.options.OPTION_SCOPE_LOCAL))
|
if (liberator.has("tabs") && (scope & liberator.options.OPTION_SCOPE_LOCAL))
|
||||||
liberator.tabs.options[this.name] = newValue;
|
liberator.tabs.options[this.name] = newValue;
|
||||||
if (scope & liberator.options.OPTION_SCOPE_GLOBAL)
|
if (scope & liberator.options.OPTION_SCOPE_GLOBAL)
|
||||||
value = newValue;
|
this.globalvalue = newValue;
|
||||||
|
|
||||||
this.hasChanged = true;
|
this.hasChanged = true;
|
||||||
};
|
};
|
||||||
@@ -131,7 +135,7 @@ liberator.Option = function (names, description, type, defaultValue, extraInfo)
|
|||||||
|
|
||||||
this.hasName = function (name)
|
this.hasName = function (name)
|
||||||
{
|
{
|
||||||
return this.names.some(function (e) { return e == name; });
|
return this.names.indexOf(name) >= 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isValidValue = function (value)
|
this.isValidValue = function (value)
|
||||||
@@ -155,6 +159,8 @@ liberator.Options = function () //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
liberator.storage.newObject("options", false);
|
||||||
|
|
||||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||||
.getService(Components.interfaces.nsIPrefBranch);
|
.getService(Components.interfaces.nsIPrefBranch);
|
||||||
var options = [];
|
var options = [];
|
||||||
@@ -768,8 +774,6 @@ liberator.Options = function () //{{{
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < options.length; i++)
|
for (var i = 0; i < options.length; i++)
|
||||||
yield options[i];
|
yield options[i];
|
||||||
|
|
||||||
throw StopIteration;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
add: function (names, description, type, defaultValue, extraInfo)
|
add: function (names, description, type, defaultValue, extraInfo)
|
||||||
@@ -782,9 +786,9 @@ liberator.Options = function () //{{{
|
|||||||
if (!option)
|
if (!option)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (var i = 0; i < options.length; i++)
|
for (var opt in Iterator(this))
|
||||||
{
|
{
|
||||||
if (options[i].name == option.name)
|
if (opt.name == option.name)
|
||||||
{
|
{
|
||||||
// never replace for now
|
// never replace for now
|
||||||
liberator.log("Warning: '" + names[0] + "' already exists, NOT replacing existing option.", 1);
|
liberator.log("Warning: '" + names[0] + "' already exists, NOT replacing existing option.", 1);
|
||||||
@@ -832,19 +836,19 @@ liberator.Options = function () //{{{
|
|||||||
if (!scope)
|
if (!scope)
|
||||||
scope = liberator.options.OPTION_SCOPE_BOTH;
|
scope = liberator.options.OPTION_SCOPE_BOTH;
|
||||||
|
|
||||||
for (var i = 0; i < options.length; i++)
|
for (var opt in Iterator(this))
|
||||||
{
|
{
|
||||||
name = options[i].name;
|
name = opt.name;
|
||||||
value = options[i].value;
|
value = opt.value;
|
||||||
def = options[i].defaultValue;
|
def = opt.defaultValue;
|
||||||
|
|
||||||
if (onlyNonDefault && value == def)
|
if (onlyNonDefault && value == def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(options[i].scope & scope))
|
if (!(opt.scope & scope))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (options[i].type == "boolean")
|
if (opt.type == "boolean")
|
||||||
{
|
{
|
||||||
name = value ? " " + name : "no" + name;
|
name = value ? " " + name : "no" + name;
|
||||||
if (value != def)
|
if (value != def)
|
||||||
@@ -882,12 +886,12 @@ liberator.Options = function () //{{{
|
|||||||
" Options ---</th></tr>";
|
" Options ---</th></tr>";
|
||||||
var name, value, defaultValue;
|
var name, value, defaultValue;
|
||||||
|
|
||||||
for (var i = 0; i < prefArray.length; i++)
|
prefArray.forEach(function (pref)
|
||||||
{
|
{
|
||||||
var userValue = prefService.prefHasUserValue(prefArray[i]);
|
var userValue = prefService.prefHasUserValue(pref);
|
||||||
if ((!onlyNonDefault || userValue) && prefArray[i].indexOf(filter) >= 0)
|
if ((!onlyNonDefault || userValue) && pref.indexOf(filter) >= 0)
|
||||||
{
|
{
|
||||||
name = prefArray[i];
|
name = pref;
|
||||||
value = this.getPref(name);
|
value = this.getPref(name);
|
||||||
if (typeof value == "string")
|
if (typeof value == "string")
|
||||||
value = value.substr(0, 100).replace(/\n/g, " ");
|
value = value.substr(0, 100).replace(/\n/g, " ");
|
||||||
@@ -907,11 +911,13 @@ liberator.Options = function () //{{{
|
|||||||
else
|
else
|
||||||
list += "<tr><td> " + name + "=" + value + "</td></tr>";
|
list += "<tr><td> " + name + "=" + value + "</td></tr>";
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
list += "</table>";
|
list += "</table>";
|
||||||
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get store() liberator.storage.options,
|
||||||
|
|
||||||
getPref: function (name, forcedDefault)
|
getPref: function (name, forcedDefault)
|
||||||
{
|
{
|
||||||
return loadPreference(name, forcedDefault);
|
return loadPreference(name, forcedDefault);
|
||||||
|
|||||||
236
content/storage.jsi
Normal file
236
content/storage.jsi
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||||
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
|
||||||
|
The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
http://www.mozilla.org/MPL/
|
||||||
|
|
||||||
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
for the specific language governing rights and limitations under the
|
||||||
|
License.
|
||||||
|
|
||||||
|
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of the MPL, indicate your
|
||||||
|
decision by deleting the provisions above and replace them with the notice
|
||||||
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
}}} ***** END LICENSE BLOCK *****/
|
||||||
|
|
||||||
|
var EXPORTED_SYMBOLS = ["storage"];
|
||||||
|
|
||||||
|
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIPrefBranch);
|
||||||
|
var json = Components.classes["@mozilla.org/dom/json;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIJSON);
|
||||||
|
|
||||||
|
function getCharPref(name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var value = prefService.getComplexValue(name, Components.interfaces.nsISupportsString).data;
|
||||||
|
// try in case it's a localized string (will throw an exception if not)
|
||||||
|
if (!prefService.prefIsLocked(name) && !prefService.prefHasUserValue(name) &&
|
||||||
|
/^chrome:\/\/.+\/locale\/.+\.properties/.test(value))
|
||||||
|
value = branch.getComplexValue(name, Components.interfaces.nsIPrefLocalizedString).data;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefName(key) {
|
||||||
|
return "extensions.liberator.datastore." + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPref(name, store, type)
|
||||||
|
{
|
||||||
|
if (store)
|
||||||
|
var pref = getCharPref(prefName(name));
|
||||||
|
if (pref)
|
||||||
|
var obj = json.decode(pref);
|
||||||
|
if (obj instanceof type)
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
var prototype = {
|
||||||
|
fireEvent: function(event, arg) { storage.fireEvent(this.name, event, arg) },
|
||||||
|
save: function()
|
||||||
|
{
|
||||||
|
if(this.store)
|
||||||
|
prefService.setCharPref(prefName(this.name), this.serial)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function ObjectStore(name, store)
|
||||||
|
{
|
||||||
|
var object = loadPref(name, store, Object) || {};
|
||||||
|
|
||||||
|
this.__defineGetter__("store", function() store);
|
||||||
|
this.__defineGetter__("name", function() name);
|
||||||
|
this.__defineGetter__("serial", function() json.encode(object));
|
||||||
|
|
||||||
|
this.set = function set(key, val)
|
||||||
|
{
|
||||||
|
var orig = object[key];
|
||||||
|
object[key] = val;
|
||||||
|
if (orig == val)
|
||||||
|
this.fireEvent("change", key);
|
||||||
|
else
|
||||||
|
this.fireEvent("add", key);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function remove(key)
|
||||||
|
{
|
||||||
|
var ret = object[key];
|
||||||
|
delete object[key];
|
||||||
|
this.fireEvent("remove", key);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.get = function get(val) object[val];
|
||||||
|
|
||||||
|
this.clear = function()
|
||||||
|
{
|
||||||
|
object = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.__iterator__ = function() {
|
||||||
|
for (let key in object)
|
||||||
|
yield [key, object[key]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ObjectStore.prototype = prototype;
|
||||||
|
|
||||||
|
function ArrayStore(name, store)
|
||||||
|
{
|
||||||
|
var array = loadPref(name, store, Array) || {};
|
||||||
|
|
||||||
|
this.__defineGetter__("store", function() store);
|
||||||
|
this.__defineGetter__("name", function() name);
|
||||||
|
this.__defineGetter__("serial", function() json.encode(array));
|
||||||
|
this.__defineGetter__("length", function() array.length);
|
||||||
|
|
||||||
|
this.set = function set(index, value)
|
||||||
|
{
|
||||||
|
var orig = array[index];
|
||||||
|
array[index] = value;
|
||||||
|
this.fireEvent("change", index);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.push = function push(value)
|
||||||
|
{
|
||||||
|
array.push(value);
|
||||||
|
this.fireEvent("push", array.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pop = function pop(value)
|
||||||
|
{
|
||||||
|
var ret = array.pop();
|
||||||
|
this.fireEvent("pop", array.length);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.truncate = function truncate(length, fromEnd)
|
||||||
|
{
|
||||||
|
var ret = array.length;
|
||||||
|
if (array.length > length)
|
||||||
|
{
|
||||||
|
if(fromEnd)
|
||||||
|
array.splice(0, array.length - length);
|
||||||
|
array.length = length;
|
||||||
|
}
|
||||||
|
this.fireEvent("truncate", length);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXX: Awkward.
|
||||||
|
this.mutate = function mutate(aFuncName)
|
||||||
|
{
|
||||||
|
var funcName = aFuncName;
|
||||||
|
arguments[0] = array;
|
||||||
|
array = Array[funcName].apply(Array, arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
this.get = function get(index)
|
||||||
|
{
|
||||||
|
return index >= 0 ? array[index] : array[array.length + index];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.__iterator__ = function() {
|
||||||
|
for(let i = 0; i < array.length; i++)
|
||||||
|
yield [i, array[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArrayStore.prototype = prototype;
|
||||||
|
|
||||||
|
var keys = {};
|
||||||
|
var observers = {};
|
||||||
|
|
||||||
|
var storage = {
|
||||||
|
_addKey: function addKey(key, val)
|
||||||
|
{
|
||||||
|
if(key in this)
|
||||||
|
throw Error; // TODO: Find a better error.
|
||||||
|
keys[key] = val;
|
||||||
|
this.__defineGetter__(key, function() keys[key]);
|
||||||
|
},
|
||||||
|
|
||||||
|
newObject: function newObject(key, store)
|
||||||
|
{
|
||||||
|
// TODO: Add type checking.
|
||||||
|
if(key in keys)
|
||||||
|
return;
|
||||||
|
this._addKey(key, new ObjectStore(key, store));
|
||||||
|
},
|
||||||
|
|
||||||
|
newArray: function newArray(key, store)
|
||||||
|
{
|
||||||
|
// TODO: Add type checking.
|
||||||
|
if(key in keys)
|
||||||
|
return;
|
||||||
|
this._addKey(key, new ArrayStore(key, store));
|
||||||
|
},
|
||||||
|
|
||||||
|
addObserver: function addObserver(key, callback)
|
||||||
|
{
|
||||||
|
if(!(key in observers))
|
||||||
|
observers[key] = [];
|
||||||
|
if(observers[key].indexOf(key) >= 0)
|
||||||
|
return;
|
||||||
|
observers[key].push(callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeObserver: function(key, callback)
|
||||||
|
{
|
||||||
|
if(!(key in observers))
|
||||||
|
return;
|
||||||
|
observers[key] = observers[key].filter(function(elem) elem != callback);
|
||||||
|
if(obsevers[key].length == 0)
|
||||||
|
delete obsevers[key];
|
||||||
|
},
|
||||||
|
|
||||||
|
fireEvent: function fireEvent(key, event, arg)
|
||||||
|
{
|
||||||
|
for each(callback in observers[key])
|
||||||
|
callback(key, event, arg);
|
||||||
|
},
|
||||||
|
|
||||||
|
saveAll: function storeAll() {
|
||||||
|
for each(key in keys)
|
||||||
|
key.store();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// vim: set fdm=marker sw=4 sts=4 et ft=javascript:
|
||||||
@@ -43,53 +43,29 @@ liberator.CommandLine = function () //{{{
|
|||||||
var completionlist = new liberator.InformationList("liberator-completion", { minItems: 1, maxItems: 10 });
|
var completionlist = new liberator.InformationList("liberator-completion", { minItems: 1, maxItems: 10 });
|
||||||
var completions = [];
|
var completions = [];
|
||||||
|
|
||||||
|
liberator.storage.newArray("history-search", true);
|
||||||
|
liberator.storage.newArray("history-command", true);
|
||||||
|
|
||||||
// TODO: clean this up when it's not 3am...
|
// TODO: clean this up when it's not 3am...
|
||||||
var history = {
|
var history = {
|
||||||
get size() { return liberator.options["history"]; },
|
get mode() (liberator.modes.extended == liberator.modes.EX) ? "command" : "search",
|
||||||
|
|
||||||
get mode() { return (liberator.modes.extended == liberator.modes.EX) ? "cmd" : "search"; },
|
get store() liberator.storage["history-" + this.mode],
|
||||||
|
|
||||||
cmd: null, // ex command history
|
get length() this.store.length,
|
||||||
|
|
||||||
search: null, // text search history
|
get: function(index) this.store.get(index),
|
||||||
|
|
||||||
get: function () { return this[this.mode]; },
|
|
||||||
|
|
||||||
set: function (lines) { this[this.mode] = lines; },
|
|
||||||
|
|
||||||
load: function ()
|
|
||||||
{
|
|
||||||
// TODO: move to storage module
|
|
||||||
this.cmd = liberator.options.getPref("extensions.vimperator.commandline_cmd_history", "").split("\n");
|
|
||||||
this.search = liberator.options.getPref("extensions.vimperator.commandline_search_history", "").split("\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
save: function ()
|
|
||||||
{
|
|
||||||
liberator.options.setPref("extensions.vimperator.commandline_cmd_history", this.cmd.join("\n"));
|
|
||||||
liberator.options.setPref("extensions.vimperator.commandline_search_history", this.search.join("\n"));
|
|
||||||
},
|
|
||||||
|
|
||||||
add: function (str)
|
add: function (str)
|
||||||
{
|
{
|
||||||
if (!str)
|
if (!str)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var lines = this.get();
|
this.store.mutate('filter', function(line) line != str);
|
||||||
|
this.store.push(str);
|
||||||
// remove all old history lines which have this string
|
this.store.truncate(liberator.options["history"], true);
|
||||||
lines = lines.filter(function (line) {
|
|
||||||
return line != str;
|
|
||||||
});
|
|
||||||
|
|
||||||
// add string to the command line history
|
|
||||||
if (lines.push(str) > this.size) // remove the first 10% of the history
|
|
||||||
lines = lines.slice(this.size / 10);
|
|
||||||
|
|
||||||
this.set(lines);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
history.load();
|
|
||||||
|
|
||||||
var historyIndex = UNINITIALIZED;
|
var historyIndex = UNINITIALIZED;
|
||||||
var historyStart = "";
|
var historyStart = "";
|
||||||
@@ -643,8 +619,6 @@ liberator.CommandLine = function () //{{{
|
|||||||
// user pressed UP or DOWN arrow to cycle history completion
|
// user pressed UP or DOWN arrow to cycle history completion
|
||||||
else if (key == "<Up>" || key == "<Down>")
|
else if (key == "<Up>" || key == "<Down>")
|
||||||
{
|
{
|
||||||
var lines = history.get();
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
@@ -654,18 +628,18 @@ liberator.CommandLine = function () //{{{
|
|||||||
// save 'start' position for iterating through the history
|
// save 'start' position for iterating through the history
|
||||||
if (historyIndex == UNINITIALIZED)
|
if (historyIndex == UNINITIALIZED)
|
||||||
{
|
{
|
||||||
historyIndex = lines.length;
|
historyIndex = history.length;
|
||||||
historyStart = command;
|
historyStart = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
// search the history for the first item matching the current
|
// search the history for the first item matching the current
|
||||||
// commandline string
|
// commandline string
|
||||||
while (historyIndex >= -1 && historyIndex <= lines.length)
|
while (historyIndex >= -1 && historyIndex <= history.length)
|
||||||
{
|
{
|
||||||
key == "<Up>" ? historyIndex-- : historyIndex++;
|
key == "<Up>" ? historyIndex-- : historyIndex++;
|
||||||
|
|
||||||
// user pressed DOWN when there is no newer history item
|
// user pressed DOWN when there is no newer history item
|
||||||
if (historyIndex == lines.length)
|
if (historyIndex == history.length)
|
||||||
{
|
{
|
||||||
setCommand(historyStart);
|
setCommand(historyStart);
|
||||||
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
||||||
@@ -679,16 +653,16 @@ liberator.CommandLine = function () //{{{
|
|||||||
liberator.beep();
|
liberator.beep();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (historyIndex >= lines.length + 1)
|
else if (historyIndex >= history.length + 1)
|
||||||
{
|
{
|
||||||
historyIndex = lines.length;
|
historyIndex = history.length;
|
||||||
liberator.beep();
|
liberator.beep();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lines[historyIndex].indexOf(historyStart) == 0)
|
if (history.get(historyIndex).indexOf(historyStart) == 0)
|
||||||
{
|
{
|
||||||
setCommand(lines[historyIndex]);
|
setCommand(history.get(historyIndex));
|
||||||
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1094,13 +1068,6 @@ liberator.CommandLine = function () //{{{
|
|||||||
{
|
{
|
||||||
completionIndex = historyIndex = UNINITIALIZED;
|
completionIndex = historyIndex = UNINITIALIZED;
|
||||||
},
|
},
|
||||||
|
|
||||||
// it would be better if we had a destructor in javascript ...
|
|
||||||
destroy: function ()
|
|
||||||
{
|
|
||||||
history.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
//}}}
|
//}}}
|
||||||
}; //}}}
|
}; //}}}
|
||||||
|
|||||||
Reference in New Issue
Block a user