Detta skript bör inte installeras direkt. Det är ett bibliotek för andra skript att inkludera med meta-direktivet // @require https://update.greasyfork.org/scripts/29175/189868/Persist.js
// ==UserScript==
// @name Persist
// @namespace http://gm.wesley.eti.br
// @description Persist Function
// @author w35l3y
// @email w35l3y@brasnet.org
// @copyright 2013+, w35l3y (http://gm.wesley.eti.br)
// @license GNU GPL
// @homepage http://gm.wesley.eti.br
// @version 1.0.1.0
// @language en
// @include nowhere
// @exclude *
// @require https://greasyfork.org/scripts/29175-xpath/code/XPath.js?version=189855
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
/**************************************************************************
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
var Persist = function (s) {
var service = Persist.services[s];
this.request = function (obj) {
var k,
xthis = this,
params = function (def) {
var list = {};
this.add = function (vars) {
if (vars) {
if (typeof vars == "object") {
for (var k in vars) {
var e = vars[k];
if (typeof e == "object" && (!/^(?:radio|checkbox)$/i.test(e.type) || e.checked)) {
var n = e.name || k;
if (e.checked && /^checkbox$/i.test(e.type)) {
if (n in list) {
list[n].push(e.value);
} else {
list[n] = [e.value];
}
} else if ("value" in e) {
list[n] = e.value;
} else {
list[n] = e;
}
} else {
list[k] = e;
}
}
} else {
list = vars;
}
}
};
this.toString = function() {
if (typeof list == "object") {
var data = "";
for (var key in list) {
if (list[key] instanceof Array) {
var keyarr = key.replace(/^\s+|\s+$/g, "");
if (!/\[\w*\]$/.test(key)) keyarr += "[]";
for (var k in list[key]) {
var v = list[key][k];
data += "&" + encodeURIComponent(keyarr) + "=" + encodeURIComponent(v);
}
} else {
data += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(list[key]);
}
}
return data.substr(1);
} else {
return list;
}
};
},
data = new params();
data.add(obj.pdata);
data.add(obj.adata);
data.add(obj.data);
data.add(obj.odata);
if (typeof obj.onload != "function") {
obj.onload = function (obj) {
console.log(["request.load", obj]);
};
}
if (typeof obj.onerror != "function") {
obj.onerror = function (obj) {
console.log(["request.error", obj]);
};
}
var update = function (obj, e) {
obj.response = {
raw : function () {return e;},
text : function () {return e.responseText;},
json : function () {
try {
return JSON.parse(e.responseText);
} catch (x) {
return eval("(" + e.responseText + ")");
}
},
doc : function () {
try {
return new DOMParser().parseFromString(e.responseText, /^Content-Type: ([\w/]+)$/mi.test(e.responseHeaders) && RegExp.$1 || "text/html");
} catch (x) {
var doc = document.implementation.createHTMLDocument("");
doc.documentElement.innerHTML = e.responseText;
return doc;
}
},
};
obj.value = e.responseText;
},
params = {
url : obj.url,
method : obj.method,
onload : function (e) {
update(obj, e);
obj[(/^2/.test(e.status)?"onload":"onerror")].apply(xthis, [obj]);
},
onerror : function (e) {
update(obj, e);
obj.onerror.apply(xthis, [obj]);
}
},
sdata = data.toString();
if (/^post$/i.test(obj.method)) {
var p = {
headers : {
"Content-Type" : "application/x-www-form-urlencoded"
},
data : sdata,
};
console.log(sdata);
for (k in p) {
params[k] = p[k];
}
} else if (sdata) {
params.url += "?" + sdata;
}
if (typeof obj.headers == "object")
for (k in obj.headers) {
params.headers[k] = obj.headers[k];
}
return GM_xmlhttpRequest(params);
};
for (var k in service) {
this[k] = service[k];
}
};
Persist.services = {
LOCAL : {
write : function (obj) {
var label_keys = "persist_keys-" + obj.service,
label_data = "persist_data-" + obj.service,
mapping = JSON.parse(GM_getValue(label_keys, "{}")),
data = JSON.parse(GM_getValue(label_data, "[]")),
key = obj.key;
if (key in mapping) {
key = mapping[obj.key];
}
if (key in data) {
var tv = typeof obj.value,
td = typeof data[key];
if ((td != tv) && (td == "object" || tv == "object")) {
throw ["Incompatible types ", td, tv].toString();
} else {
switch (td) {
case "string":
if (-1 == obj.mode) { // prepend
data[key] = obj.value + data[key];
} else if (1 == obj.mode) { // append
data[key] += obj.value;
} else { // overwrite (default)
data[key] = obj.value;
}
break;
case "boolean":
if (-1 == obj.mode) { // unused
throw ["Reserved action"].toString();
} else if (1 == obj.mode) { // toggle
data[key] = !data[key];
} else { // overwrite (default)
data[key] = !!value;
}
break;
case "number":
var value = Number(obj.value);
if (-1 == obj.mode) { // subtract
data[key] -= value;
} else if (1 == obj.mode) { // add
data[key] += value;
} else { // overwrite (default)
data[key] = value;
}
break;
case "object":
if (-1 == obj.mode) { // prepend
for (var k in data[key]) {
obj.value[k] = data[key][k];
}
data[key] = obj.value;
} else if (1 == obj.mode) { // append
for (var k in obj.value) {
data[key][k] = obj.value[k];
}
} else { // overwrite (default)
data[key] = obj.value;
}
break;
default:
throw ["Unsupported type " + td, data[key], key].toString();
}
obj.value = data[key];
}
} else {
var tkey = data.push(obj.value);
if (--tkey != key) {
if ("key" in obj) {
if (key in mapping) {
console.log(["Wrong mapping... ", tkey, key]);
}
mapping[key] = tkey;
obj.key = key;
GM_setValue(label_keys, JSON.stringify(mapping));
} else {
obj.key = tkey;
}
}
}
GM_setValue(label_data, JSON.stringify(data));
if (typeof obj.onload != "function") {
obj.onload = function (obj) {
console.log(["write.load", obj]);
};
}
return obj.onload.apply(this, [obj]);
},
delete : function (obj) {
throw ["Not implemented"].toString();
},
read : function (obj) {
var mapping = JSON.parse(GM_getValue("persist_keys-" + obj.service, "{}")),
key = obj.key;
if (key in mapping) {
key = mapping[key];
}
obj.value = JSON.parse(GM_getValue("persist_data-" + obj.service, "[]"))[key];
if (typeof obj.onload != "function") {
obj.onload = function (obj) {
console.log(["read.load", obj]);
};
}
return obj.onload.apply(this, [obj]);
},
},
PASTEBIN : {
write : function (obj) {
var execute = function (x) {
var onload = x.onload,
value = x.value,
xthis = this,
p = {
url : "http://pastebin.com/api/api_post.php",
method : "post",
adata : JSON.parse(GM_getValue("pastebin_adata", JSON.stringify({
// api_dev_key : "", // required
// api_user_key : "",
}))),
pdata : {
api_paste_format : "text",
api_paste_private : "1",
api_paste_expire_date : "N",
api_paste_code : x.value, // required
},
odata : {
api_paste_key : obj.key,
api_option : "paste"
},
onload : function (y) {
if (/^https?:\/\//i.test(y.value) && /\w+$/.test(y.value)) {
var key = x.key;
x.key = RegExp["$&"];
x.onload = onload;
x.value = value;
x.onload.apply(xthis, [x]);
if (x.read) {
/* It is implemented that way because currently there isn't an EDIT option via API */
y.key = key;
y.onload = function (z) {
console.log(["delete.load", z]);
};
y.onerror = function (z) {
console.log(["delete.error", z]);
};
xthis.delete.apply(xthis, [y]);
}
} else {
x.onerror.apply(xthis, [x]);
}
}
};
for (var i in p) {
x[i] = p[i];
}
return this.request(x);
};
if (1 == Math.abs(obj.mode)) { // prepend or append
var value = obj.value,
onload = obj.onload,
xthis = this;
obj.onload = function (x) {
obj.onload = onload;
if (-1 == obj.mode) { // prepend
obj.value = value + obj.value;
} else { // append
obj.value += value;
}
return execute.apply(xthis, [obj]);
};
return this.read.apply(this, [obj]);
} else {
return execute.apply(this, [obj]);
}
},
read : function (obj) {
if ("key" in obj) {
var onload = obj.onload,
xthis = this,
p = {
read : false,
url : "http://pastebin.com/download.php",
method : "get",
adata : {
i : obj.key
},
onload : function (x) {
obj.onload = onload;
if (x.response.raw().finalUrl.indexOf(x.url)) {
obj.value = "";
obj[typeof obj.onwarn == "function"?"onwarn":"onload"].apply(this, [obj]);
} else {
obj.read = true;
obj.onload.apply(xthis, [obj]);
}
}
};
for (var i in p) {
obj[i] = p[i];
}
return this.request(obj);
} else {
obj.value = "";
obj.read = false;
obj[typeof obj.onwarn == "function"?"onwarn":"onload"].apply(this, [obj]);
}
},
delete : function (obj) {
var onload = obj.onload,
value = obj.value,
xthis = this,
p = {
url : "http://pastebin.com/api/api_post.php",
method : "post",
adata : JSON.parse(GM_getValue("pastebin_adata", JSON.stringify({
// api_dev_key : "", // required
// api_user_key : "",
}))),
pdata : {},
odata : {
api_paste_key : obj.key,
api_option : "delete"
},
onload : function (x) {
if (/^Paste Removed$/i.test(x.value)) {
obj.onload = onload;
obj.value = value;
obj.onload.apply(xthis, [obj]);
} else {
obj.onerror.apply(xthis, [obj]);
}
}
};
for (var i in p) {
obj[i] = p[i];
}
return this.request(obj);
},
},
PASTEBIN2 : {
write : function (obj) {
var ovalue = obj.value,
xthis = this,
execute = function (x) {
var onload = x.onload,
nvalue = x.value,
p = {
method : "post",
adata : JSON.parse(GM_getValue("pastebin2_adata", JSON.stringify({
// paste_private : "1",
}))),
pdata : {
paste_format : "1",
paste_private : "2",
paste_expire_date : "N",
paste_code : x.value, // required
},
odata : {
submit : "Submit",
submit_hidden : "submit_hidden",
item_key : obj.key,
post_key : obj.key,
},
onload : function (y) {
var doc = y.response.doc(),
url = y.response.raw().finalUrl;
if (/warning\.php\?p=(\d+)/i.test(url)) {
x.code = RegExp.$1 - 1;
x.value = [
"You have reached your limit of [10] pastes per 24 hours.",
"You have reached your limit of [20] pastes per 24 hours.",
"You have reached your limit of [250] pastes per 24 hours.",
][x.code] || xpath("string(id('content_left')/div[2])", doc) || "Unknown error (WARN " + x.code + ")";
x.onerror.apply(xthis, [x]);
} else if ((/^https?:/i.test(url)) && (/\/(\w+)$/.test(url))) {
x.key = RegExp.$1;
if (xpath("string(.//text()[contains(., 'Pastebin.com is under heavy load right now')])", doc)) {
x.onerror.apply(xthis, [x]);
} else {
if (xpath("id('siimage')", doc)[0]) {
x.value = nvalue;
GM_log(ovalue);
alert("A new window will be opened. You must fill the captcha correctly, otherwise you will lose your data and a new paste will be created next time.");
GM_openInTab(url);
} else {
var code = xpath("id('paste_code')", doc)[0];
x.value = code && code.textContent || "";
}
x.onload = onload;
x.onload.apply(xthis, [x]);
}
} else {
x.value = [
"You have exceeded the maximum file size of [500] kilobytes per paste.",
"You cannot create an empty paste.",
"You have reached the maximum number of [25] unlisted pastes.",
"You have reached the maximum number of [10] private pastes.",
][/index\.php\?e=(\d+)/.test(url) && (x.code = RegExp.$1 - 1)] || xpath("string(id('notice'))", doc) || "Unknown error (ERROR " + x.code + ")";
x.onerror.apply(xthis, [x]);
}
}
};
for (var i in p) {
x[i] = p[i];
}
return this.request(x);
};
if (1 == Math.abs(obj.mode)) { // prepend or append
var onload = obj.onload;
if ("" != ovalue) {
obj.onload = function (x) {
obj.onload = onload;
if (-1 == obj.mode) { // prepend
obj.value = ovalue + obj.value;
} else { // append
obj.value += ovalue;
}
return execute.apply(xthis, [obj]);
};
}
return xthis.read.apply(xthis, [obj]);
} else {
return execute.apply(xthis, [obj]);
}
},
read : function (obj) {
var xthis = this;
if ("key" in obj && obj.key) {
var onload = obj.onload,
p = {
read : false,
url : "http://pastebin.com/download.php",
method : "get",
adata : {
i : obj.key
},
onload : function (x) {
var url = x.response.raw().finalUrl;
x.onload = onload;
if (url.indexOf(x.url)) { // Unknown Paste ID
x.value = "";
x.url = "http://pastebin.com/post.php";
x.key = "";
x[typeof x.onwarn == "function"?"onwarn":"onload"].apply(this, [x]);
} else if (~x.value.indexOf("this is a private paste. If this is your private paste")) { // may occur false positive
x.value = "This is a private paste (#"+x.key+"). You must login to Pastebin first.";
x.onerror.apply(xthis, [x]);
} else if (~x.value.indexOf("Pastebin.com is under heavy load right now")) {
x.value = "Pastebin.com is under heavy load right now.";
x.onerror.apply(xthis, [x]);
} else {
x.read = true;
x.url = "http://pastebin.com/edit.php";
x.onload.apply(xthis, [x]);
}
}
};
for (var i in p) {
obj[i] = p[i];
}
return this.request(obj);
} else {
obj.read = false;
obj.url = "http://pastebin.com/post.php";
obj.key = "";
this.request({
url : "http://pastebin.com/",
method : "get",
onload : function (c) {
if (xpath("boolean(id('header_bottom')//a[contains(@href, '/logout')])", c.response.doc())) {
obj.value = "";
obj[typeof obj.onwarn == "function"?"onwarn":"onload"].apply(xthis, [obj]);
} else {
obj.value = "You must login to Pastebin first.";
obj.onerror.apply(xthis, [obj]);
}
},
onerror : function (c) {
c.value = xpath("string(id('content_left')/div[1])", c.response.doc());
obj.onerror(c);
},
});
}
},
delete : function (obj) {
var onload = obj.onload,
value = obj.value,
xthis = this,
p = {
url : "http://pastebin.com/delete.php",
method : "get",
adata : {},
pdata : {},
odata : {
i : obj.key,
r : "/" + obj.key
},
onload : function (x) {
if (/^Paste Removed$/i.test(x.value)) {
obj.onload = onload;
obj.value = value;
obj.onload.apply(xthis, [obj]);
} else {
obj.onerror.apply(xthis, [obj]);
}
}
};
for (var i in p) {
obj[i] = p[i];
}
return this.request(obj);
}
}
};
Persist.write = function (obj) {
var p = new Persist(obj.service);
return p.write.apply(p, [obj]);
};
Persist.delete = function (obj) {
var p = new Persist(obj.service);
return p.delete.apply(p, [obj]);
};
Persist.read = function (obj) {
var p = new Persist(obj.service);
return p.read.apply(p, [obj]);
};