Storing JavaScript Objects
|
|
My scripts use many JavaScript objects that need storing between page reloads. For now I am storing each property in a different GreaseMonkey preference and then retrieve every property and assign it to the properties of the object I created. How could I store objects in a better way? I want to store the properties, but not the methods. My idea was to store everything in one preference in JSON format and then parse it and assign the properties to the a new object created (when retrieving the data) or to store data like "this.property1 = 1; this.property2 = 2;" and then use eval when loading the object. What is the right way to do this? |
|
|
did you tried to use gm_setvalue? |
|
|
According to the Wiki GreaseMonkey only stores Strings, Numbers or Booleans. So for storing Objects it's a DIY. |
|
|
How about using toSource() and eval()?
|
|
|
Perhaps you could write some sort of property-storage »class« from which each object creates an instance in its constructor.
This is a solution for objects you designed yourself (I was assuming this), and only if the properties are of basic types. |
|
|
set(obj)
get(obj)
|
|
|
Set all the properties into an object and use the toSource() method. |
|
|
Here are overridden and extended versions of GM_getValue and GM_setValue I have built to extend the built in functionality to store arrays, dates, functions and objects as well as the standard strings, booleans and integers: GM_getValue __GM_getValue = GM_getValue;
GM_getValue = function()
{
var bExtendedArguments = ((arguments.length == 1) && (typeof(arguments[0]) == "object"));
if (bExtendedArguments) { var oData = arguments[0]; } else
{
var oData = { name:arguments[0] };
if (arguments.length == 2) { oData.defaultValue = arguments[1]; }
}
oData.value = __GM_getValue(oData.name);
if (oData.value == undefined) return oData.defaultValue;
oData.actualType = typeof(oData.value);
if (oData.actualType == "string")
{
var bExtendedData = (oData.value.substr(0, 1) == "Ø");
if (bExtendedData)
{
var b = true;
var s = oData.value;
do
{
var s2 = s.substr(1, s.indexOf("Ø", 1)-1);
var a2 = s2.split("=");
if (a2.length == 2)
{
switch(a2[0])
{
case "type":
oData.actualType = a2[1];
break;
}
}
s = s.substr(s.indexOf("Ø", 1)+1, s.length);
}
while (s.substr(0, 1) == "Ø");
if (oData.type != "string") { oData.value = s; }
}
var bNumericData = (!isNaN(oData.value));
if (bNumericData)
{
oData.value = parseFloat(oData.value);
if (!bExtendedData) { oData.actualType = ((((oData.value % 1) == 0) && (oData.value > 2147483647)) ? "bignumber" : "number"); }
}
}
if (oData.type == undefined) { oData.type = oData.actualType; }
switch (oData.type)
{
case "array":
return oData.value.split("§");
break;
case "bignumber":
return parseInt(oData.value);
break;
case "date":
return new Date(parseInt(oData.value));
break;
case "function":
return eval(oData.value);
break;
case "object":
if ((oData.value.substr(0, 2) == "({") && (oData.value.substr(oData.value.length-2, 2) == "})"))
{
eval("oData.value = " + oData.value.substring(1, oData.value.length-1) + ";");
}
return oData.value;
break;
default:
return oData.value;
}
};
GM_setValue
__GM_setValue = GM_setValue;
GM_setValue = function()
{
var bExtendedArguments = ((arguments.length == 1) && (typeof(arguments[0]) == "object"));
if (bExtendedArguments) { var oData = arguments[0]; } else
{
var oData = { name:arguments[0], type:typeof(arguments[1]), value:arguments[1] };
switch(oData.type)
{
case "number":
if (((oData.value % 1) == 0) && (oData.value > 2147483647)) { oData.type = "bignumber"; }
break;
case "object":
var s = oData.value.constructor.toString();
if (s.indexOf("function Array()") == 0) { oData.type = "array"; }
if (s.indexOf("function Date()") == 0) { oData.type = "date"; }
break;
}
}
switch(oData.type)
{
case "array":
oData.value = "Øtype=arrayØ" + oData.value.join("§");
break;
case "bignumber":
oData.value = oData.value.toString();
break;
case "date":
oData.value = "Øtype=dateØ" + oData.value.getTime().toString();
break;
case "function":
oData.value = "Øtype=functionØ" + oData.value.toString();
break;
case "object":
oData.value = "Øtype=objectØ" + oData.value.toSource();
break;
}
__GM_setValue(oData.name, oData.value);
};
Usage Examples:
// Simple Synyax
var arrayTestS1 = ["hello", "world"];
var bigNumberTestS1 = new Date().getTime();
var dateTestS1 = new Date();
var functionTestS1 = function() { return("hello world"); };
var objectTestS1 = { value:"hello world" };
GM_setValue("arrayTestS", arrayTestS1);
GM_setValue("bigNumberTestS", bigNumberTestS1);
GM_setValue("dateTestS", dateTestS1);
GM_setValue("functionTestS", functionTestS1);
GM_setValue("objectTestS", objectTestS1);
var arrayTestS2 = GM_getValue("arrayTestS");
var bigNumberTestS2 = GM_getValue("bigNumberTestS");
var dateTestS2 = GM_getValue("dateTestS");
var functionTestS2 = GM_getValue("functionTestS");
var objectTestS2 = GM_getValue("objectTestS");
alert(arrayTestS2.join("\n"));
alert(bigNumberTestS2 + "\n" + (bigNumberTestS2-1));
alert(dateTestS2);
alert(functionTestS2());
alert(objectTestS2.value);
// Extended Syntax
var arrayTestE1 = ["hello", "world"];
var bigNumberTestE1 = new Date().getTime();
var dateTestE1 = new Date();
var functionTestE1 = function() { return("hello world"); };
var objectTestE1 = { value:"hello world" };
GM_setValue({ name:"arrayTestE", type:"array", value:arrayTestE1 });
GM_setValue({ name:"bigNumberTestE", type:"bignumber", value:bigNumberTestE1 });
GM_setValue({ name:"dateTestE", type:"date", value:dateTestE1 });
GM_setValue({ name:"functionTestE", type:"function", value:functionTestE1 });
GM_setValue({ name:"objectTestE", type:"object", value:objectTestE1 });
var arrayTestE2 = GM_getValue({ name:"arrayTestE", type:"array", defaultValue:[] });
var bigNumberTestE2 = GM_getValue({ name:"bigNumberTestE", type:"bigNumber", defaultValue:0 });
var dateTestE2 = GM_getValue({ name:"dateTestE", type:"date", defaultValue:new Date("01 Jan 1970") });
var functionTestE2 = GM_getValue({ name:"functionTestE", type:"function", defaultValue:function() { } });
var objectTestE2 = GM_getValue({ name:"objectTestE", type:"object", defaultValue:{} });
alert(arrayTestE2.join("\n"));
alert(bigNumberTestE2 + "\n" + (bigNumberTestE2-1));
alert(dateTestE2);
alert(functionTestE2());
alert(objectTestE2.value);
|
|
|
|
|
|
@Aquilax
|
|
|
@aquilax: very nice :) |
|
|
If people only read...How about using |
|
|
@dob: very nice :) im sorry :) you're right i didnt read it. |
|
|
No problem, we coulda just saved 10 posts or so :d |
|
|
Take a look at DOM:Storage that was introduced in Firefox 2.
I'm have been using the globalStorage object in FF2/GM for quite a while and it has been working fine for me. It's using a sqlite database (if I remember it right) for storing your data and I think that you can save up to 5 MB data/domain (access to data is controlled by host/domain). /A |
|
|
@crazysnailboy
Thanks |
|
|
toSource and eval works with »associative arrays«. |
