Merge branch 'v3' of git://github.com/zixaphir/appchan-x
This commit is contained in:
commit
133c8bd1f9
@ -302,6 +302,59 @@
|
|||||||
posts: {}
|
posts: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
String.prototype.capitalize = function() {
|
||||||
|
return this.charAt(0).toUpperCase() + this.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.contains = function(string) {
|
||||||
|
return this.indexOf(string) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.add = function(object, position) {
|
||||||
|
var keep;
|
||||||
|
|
||||||
|
keep = this.slice(position);
|
||||||
|
this.length = position;
|
||||||
|
this.push(object);
|
||||||
|
return this.pushArrays(keep);
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.contains = function(object) {
|
||||||
|
return this.indexOf(object) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.indexOf = function(object) {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
i = this.length;
|
||||||
|
while (i--) {
|
||||||
|
if (this[i] === object) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.pushArrays = function() {
|
||||||
|
var arg, args, _i, _len;
|
||||||
|
|
||||||
|
args = arguments;
|
||||||
|
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
||||||
|
arg = args[_i];
|
||||||
|
this.push.apply(this, arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.remove = function(object) {
|
||||||
|
var index;
|
||||||
|
|
||||||
|
if ((index = this.indexOf(object)) > -1) {
|
||||||
|
return this.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$ = function(selector, root) {
|
$ = function(selector, root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = d.body;
|
root = d.body;
|
||||||
@ -309,15 +362,6 @@
|
|||||||
return root.querySelector(selector);
|
return root.querySelector(selector);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d.body;
|
|
||||||
}
|
|
||||||
return __slice.call(root.querySelectorAll(selector));
|
|
||||||
};
|
|
||||||
|
|
||||||
$.extend = function(object, properties) {
|
$.extend = function(object, properties) {
|
||||||
var key, val;
|
var key, val;
|
||||||
|
|
||||||
@ -330,462 +374,451 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend(Array.prototype, {
|
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
||||||
add: function(object, position) {
|
|
||||||
var keep;
|
|
||||||
|
|
||||||
keep = this.slice(position);
|
$.id = function(id) {
|
||||||
this.length = position;
|
return d.getElementById(id);
|
||||||
this.push(object);
|
};
|
||||||
return this.pushArrays(keep);
|
|
||||||
},
|
|
||||||
contains: function(object) {
|
|
||||||
return this.indexOf(object) > -1;
|
|
||||||
},
|
|
||||||
indexOf: function(object) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
i = this.length;
|
$.ready = function(fc) {
|
||||||
while (i--) {
|
var cb, _ref;
|
||||||
if (this[i] === object) {
|
|
||||||
break;
|
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
||||||
}
|
$.queueTask(fc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cb = function() {
|
||||||
|
$.off(d, 'DOMContentLoaded', cb);
|
||||||
|
return fc();
|
||||||
|
};
|
||||||
|
return $.on(d, 'DOMContentLoaded', cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.formData = function(form) {
|
||||||
|
var fd, key, val;
|
||||||
|
|
||||||
|
if (form instanceof HTMLFormElement) {
|
||||||
|
return new FormData(form);
|
||||||
|
}
|
||||||
|
fd = new FormData();
|
||||||
|
for (key in form) {
|
||||||
|
val = form[key];
|
||||||
|
if (!val) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
return i;
|
if (val.size && val.name) {
|
||||||
},
|
fd.append(key, val, val.name);
|
||||||
pushArrays: function() {
|
|
||||||
var arg, args, _i, _len;
|
|
||||||
|
|
||||||
args = arguments;
|
|
||||||
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
|
||||||
arg = args[_i];
|
|
||||||
this.push.apply(this, arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove: function(object) {
|
|
||||||
var index;
|
|
||||||
|
|
||||||
if ((index = this.indexOf(object)) > -1) {
|
|
||||||
return this.splice(index, 1);
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
fd.append(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
return fd;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend(String.prototype, {
|
$.ajax = function(url, callbacks, opts) {
|
||||||
capitalize: function() {
|
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
||||||
return this.charAt(0).toUpperCase() + this.slice(1);
|
|
||||||
},
|
if (opts == null) {
|
||||||
contains: function(string) {
|
opts = {};
|
||||||
return this.indexOf(string) > -1;
|
|
||||||
}
|
}
|
||||||
});
|
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
||||||
|
r = new XMLHttpRequest();
|
||||||
|
r.overrideMimeType('text/html');
|
||||||
|
type || (type = form && 'post' || 'get');
|
||||||
|
r.open(type, url, !sync);
|
||||||
|
for (key in headers) {
|
||||||
|
val = headers[key];
|
||||||
|
r.setRequestHeader(key, val);
|
||||||
|
}
|
||||||
|
$.extend(r, callbacks);
|
||||||
|
$.extend(r.upload, upCallbacks);
|
||||||
|
r.withCredentials = cred;
|
||||||
|
r.send(form);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend($, {
|
$.cache = (function() {
|
||||||
id: function(id) {
|
var reqs;
|
||||||
return d.getElementById(id);
|
|
||||||
},
|
|
||||||
ready: function(fc) {
|
|
||||||
var cb, _ref;
|
|
||||||
|
|
||||||
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
reqs = {};
|
||||||
$.queueTask(fc);
|
return function(url, cb) {
|
||||||
|
var req, rm;
|
||||||
|
|
||||||
|
if (req = reqs[url]) {
|
||||||
|
if (req.readyState === 4) {
|
||||||
|
cb.call(req);
|
||||||
|
} else {
|
||||||
|
req.callbacks.push(cb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cb = function() {
|
rm = function() {
|
||||||
$.off(d, 'DOMContentLoaded', cb);
|
return delete reqs[url];
|
||||||
return fc();
|
|
||||||
};
|
};
|
||||||
return $.on(d, 'DOMContentLoaded', cb);
|
req = $.ajax(url, {
|
||||||
},
|
onload: function(e) {
|
||||||
formData: function(form) {
|
var _i, _len, _ref;
|
||||||
var fd, key, val;
|
|
||||||
|
|
||||||
if (form instanceof HTMLFormElement) {
|
_ref = this.callbacks;
|
||||||
return new FormData(form);
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
}
|
cb = _ref[_i];
|
||||||
fd = new FormData();
|
cb.call(this, e);
|
||||||
for (key in form) {
|
|
||||||
val = form[key];
|
|
||||||
if (!val) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (val.size && val.name) {
|
|
||||||
fd.append(key, val, val.name);
|
|
||||||
} else {
|
|
||||||
fd.append(key, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
},
|
|
||||||
ajax: function(url, callbacks, opts) {
|
|
||||||
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
|
||||||
|
|
||||||
if (opts == null) {
|
|
||||||
opts = {};
|
|
||||||
}
|
|
||||||
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
|
||||||
r = new XMLHttpRequest();
|
|
||||||
r.overrideMimeType('text/html');
|
|
||||||
type || (type = form && 'post' || 'get');
|
|
||||||
r.open(type, url, !sync);
|
|
||||||
for (key in headers) {
|
|
||||||
val = headers[key];
|
|
||||||
r.setRequestHeader(key, val);
|
|
||||||
}
|
|
||||||
$.extend(r, callbacks);
|
|
||||||
$.extend(r.upload, upCallbacks);
|
|
||||||
r.withCredentials = cred;
|
|
||||||
r.send(form);
|
|
||||||
return r;
|
|
||||||
},
|
|
||||||
cache: (function() {
|
|
||||||
var reqs;
|
|
||||||
|
|
||||||
reqs = {};
|
|
||||||
return function(url, cb) {
|
|
||||||
var req, rm;
|
|
||||||
|
|
||||||
if (req = reqs[url]) {
|
|
||||||
if (req.readyState === 4) {
|
|
||||||
cb.call(req);
|
|
||||||
} else {
|
|
||||||
req.callbacks.push(cb);
|
|
||||||
}
|
}
|
||||||
return;
|
return delete this.callbacks;
|
||||||
}
|
},
|
||||||
rm = function() {
|
onabort: rm,
|
||||||
return delete reqs[url];
|
onerror: rm
|
||||||
};
|
|
||||||
req = $.ajax(url, {
|
|
||||||
onload: function(e) {
|
|
||||||
var _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = this.callbacks;
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
cb = _ref[_i];
|
|
||||||
cb.call(this, e);
|
|
||||||
}
|
|
||||||
return delete this.callbacks;
|
|
||||||
},
|
|
||||||
onabort: rm,
|
|
||||||
onerror: rm
|
|
||||||
});
|
|
||||||
req.callbacks = [cb];
|
|
||||||
return reqs[url] = req;
|
|
||||||
};
|
|
||||||
})(),
|
|
||||||
cb: {
|
|
||||||
checked: function() {
|
|
||||||
$.set(this.name, this.checked);
|
|
||||||
return Conf[this.name] = this.checked;
|
|
||||||
},
|
|
||||||
value: function() {
|
|
||||||
$.set(this.name, this.value.trim());
|
|
||||||
return Conf[this.name] = this.value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
asap: function(test, cb) {
|
|
||||||
if (test()) {
|
|
||||||
return cb();
|
|
||||||
} else {
|
|
||||||
return setTimeout($.asap, 25, test, cb);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addStyle: function(css, id) {
|
|
||||||
var style;
|
|
||||||
|
|
||||||
style = $.el('style', {
|
|
||||||
id: id,
|
|
||||||
textContent: css
|
|
||||||
});
|
});
|
||||||
$.asap((function() {
|
req.callbacks = [cb];
|
||||||
return d.head;
|
return reqs[url] = req;
|
||||||
}), function() {
|
};
|
||||||
return $.add(d.head, style);
|
})();
|
||||||
});
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
x: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
|
||||||
},
|
|
||||||
X: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
||||||
},
|
|
||||||
addClass: function(el, className) {
|
|
||||||
return el.classList.add(className);
|
|
||||||
},
|
|
||||||
rmClass: function(el, className) {
|
|
||||||
return el.classList.remove(className);
|
|
||||||
},
|
|
||||||
toggleClass: function(el, className) {
|
|
||||||
return el.classList.toggle(className);
|
|
||||||
},
|
|
||||||
hasClass: function(el, className) {
|
|
||||||
return el.classList.contains(className);
|
|
||||||
},
|
|
||||||
rm: (function() {
|
|
||||||
if ('remove' in Element.prototype) {
|
|
||||||
return function(el) {
|
|
||||||
return el.remove();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(el) {
|
|
||||||
var _ref;
|
|
||||||
|
|
||||||
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
$.cb = {
|
||||||
};
|
checked: function() {
|
||||||
}
|
$.set(this.name, this.checked);
|
||||||
})(),
|
return Conf[this.name] = this.checked;
|
||||||
rmAll: function(root) {
|
|
||||||
var node;
|
|
||||||
|
|
||||||
while (node = root.firstChild) {
|
|
||||||
root.removeChild(node);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
tn: function(s) {
|
value: function() {
|
||||||
return d.createTextNode(s);
|
$.set(this.name, this.value.trim());
|
||||||
},
|
return Conf[this.name] = this.value;
|
||||||
frag: function() {
|
|
||||||
return d.createDocumentFragment();
|
|
||||||
},
|
|
||||||
nodes: function(nodes) {
|
|
||||||
var frag, node, _i, _len;
|
|
||||||
|
|
||||||
if (!(nodes instanceof Array)) {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
frag = $.frag();
|
|
||||||
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
|
||||||
node = nodes[_i];
|
|
||||||
frag.appendChild(node);
|
|
||||||
}
|
|
||||||
return frag;
|
|
||||||
},
|
|
||||||
add: function(parent, el) {
|
|
||||||
return parent.appendChild($.nodes(el));
|
|
||||||
},
|
|
||||||
prepend: function(parent, el) {
|
|
||||||
return parent.insertBefore($.nodes(el), parent.firstChild);
|
|
||||||
},
|
|
||||||
after: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
|
||||||
},
|
|
||||||
before: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root);
|
|
||||||
},
|
|
||||||
replace: function(root, el) {
|
|
||||||
return root.parentNode.replaceChild($.nodes(el), root);
|
|
||||||
},
|
|
||||||
el: function(tag, properties) {
|
|
||||||
var el;
|
|
||||||
|
|
||||||
el = d.createElement(tag);
|
|
||||||
if (properties) {
|
|
||||||
$.extend(el, properties);
|
|
||||||
}
|
|
||||||
return el;
|
|
||||||
},
|
|
||||||
on: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.addEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
off: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.removeEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event: function(event, detail, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d;
|
|
||||||
}
|
|
||||||
return root.dispatchEvent(new CustomEvent(event, {
|
|
||||||
bubbles: true,
|
|
||||||
detail: detail
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
open: (function() {
|
|
||||||
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
|
||||||
return function(URL) {
|
|
||||||
var a;
|
|
||||||
|
|
||||||
a = $.el('a', {
|
|
||||||
href: URL
|
|
||||||
});
|
|
||||||
return GM_openInTab(a.href);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(URL) {
|
|
||||||
return window.open(URL, '_blank');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
debounce: function(wait, fn) {
|
|
||||||
var args, exec, that, timeout;
|
|
||||||
|
|
||||||
timeout = null;
|
|
||||||
that = null;
|
|
||||||
args = null;
|
|
||||||
exec = function() {
|
|
||||||
fn.apply(that, args);
|
|
||||||
return timeout = null;
|
|
||||||
};
|
|
||||||
return function() {
|
|
||||||
args = arguments;
|
|
||||||
that = this;
|
|
||||||
if (timeout) {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} else {
|
|
||||||
exec();
|
|
||||||
}
|
|
||||||
return timeout = setTimeout(exec, wait);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
queueTask: (function() {
|
|
||||||
var execTask, taskChannel, taskQueue;
|
|
||||||
|
|
||||||
taskQueue = [];
|
|
||||||
execTask = function() {
|
|
||||||
var args, func, task;
|
|
||||||
|
|
||||||
task = taskQueue.shift();
|
|
||||||
func = task[0];
|
|
||||||
args = Array.prototype.slice.call(task, 1);
|
|
||||||
return func.apply(func, args);
|
|
||||||
};
|
|
||||||
if (window.MessageChannel) {
|
|
||||||
taskChannel = new MessageChannel();
|
|
||||||
taskChannel.port1.onmessage = execTask;
|
|
||||||
return function() {
|
|
||||||
taskQueue.push(arguments);
|
|
||||||
return taskChannel.port2.postMessage(null);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function() {
|
|
||||||
taskQueue.push(arguments);
|
|
||||||
return setTimeout(execTask, 0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
globalEval: function(code) {
|
|
||||||
var script;
|
|
||||||
|
|
||||||
script = $.el('script', {
|
|
||||||
textContent: code
|
|
||||||
});
|
|
||||||
$.add(d.head || doc, script);
|
|
||||||
return $.rm(script);
|
|
||||||
},
|
|
||||||
bytesToString: function(size) {
|
|
||||||
var unit;
|
|
||||||
|
|
||||||
unit = 0;
|
|
||||||
while (size >= 1024) {
|
|
||||||
size /= 1024;
|
|
||||||
unit++;
|
|
||||||
}
|
|
||||||
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
|
||||||
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
|
||||||
},
|
|
||||||
minmax: function(value, min, max) {
|
|
||||||
return (value < min ? min : value > max ? max : value);
|
|
||||||
},
|
|
||||||
syncing: {},
|
|
||||||
sync: (function() {
|
|
||||||
window.addEventListener('storage', function(e) {
|
|
||||||
var cb;
|
|
||||||
|
|
||||||
if (cb = $.syncing[e.key]) {
|
|
||||||
return cb(JSON.parse(e.newValue));
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
return function(key, cb) {
|
|
||||||
return $.syncing[g.NAMESPACE + key] = cb;
|
|
||||||
};
|
|
||||||
})(),
|
|
||||||
item: function(key, val) {
|
|
||||||
var item;
|
|
||||||
|
|
||||||
item = {};
|
|
||||||
item[key] = val;
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
$.asap = function(test, cb) {
|
||||||
|
if (test()) {
|
||||||
|
return cb();
|
||||||
|
} else {
|
||||||
|
return setTimeout($.asap, 25, test, cb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addStyle = function(css, id) {
|
||||||
|
var style;
|
||||||
|
|
||||||
|
style = $.el('style', {
|
||||||
|
id: id,
|
||||||
|
textContent: css
|
||||||
|
});
|
||||||
|
$.asap((function() {
|
||||||
|
return d.head;
|
||||||
|
}), function() {
|
||||||
|
return $.add(d.head, style);
|
||||||
|
});
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.x = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.X = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addClass = function(el, className) {
|
||||||
|
return el.classList.add(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rmClass = function(el, className) {
|
||||||
|
return el.classList.remove(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.toggleClass = function(el, className) {
|
||||||
|
return el.classList.toggle(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.hasClass = function(el, className) {
|
||||||
|
return el.classList.contains(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rm = (function() {
|
||||||
|
if ('remove' in Element.prototype) {
|
||||||
|
return function(el) {
|
||||||
|
return el.remove();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function(el) {
|
||||||
|
var _ref;
|
||||||
|
|
||||||
|
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.rmAll = function(root) {
|
||||||
|
var node;
|
||||||
|
|
||||||
|
while (node = root.firstChild) {
|
||||||
|
root.removeChild(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.tn = function(s) {
|
||||||
|
return d.createTextNode(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.frag = function() {
|
||||||
|
return d.createDocumentFragment();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.nodes = function(nodes) {
|
||||||
|
var frag, node, _i, _len;
|
||||||
|
|
||||||
|
if (!(nodes instanceof Array)) {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
frag = $.frag();
|
||||||
|
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
||||||
|
node = nodes[_i];
|
||||||
|
frag.appendChild(node);
|
||||||
|
}
|
||||||
|
return frag;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.add = function(parent, el) {
|
||||||
|
return parent.appendChild($.nodes(el));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.prepend = function(parent, el) {
|
||||||
|
return parent.insertBefore($.nodes(el), parent.firstChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.after = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.before = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.replace = function(root, el) {
|
||||||
|
return root.parentNode.replaceChild($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.el = function(tag, properties) {
|
||||||
|
var el;
|
||||||
|
|
||||||
|
el = d.createElement(tag);
|
||||||
|
if (properties) {
|
||||||
|
$.extend(el, properties);
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.on = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.addEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.off = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.removeEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.event = function(event, detail, root) {
|
||||||
|
if (root == null) {
|
||||||
|
root = d;
|
||||||
|
}
|
||||||
|
return root.dispatchEvent(new CustomEvent(event, {
|
||||||
|
bubbles: true,
|
||||||
|
detail: detail
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.open = (function() {
|
||||||
|
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
||||||
|
return function(URL) {
|
||||||
|
var a;
|
||||||
|
|
||||||
|
a = $.el('a', {
|
||||||
|
href: URL
|
||||||
|
});
|
||||||
|
return GM_openInTab(a.href);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function(URL) {
|
||||||
|
return window.open(URL, '_blank');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.debounce = function(wait, fn) {
|
||||||
|
var args, exec, that, timeout;
|
||||||
|
|
||||||
|
timeout = null;
|
||||||
|
that = null;
|
||||||
|
args = null;
|
||||||
|
exec = function() {
|
||||||
|
fn.apply(that, args);
|
||||||
|
return timeout = null;
|
||||||
|
};
|
||||||
|
return function() {
|
||||||
|
args = arguments;
|
||||||
|
that = this;
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
} else {
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
return timeout = setTimeout(exec, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$.queueTask = (function() {
|
||||||
|
var execTask, taskChannel, taskQueue;
|
||||||
|
|
||||||
|
taskQueue = [];
|
||||||
|
execTask = function() {
|
||||||
|
var args, func, task;
|
||||||
|
|
||||||
|
task = taskQueue.shift();
|
||||||
|
func = task[0];
|
||||||
|
args = Array.prototype.slice.call(task, 1);
|
||||||
|
return func.apply(func, args);
|
||||||
|
};
|
||||||
|
if (window.MessageChannel) {
|
||||||
|
taskChannel = new MessageChannel();
|
||||||
|
taskChannel.port1.onmessage = execTask;
|
||||||
|
return function() {
|
||||||
|
taskQueue.push(arguments);
|
||||||
|
return taskChannel.port2.postMessage(null);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function() {
|
||||||
|
taskQueue.push(arguments);
|
||||||
|
return setTimeout(execTask, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.globalEval = function(code) {
|
||||||
|
var script;
|
||||||
|
|
||||||
|
script = $.el('script', {
|
||||||
|
textContent: code
|
||||||
|
});
|
||||||
|
$.add(d.head || doc, script);
|
||||||
|
return $.rm(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.bytesToString = function(size) {
|
||||||
|
var unit;
|
||||||
|
|
||||||
|
unit = 0;
|
||||||
|
while (size >= 1024) {
|
||||||
|
size /= 1024;
|
||||||
|
unit++;
|
||||||
|
}
|
||||||
|
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
||||||
|
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.minmax = function(value, min, max) {
|
||||||
|
return (value < min ? min : value > max ? max : value);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.syncing = {};
|
||||||
|
|
||||||
|
$.sync = (function() {
|
||||||
|
window.addEventListener('storage', function(e) {
|
||||||
|
var cb;
|
||||||
|
|
||||||
|
if (cb = $.syncing[e.key]) {
|
||||||
|
return cb(JSON.parse(e.newValue));
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
return function(key, cb) {
|
||||||
|
return $.syncing[g.NAMESPACE + key] = cb;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.item = function(key, val) {
|
||||||
|
var item;
|
||||||
|
|
||||||
|
item = {};
|
||||||
|
item[key] = val;
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var scriptStorage;
|
var cb, items, key, keys, scriptStorage, _i, _len;
|
||||||
|
|
||||||
scriptStorage = opera.scriptStorage;
|
scriptStorage = opera.scriptStorage;
|
||||||
$["delete"] = function(keys) {
|
$["delete"] = function(keys) {};
|
||||||
var key, _i, _len;
|
if (!(keys instanceof Array)) {
|
||||||
|
keys = [keys];
|
||||||
|
}
|
||||||
|
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
||||||
|
key = keys[_i];
|
||||||
|
key = g.NAMESPACE + key;
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
delete scriptStorage[key];
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
$.get = function(key, val, cb) {};
|
||||||
|
if (typeof cb === 'function') {
|
||||||
|
items = $.item(key, val);
|
||||||
|
} else {
|
||||||
|
items = key;
|
||||||
|
cb = val;
|
||||||
|
}
|
||||||
|
return $.queueTask(function() {
|
||||||
|
var val;
|
||||||
|
|
||||||
if (!(keys instanceof Array)) {
|
for (key in items) {
|
||||||
keys = [keys];
|
if (val = scriptStorage[g.NAMESPACE + key]) {
|
||||||
|
items[key] = JSON.parse(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
return cb(items);
|
||||||
key = keys[_i];
|
});
|
||||||
key = g.NAMESPACE + key;
|
|
||||||
localStorage.removeItem(key);
|
|
||||||
delete scriptStorage[key];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
$.get = function(key, val, cb) {
|
|
||||||
var items;
|
|
||||||
|
|
||||||
if (typeof cb === 'function') {
|
|
||||||
items = $.item(key, val);
|
|
||||||
} else {
|
|
||||||
items = key;
|
|
||||||
cb = val;
|
|
||||||
}
|
|
||||||
return $.queueTask(function() {
|
|
||||||
for (key in items) {
|
|
||||||
if (val = scriptStorage[g.NAMESPACE + key]) {
|
|
||||||
items[key] = JSON.parse(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cb(items);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return $.set = (function() {
|
|
||||||
var set;
|
|
||||||
|
|
||||||
set = function(key, val) {
|
|
||||||
key = g.NAMESPACE + key;
|
|
||||||
val = JSON.stringify(val);
|
|
||||||
if (key in $.syncing) {
|
|
||||||
localStorage.setItem(key, val);
|
|
||||||
}
|
|
||||||
return scriptStorage[key] = val;
|
|
||||||
};
|
|
||||||
return function(keys, val) {
|
|
||||||
var key;
|
|
||||||
|
|
||||||
if (typeof keys === 'string') {
|
|
||||||
set(keys, val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (key in keys) {
|
|
||||||
val = keys[key];
|
|
||||||
set(key, val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
$.set = (function() {
|
||||||
|
var set;
|
||||||
|
|
||||||
|
set = function(key, val) {
|
||||||
|
key = g.NAMESPACE + key;
|
||||||
|
val = JSON.stringify(val);
|
||||||
|
if (key in $.syncing) {
|
||||||
|
localStorage.setItem(key, val);
|
||||||
|
}
|
||||||
|
return scriptStorage[key] = val;
|
||||||
|
};
|
||||||
|
return function(keys, val) {
|
||||||
|
var key;
|
||||||
|
|
||||||
|
if (typeof keys === 'string') {
|
||||||
|
set(keys, val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (key in keys) {
|
||||||
|
val = keys[key];
|
||||||
|
set(key, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
$$ = function(selector, root) {
|
||||||
|
if (root == null) {
|
||||||
|
root = d.body;
|
||||||
|
}
|
||||||
|
return __slice.call(root.querySelectorAll(selector));
|
||||||
|
};
|
||||||
|
|
||||||
Build = {
|
Build = {
|
||||||
spoilerRange: {},
|
spoilerRange: {},
|
||||||
shortFilename: function(filename, isReply) {
|
shortFilename: function(filename, isReply) {
|
||||||
|
|||||||
@ -299,6 +299,59 @@
|
|||||||
posts: {}
|
posts: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
String.prototype.capitalize = function() {
|
||||||
|
return this.charAt(0).toUpperCase() + this.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.contains = function(string) {
|
||||||
|
return this.indexOf(string) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.add = function(object, position) {
|
||||||
|
var keep;
|
||||||
|
|
||||||
|
keep = this.slice(position);
|
||||||
|
this.length = position;
|
||||||
|
this.push(object);
|
||||||
|
return this.pushArrays(keep);
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.contains = function(object) {
|
||||||
|
return this.indexOf(object) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.indexOf = function(object) {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
i = this.length;
|
||||||
|
while (i--) {
|
||||||
|
if (this[i] === object) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.pushArrays = function() {
|
||||||
|
var arg, args, _i, _len;
|
||||||
|
|
||||||
|
args = arguments;
|
||||||
|
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
||||||
|
arg = args[_i];
|
||||||
|
this.push.apply(this, arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.remove = function(object) {
|
||||||
|
var index;
|
||||||
|
|
||||||
|
if ((index = this.indexOf(object)) > -1) {
|
||||||
|
return this.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$ = function(selector, root) {
|
$ = function(selector, root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = d.body;
|
root = d.body;
|
||||||
@ -306,15 +359,6 @@
|
|||||||
return root.querySelector(selector);
|
return root.querySelector(selector);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d.body;
|
|
||||||
}
|
|
||||||
return __slice.call(root.querySelectorAll(selector));
|
|
||||||
};
|
|
||||||
|
|
||||||
$.extend = function(object, properties) {
|
$.extend = function(object, properties) {
|
||||||
var key, val;
|
var key, val;
|
||||||
|
|
||||||
@ -327,455 +371,449 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend(Array.prototype, {
|
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
||||||
add: function(object, position) {
|
|
||||||
var keep;
|
|
||||||
|
|
||||||
keep = this.slice(position);
|
$.id = function(id) {
|
||||||
this.length = position;
|
return d.getElementById(id);
|
||||||
this.push(object);
|
};
|
||||||
return this.pushArrays(keep);
|
|
||||||
},
|
|
||||||
contains: function(object) {
|
|
||||||
return this.indexOf(object) > -1;
|
|
||||||
},
|
|
||||||
indexOf: function(object) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
i = this.length;
|
$.ready = function(fc) {
|
||||||
while (i--) {
|
var cb, _ref;
|
||||||
if (this[i] === object) {
|
|
||||||
break;
|
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
||||||
}
|
$.queueTask(fc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cb = function() {
|
||||||
|
$.off(d, 'DOMContentLoaded', cb);
|
||||||
|
return fc();
|
||||||
|
};
|
||||||
|
return $.on(d, 'DOMContentLoaded', cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.formData = function(form) {
|
||||||
|
var fd, key, val;
|
||||||
|
|
||||||
|
if (form instanceof HTMLFormElement) {
|
||||||
|
return new FormData(form);
|
||||||
|
}
|
||||||
|
fd = new FormData();
|
||||||
|
for (key in form) {
|
||||||
|
val = form[key];
|
||||||
|
if (!val) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
return i;
|
if (val.size && val.name) {
|
||||||
},
|
fd.append(key, val, val.name);
|
||||||
pushArrays: function() {
|
|
||||||
var arg, args, _i, _len;
|
|
||||||
|
|
||||||
args = arguments;
|
|
||||||
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
|
||||||
arg = args[_i];
|
|
||||||
this.push.apply(this, arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove: function(object) {
|
|
||||||
var index;
|
|
||||||
|
|
||||||
if ((index = this.indexOf(object)) > -1) {
|
|
||||||
return this.splice(index, 1);
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
fd.append(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
return fd;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend(String.prototype, {
|
$.ajax = function(url, callbacks, opts) {
|
||||||
capitalize: function() {
|
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
||||||
return this.charAt(0).toUpperCase() + this.slice(1);
|
|
||||||
},
|
if (opts == null) {
|
||||||
contains: function(string) {
|
opts = {};
|
||||||
return this.indexOf(string) > -1;
|
|
||||||
}
|
}
|
||||||
});
|
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
||||||
|
r = new XMLHttpRequest();
|
||||||
|
r.overrideMimeType('text/html');
|
||||||
|
type || (type = form && 'post' || 'get');
|
||||||
|
r.open(type, url, !sync);
|
||||||
|
for (key in headers) {
|
||||||
|
val = headers[key];
|
||||||
|
r.setRequestHeader(key, val);
|
||||||
|
}
|
||||||
|
$.extend(r, callbacks);
|
||||||
|
$.extend(r.upload, upCallbacks);
|
||||||
|
r.withCredentials = cred;
|
||||||
|
r.send(form);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend($, {
|
$.cache = (function() {
|
||||||
id: function(id) {
|
var reqs;
|
||||||
return d.getElementById(id);
|
|
||||||
},
|
|
||||||
ready: function(fc) {
|
|
||||||
var cb, _ref;
|
|
||||||
|
|
||||||
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
reqs = {};
|
||||||
$.queueTask(fc);
|
return function(url, cb) {
|
||||||
|
var req, rm;
|
||||||
|
|
||||||
|
if (req = reqs[url]) {
|
||||||
|
if (req.readyState === 4) {
|
||||||
|
cb.call(req);
|
||||||
|
} else {
|
||||||
|
req.callbacks.push(cb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cb = function() {
|
rm = function() {
|
||||||
$.off(d, 'DOMContentLoaded', cb);
|
return delete reqs[url];
|
||||||
return fc();
|
|
||||||
};
|
};
|
||||||
return $.on(d, 'DOMContentLoaded', cb);
|
req = $.ajax(url, {
|
||||||
},
|
onload: function(e) {
|
||||||
formData: function(form) {
|
var _i, _len, _ref;
|
||||||
var fd, key, val;
|
|
||||||
|
|
||||||
if (form instanceof HTMLFormElement) {
|
_ref = this.callbacks;
|
||||||
return new FormData(form);
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
}
|
cb = _ref[_i];
|
||||||
fd = new FormData();
|
cb.call(this, e);
|
||||||
for (key in form) {
|
|
||||||
val = form[key];
|
|
||||||
if (!val) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (val.size && val.name) {
|
|
||||||
fd.append(key, val, val.name);
|
|
||||||
} else {
|
|
||||||
fd.append(key, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
},
|
|
||||||
ajax: function(url, callbacks, opts) {
|
|
||||||
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
|
||||||
|
|
||||||
if (opts == null) {
|
|
||||||
opts = {};
|
|
||||||
}
|
|
||||||
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
|
||||||
r = new XMLHttpRequest();
|
|
||||||
r.overrideMimeType('text/html');
|
|
||||||
type || (type = form && 'post' || 'get');
|
|
||||||
r.open(type, url, !sync);
|
|
||||||
for (key in headers) {
|
|
||||||
val = headers[key];
|
|
||||||
r.setRequestHeader(key, val);
|
|
||||||
}
|
|
||||||
$.extend(r, callbacks);
|
|
||||||
$.extend(r.upload, upCallbacks);
|
|
||||||
r.withCredentials = cred;
|
|
||||||
r.send(form);
|
|
||||||
return r;
|
|
||||||
},
|
|
||||||
cache: (function() {
|
|
||||||
var reqs;
|
|
||||||
|
|
||||||
reqs = {};
|
|
||||||
return function(url, cb) {
|
|
||||||
var req, rm;
|
|
||||||
|
|
||||||
if (req = reqs[url]) {
|
|
||||||
if (req.readyState === 4) {
|
|
||||||
cb.call(req);
|
|
||||||
} else {
|
|
||||||
req.callbacks.push(cb);
|
|
||||||
}
|
}
|
||||||
return;
|
return delete this.callbacks;
|
||||||
}
|
},
|
||||||
rm = function() {
|
onabort: rm,
|
||||||
return delete reqs[url];
|
onerror: rm
|
||||||
};
|
});
|
||||||
req = $.ajax(url, {
|
req.callbacks = [cb];
|
||||||
onload: function(e) {
|
return reqs[url] = req;
|
||||||
var _i, _len, _ref;
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
_ref = this.callbacks;
|
$.cb = {
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
checked: function() {
|
||||||
cb = _ref[_i];
|
$.set(this.name, this.checked);
|
||||||
cb.call(this, e);
|
return Conf[this.name] = this.checked;
|
||||||
}
|
},
|
||||||
return delete this.callbacks;
|
value: function() {
|
||||||
},
|
$.set(this.name, this.value.trim());
|
||||||
onabort: rm,
|
return Conf[this.name] = this.value;
|
||||||
onerror: rm
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.asap = function(test, cb) {
|
||||||
|
if (test()) {
|
||||||
|
return cb();
|
||||||
|
} else {
|
||||||
|
return setTimeout($.asap, 25, test, cb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addStyle = function(css, id) {
|
||||||
|
var style;
|
||||||
|
|
||||||
|
style = $.el('style', {
|
||||||
|
id: id,
|
||||||
|
textContent: css
|
||||||
|
});
|
||||||
|
$.asap((function() {
|
||||||
|
return d.head;
|
||||||
|
}), function() {
|
||||||
|
return $.add(d.head, style);
|
||||||
|
});
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.x = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.X = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addClass = function(el, className) {
|
||||||
|
return el.classList.add(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rmClass = function(el, className) {
|
||||||
|
return el.classList.remove(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.toggleClass = function(el, className) {
|
||||||
|
return el.classList.toggle(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.hasClass = function(el, className) {
|
||||||
|
return el.classList.contains(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rm = (function() {
|
||||||
|
if ('remove' in Element.prototype) {
|
||||||
|
return function(el) {
|
||||||
|
return el.remove();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function(el) {
|
||||||
|
var _ref;
|
||||||
|
|
||||||
|
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.rmAll = function(root) {
|
||||||
|
var node;
|
||||||
|
|
||||||
|
while (node = root.firstChild) {
|
||||||
|
root.removeChild(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.tn = function(s) {
|
||||||
|
return d.createTextNode(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.frag = function() {
|
||||||
|
return d.createDocumentFragment();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.nodes = function(nodes) {
|
||||||
|
var frag, node, _i, _len;
|
||||||
|
|
||||||
|
if (!(nodes instanceof Array)) {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
frag = $.frag();
|
||||||
|
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
||||||
|
node = nodes[_i];
|
||||||
|
frag.appendChild(node);
|
||||||
|
}
|
||||||
|
return frag;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.add = function(parent, el) {
|
||||||
|
return parent.appendChild($.nodes(el));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.prepend = function(parent, el) {
|
||||||
|
return parent.insertBefore($.nodes(el), parent.firstChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.after = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.before = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.replace = function(root, el) {
|
||||||
|
return root.parentNode.replaceChild($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.el = function(tag, properties) {
|
||||||
|
var el;
|
||||||
|
|
||||||
|
el = d.createElement(tag);
|
||||||
|
if (properties) {
|
||||||
|
$.extend(el, properties);
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.on = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.addEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.off = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.removeEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.event = function(event, detail, root) {
|
||||||
|
if (root == null) {
|
||||||
|
root = d;
|
||||||
|
}
|
||||||
|
return root.dispatchEvent(new CustomEvent(event, {
|
||||||
|
bubbles: true,
|
||||||
|
detail: detail
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.open = (function() {
|
||||||
|
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
||||||
|
return function(URL) {
|
||||||
|
var a;
|
||||||
|
|
||||||
|
a = $.el('a', {
|
||||||
|
href: URL
|
||||||
});
|
});
|
||||||
req.callbacks = [cb];
|
return GM_openInTab(a.href);
|
||||||
return reqs[url] = req;
|
|
||||||
};
|
};
|
||||||
})(),
|
} else {
|
||||||
cb: {
|
return function(URL) {
|
||||||
checked: function() {
|
return window.open(URL, '_blank');
|
||||||
$.set(this.name, this.checked);
|
|
||||||
return Conf[this.name] = this.checked;
|
|
||||||
},
|
|
||||||
value: function() {
|
|
||||||
$.set(this.name, this.value.trim());
|
|
||||||
return Conf[this.name] = this.value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
asap: function(test, cb) {
|
|
||||||
if (test()) {
|
|
||||||
return cb();
|
|
||||||
} else {
|
|
||||||
return setTimeout($.asap, 25, test, cb);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addStyle: function(css, id) {
|
|
||||||
var style;
|
|
||||||
|
|
||||||
style = $.el('style', {
|
|
||||||
id: id,
|
|
||||||
textContent: css
|
|
||||||
});
|
|
||||||
$.asap((function() {
|
|
||||||
return d.head;
|
|
||||||
}), function() {
|
|
||||||
return $.add(d.head, style);
|
|
||||||
});
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
x: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
|
||||||
},
|
|
||||||
X: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
||||||
},
|
|
||||||
addClass: function(el, className) {
|
|
||||||
return el.classList.add(className);
|
|
||||||
},
|
|
||||||
rmClass: function(el, className) {
|
|
||||||
return el.classList.remove(className);
|
|
||||||
},
|
|
||||||
toggleClass: function(el, className) {
|
|
||||||
return el.classList.toggle(className);
|
|
||||||
},
|
|
||||||
hasClass: function(el, className) {
|
|
||||||
return el.classList.contains(className);
|
|
||||||
},
|
|
||||||
rm: (function() {
|
|
||||||
if ('remove' in Element.prototype) {
|
|
||||||
return function(el) {
|
|
||||||
return el.remove();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(el) {
|
|
||||||
var _ref;
|
|
||||||
|
|
||||||
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
rmAll: function(root) {
|
|
||||||
var node;
|
|
||||||
|
|
||||||
while (node = root.firstChild) {
|
|
||||||
root.removeChild(node);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tn: function(s) {
|
|
||||||
return d.createTextNode(s);
|
|
||||||
},
|
|
||||||
frag: function() {
|
|
||||||
return d.createDocumentFragment();
|
|
||||||
},
|
|
||||||
nodes: function(nodes) {
|
|
||||||
var frag, node, _i, _len;
|
|
||||||
|
|
||||||
if (!(nodes instanceof Array)) {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
frag = $.frag();
|
|
||||||
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
|
||||||
node = nodes[_i];
|
|
||||||
frag.appendChild(node);
|
|
||||||
}
|
|
||||||
return frag;
|
|
||||||
},
|
|
||||||
add: function(parent, el) {
|
|
||||||
return parent.appendChild($.nodes(el));
|
|
||||||
},
|
|
||||||
prepend: function(parent, el) {
|
|
||||||
return parent.insertBefore($.nodes(el), parent.firstChild);
|
|
||||||
},
|
|
||||||
after: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
|
||||||
},
|
|
||||||
before: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root);
|
|
||||||
},
|
|
||||||
replace: function(root, el) {
|
|
||||||
return root.parentNode.replaceChild($.nodes(el), root);
|
|
||||||
},
|
|
||||||
el: function(tag, properties) {
|
|
||||||
var el;
|
|
||||||
|
|
||||||
el = d.createElement(tag);
|
|
||||||
if (properties) {
|
|
||||||
$.extend(el, properties);
|
|
||||||
}
|
|
||||||
return el;
|
|
||||||
},
|
|
||||||
on: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.addEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
off: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.removeEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event: function(event, detail, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d;
|
|
||||||
}
|
|
||||||
return root.dispatchEvent(new CustomEvent(event, {
|
|
||||||
bubbles: true,
|
|
||||||
detail: detail
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
open: (function() {
|
|
||||||
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
|
||||||
return function(URL) {
|
|
||||||
var a;
|
|
||||||
|
|
||||||
a = $.el('a', {
|
|
||||||
href: URL
|
|
||||||
});
|
|
||||||
return GM_openInTab(a.href);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(URL) {
|
|
||||||
return window.open(URL, '_blank');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
debounce: function(wait, fn) {
|
|
||||||
var args, exec, that, timeout;
|
|
||||||
|
|
||||||
timeout = null;
|
|
||||||
that = null;
|
|
||||||
args = null;
|
|
||||||
exec = function() {
|
|
||||||
fn.apply(that, args);
|
|
||||||
return timeout = null;
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.debounce = function(wait, fn) {
|
||||||
|
var args, exec, that, timeout;
|
||||||
|
|
||||||
|
timeout = null;
|
||||||
|
that = null;
|
||||||
|
args = null;
|
||||||
|
exec = function() {
|
||||||
|
fn.apply(that, args);
|
||||||
|
return timeout = null;
|
||||||
|
};
|
||||||
|
return function() {
|
||||||
|
args = arguments;
|
||||||
|
that = this;
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
} else {
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
return timeout = setTimeout(exec, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$.queueTask = (function() {
|
||||||
|
var execTask, taskChannel, taskQueue;
|
||||||
|
|
||||||
|
taskQueue = [];
|
||||||
|
execTask = function() {
|
||||||
|
var args, func, task;
|
||||||
|
|
||||||
|
task = taskQueue.shift();
|
||||||
|
func = task[0];
|
||||||
|
args = Array.prototype.slice.call(task, 1);
|
||||||
|
return func.apply(func, args);
|
||||||
|
};
|
||||||
|
if (window.MessageChannel) {
|
||||||
|
taskChannel = new MessageChannel();
|
||||||
|
taskChannel.port1.onmessage = execTask;
|
||||||
return function() {
|
return function() {
|
||||||
args = arguments;
|
taskQueue.push(arguments);
|
||||||
that = this;
|
return taskChannel.port2.postMessage(null);
|
||||||
if (timeout) {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} else {
|
|
||||||
exec();
|
|
||||||
}
|
|
||||||
return timeout = setTimeout(exec, wait);
|
|
||||||
};
|
};
|
||||||
},
|
} else {
|
||||||
queueTask: (function() {
|
return function() {
|
||||||
var execTask, taskChannel, taskQueue;
|
taskQueue.push(arguments);
|
||||||
|
return setTimeout(execTask, 0);
|
||||||
taskQueue = [];
|
|
||||||
execTask = function() {
|
|
||||||
var args, func, task;
|
|
||||||
|
|
||||||
task = taskQueue.shift();
|
|
||||||
func = task[0];
|
|
||||||
args = Array.prototype.slice.call(task, 1);
|
|
||||||
return func.apply(func, args);
|
|
||||||
};
|
};
|
||||||
if (window.MessageChannel) {
|
}
|
||||||
taskChannel = new MessageChannel();
|
})();
|
||||||
taskChannel.port1.onmessage = execTask;
|
|
||||||
return function() {
|
$.globalEval = function(code) {
|
||||||
taskQueue.push(arguments);
|
var script;
|
||||||
return taskChannel.port2.postMessage(null);
|
|
||||||
};
|
script = $.el('script', {
|
||||||
} else {
|
textContent: code
|
||||||
return function() {
|
});
|
||||||
taskQueue.push(arguments);
|
$.add(d.head || doc, script);
|
||||||
return setTimeout(execTask, 0);
|
return $.rm(script);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$.bytesToString = function(size) {
|
||||||
|
var unit;
|
||||||
|
|
||||||
|
unit = 0;
|
||||||
|
while (size >= 1024) {
|
||||||
|
size /= 1024;
|
||||||
|
unit++;
|
||||||
|
}
|
||||||
|
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
||||||
|
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.minmax = function(value, min, max) {
|
||||||
|
return (value < min ? min : value > max ? max : value);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.syncing = {};
|
||||||
|
|
||||||
|
$.sync = (function() {
|
||||||
|
window.addEventListener('storage', function(e) {
|
||||||
|
var cb;
|
||||||
|
|
||||||
|
if (cb = $.syncing[e.key]) {
|
||||||
|
return cb(JSON.parse(e.newValue));
|
||||||
}
|
}
|
||||||
})(),
|
}, false);
|
||||||
globalEval: function(code) {
|
return function(key, cb) {
|
||||||
var script;
|
return $.syncing[g.NAMESPACE + key] = cb;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
script = $.el('script', {
|
$.item = function(key, val) {
|
||||||
textContent: code
|
var item;
|
||||||
});
|
|
||||||
$.add(d.head || doc, script);
|
|
||||||
return $.rm(script);
|
|
||||||
},
|
|
||||||
bytesToString: function(size) {
|
|
||||||
var unit;
|
|
||||||
|
|
||||||
unit = 0;
|
item = {};
|
||||||
while (size >= 1024) {
|
item[key] = val;
|
||||||
size /= 1024;
|
return item;
|
||||||
unit++;
|
};
|
||||||
|
|
||||||
|
$["delete"] = function(keys) {
|
||||||
|
var key, _i, _len;
|
||||||
|
|
||||||
|
if (!(keys instanceof Array)) {
|
||||||
|
keys = [keys];
|
||||||
|
}
|
||||||
|
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
||||||
|
key = keys[_i];
|
||||||
|
key = g.NAMESPACE + key;
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
GM_deleteValue(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.get = function(key, val, cb) {
|
||||||
|
var items;
|
||||||
|
|
||||||
|
if (typeof cb === 'function') {
|
||||||
|
items = $.item(key, val);
|
||||||
|
} else {
|
||||||
|
items = key;
|
||||||
|
cb = val;
|
||||||
|
}
|
||||||
|
return $.queueTask(function() {
|
||||||
|
for (key in items) {
|
||||||
|
if (val = GM_getValue(g.NAMESPACE + key)) {
|
||||||
|
items[key] = JSON.parse(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
return cb(items);
|
||||||
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
});
|
||||||
},
|
};
|
||||||
minmax: function(value, min, max) {
|
|
||||||
return (value < min ? min : value > max ? max : value);
|
|
||||||
},
|
|
||||||
syncing: {},
|
|
||||||
sync: (function() {
|
|
||||||
window.addEventListener('storage', function(e) {
|
|
||||||
var cb;
|
|
||||||
|
|
||||||
if (cb = $.syncing[e.key]) {
|
$.set = (function() {
|
||||||
return cb(JSON.parse(e.newValue));
|
var set;
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
return function(key, cb) {
|
|
||||||
return $.syncing[g.NAMESPACE + key] = cb;
|
|
||||||
};
|
|
||||||
})(),
|
|
||||||
item: function(key, val) {
|
|
||||||
var item;
|
|
||||||
|
|
||||||
item = {};
|
set = function(key, val) {
|
||||||
item[key] = val;
|
key = g.NAMESPACE + key;
|
||||||
return item;
|
val = JSON.stringify(val);
|
||||||
},
|
if (key in $.syncing) {
|
||||||
"delete": function(keys) {
|
localStorage.setItem(key, val);
|
||||||
var key, _i, _len;
|
|
||||||
|
|
||||||
if (!(keys instanceof Array)) {
|
|
||||||
keys = [keys];
|
|
||||||
}
|
}
|
||||||
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
return GM_setValue(key, val);
|
||||||
key = keys[_i];
|
};
|
||||||
key = g.NAMESPACE + key;
|
return function(keys, val) {
|
||||||
localStorage.removeItem(key);
|
var key;
|
||||||
GM_deleteValue(key);
|
|
||||||
|
if (typeof keys === 'string') {
|
||||||
|
set(keys, val);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
},
|
for (key in keys) {
|
||||||
get: function(key, val, cb) {
|
val = keys[key];
|
||||||
var items;
|
set(key, val);
|
||||||
|
|
||||||
if (typeof cb === 'function') {
|
|
||||||
items = $.item(key, val);
|
|
||||||
} else {
|
|
||||||
items = key;
|
|
||||||
cb = val;
|
|
||||||
}
|
}
|
||||||
return $.queueTask(function() {
|
};
|
||||||
for (key in items) {
|
})();
|
||||||
if (val = GM_getValue(g.NAMESPACE + key)) {
|
|
||||||
items[key] = JSON.parse(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cb(items);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
set: (function() {
|
|
||||||
var set;
|
|
||||||
|
|
||||||
set = function(key, val) {
|
$$ = function(selector, root) {
|
||||||
key = g.NAMESPACE + key;
|
if (root == null) {
|
||||||
val = JSON.stringify(val);
|
root = d.body;
|
||||||
if (key in $.syncing) {
|
}
|
||||||
localStorage.setItem(key, val);
|
return __slice.call(root.querySelectorAll(selector));
|
||||||
}
|
};
|
||||||
return GM_setValue(key, val);
|
|
||||||
};
|
|
||||||
return function(keys, val) {
|
|
||||||
var key;
|
|
||||||
|
|
||||||
if (typeof keys === 'string') {
|
|
||||||
set(keys, val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (key in keys) {
|
|
||||||
val = keys[key];
|
|
||||||
set(key, val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})()
|
|
||||||
});
|
|
||||||
|
|
||||||
Build = {
|
Build = {
|
||||||
spoilerRange: {},
|
spoilerRange: {},
|
||||||
|
|||||||
@ -196,6 +196,59 @@
|
|||||||
posts: {}
|
posts: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
String.prototype.capitalize = function() {
|
||||||
|
return this.charAt(0).toUpperCase() + this.slice(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.contains = function(string) {
|
||||||
|
return this.indexOf(string) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.add = function(object, position) {
|
||||||
|
var keep;
|
||||||
|
|
||||||
|
keep = this.slice(position);
|
||||||
|
this.length = position;
|
||||||
|
this.push(object);
|
||||||
|
return this.pushArrays(keep);
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.contains = function(object) {
|
||||||
|
return this.indexOf(object) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.indexOf = function(object) {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
i = this.length;
|
||||||
|
while (i--) {
|
||||||
|
if (this[i] === object) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.pushArrays = function() {
|
||||||
|
var arg, args, _i, _len;
|
||||||
|
|
||||||
|
args = arguments;
|
||||||
|
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
||||||
|
arg = args[_i];
|
||||||
|
this.push.apply(this, arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.remove = function(object) {
|
||||||
|
var index;
|
||||||
|
|
||||||
|
if ((index = this.indexOf(object)) > -1) {
|
||||||
|
return this.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$ = function(selector, root) {
|
$ = function(selector, root) {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = d.body;
|
root = d.body;
|
||||||
@ -203,15 +256,6 @@
|
|||||||
return root.querySelector(selector);
|
return root.querySelector(selector);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
|
||||||
|
|
||||||
$$ = function(selector, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d.body;
|
|
||||||
}
|
|
||||||
return __slice.call(root.querySelectorAll(selector));
|
|
||||||
};
|
|
||||||
|
|
||||||
$.extend = function(object, properties) {
|
$.extend = function(object, properties) {
|
||||||
var key, val;
|
var key, val;
|
||||||
|
|
||||||
@ -224,422 +268,416 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend(Array.prototype, {
|
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
|
||||||
add: function(object, position) {
|
|
||||||
var keep;
|
|
||||||
|
|
||||||
keep = this.slice(position);
|
$.id = function(id) {
|
||||||
this.length = position;
|
return d.getElementById(id);
|
||||||
this.push(object);
|
};
|
||||||
return this.pushArrays(keep);
|
|
||||||
},
|
|
||||||
contains: function(object) {
|
|
||||||
return this.indexOf(object) > -1;
|
|
||||||
},
|
|
||||||
indexOf: function(object) {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
i = this.length;
|
$.ready = function(fc) {
|
||||||
while (i--) {
|
var cb, _ref;
|
||||||
if (this[i] === object) {
|
|
||||||
break;
|
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
||||||
}
|
$.queueTask(fc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cb = function() {
|
||||||
|
$.off(d, 'DOMContentLoaded', cb);
|
||||||
|
return fc();
|
||||||
|
};
|
||||||
|
return $.on(d, 'DOMContentLoaded', cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.formData = function(form) {
|
||||||
|
var fd, key, val;
|
||||||
|
|
||||||
|
if (form instanceof HTMLFormElement) {
|
||||||
|
return new FormData(form);
|
||||||
|
}
|
||||||
|
fd = new FormData();
|
||||||
|
for (key in form) {
|
||||||
|
val = form[key];
|
||||||
|
if (!val) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
return i;
|
if (val.size && val.name) {
|
||||||
},
|
fd.append(key, val, val.name);
|
||||||
pushArrays: function() {
|
|
||||||
var arg, args, _i, _len;
|
|
||||||
|
|
||||||
args = arguments;
|
|
||||||
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
|
||||||
arg = args[_i];
|
|
||||||
this.push.apply(this, arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove: function(object) {
|
|
||||||
var index;
|
|
||||||
|
|
||||||
if ((index = this.indexOf(object)) > -1) {
|
|
||||||
return this.splice(index, 1);
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
fd.append(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
return fd;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend(String.prototype, {
|
$.ajax = function(url, callbacks, opts) {
|
||||||
capitalize: function() {
|
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
||||||
return this.charAt(0).toUpperCase() + this.slice(1);
|
|
||||||
},
|
if (opts == null) {
|
||||||
contains: function(string) {
|
opts = {};
|
||||||
return this.indexOf(string) > -1;
|
|
||||||
}
|
}
|
||||||
});
|
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
||||||
|
r = new XMLHttpRequest();
|
||||||
|
r.overrideMimeType('text/html');
|
||||||
|
type || (type = form && 'post' || 'get');
|
||||||
|
r.open(type, url, !sync);
|
||||||
|
for (key in headers) {
|
||||||
|
val = headers[key];
|
||||||
|
r.setRequestHeader(key, val);
|
||||||
|
}
|
||||||
|
$.extend(r, callbacks);
|
||||||
|
$.extend(r.upload, upCallbacks);
|
||||||
|
r.withCredentials = cred;
|
||||||
|
r.send(form);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
$.extend($, {
|
$.cache = (function() {
|
||||||
id: function(id) {
|
var reqs;
|
||||||
return d.getElementById(id);
|
|
||||||
},
|
|
||||||
ready: function(fc) {
|
|
||||||
var cb, _ref;
|
|
||||||
|
|
||||||
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
|
reqs = {};
|
||||||
$.queueTask(fc);
|
return function(url, cb) {
|
||||||
|
var req, rm;
|
||||||
|
|
||||||
|
if (req = reqs[url]) {
|
||||||
|
if (req.readyState === 4) {
|
||||||
|
cb.call(req);
|
||||||
|
} else {
|
||||||
|
req.callbacks.push(cb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cb = function() {
|
rm = function() {
|
||||||
$.off(d, 'DOMContentLoaded', cb);
|
return delete reqs[url];
|
||||||
return fc();
|
|
||||||
};
|
};
|
||||||
return $.on(d, 'DOMContentLoaded', cb);
|
req = $.ajax(url, {
|
||||||
},
|
onload: function(e) {
|
||||||
formData: function(form) {
|
var _i, _len, _ref;
|
||||||
var fd, key, val;
|
|
||||||
|
|
||||||
if (form instanceof HTMLFormElement) {
|
_ref = this.callbacks;
|
||||||
return new FormData(form);
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
}
|
cb = _ref[_i];
|
||||||
fd = new FormData();
|
cb.call(this, e);
|
||||||
for (key in form) {
|
|
||||||
val = form[key];
|
|
||||||
if (!val) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (val.size && val.name) {
|
|
||||||
fd.append(key, val, val.name);
|
|
||||||
} else {
|
|
||||||
fd.append(key, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
},
|
|
||||||
ajax: function(url, callbacks, opts) {
|
|
||||||
var cred, form, headers, key, r, sync, type, upCallbacks, val;
|
|
||||||
|
|
||||||
if (opts == null) {
|
|
||||||
opts = {};
|
|
||||||
}
|
|
||||||
type = opts.type, cred = opts.cred, headers = opts.headers, upCallbacks = opts.upCallbacks, form = opts.form, sync = opts.sync;
|
|
||||||
r = new XMLHttpRequest();
|
|
||||||
r.overrideMimeType('text/html');
|
|
||||||
type || (type = form && 'post' || 'get');
|
|
||||||
r.open(type, url, !sync);
|
|
||||||
for (key in headers) {
|
|
||||||
val = headers[key];
|
|
||||||
r.setRequestHeader(key, val);
|
|
||||||
}
|
|
||||||
$.extend(r, callbacks);
|
|
||||||
$.extend(r.upload, upCallbacks);
|
|
||||||
r.withCredentials = cred;
|
|
||||||
r.send(form);
|
|
||||||
return r;
|
|
||||||
},
|
|
||||||
cache: (function() {
|
|
||||||
var reqs;
|
|
||||||
|
|
||||||
reqs = {};
|
|
||||||
return function(url, cb) {
|
|
||||||
var req, rm;
|
|
||||||
|
|
||||||
if (req = reqs[url]) {
|
|
||||||
if (req.readyState === 4) {
|
|
||||||
cb.call(req);
|
|
||||||
} else {
|
|
||||||
req.callbacks.push(cb);
|
|
||||||
}
|
}
|
||||||
return;
|
return delete this.callbacks;
|
||||||
}
|
},
|
||||||
rm = function() {
|
onabort: rm,
|
||||||
return delete reqs[url];
|
onerror: rm
|
||||||
};
|
|
||||||
req = $.ajax(url, {
|
|
||||||
onload: function(e) {
|
|
||||||
var _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = this.callbacks;
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
cb = _ref[_i];
|
|
||||||
cb.call(this, e);
|
|
||||||
}
|
|
||||||
return delete this.callbacks;
|
|
||||||
},
|
|
||||||
onabort: rm,
|
|
||||||
onerror: rm
|
|
||||||
});
|
|
||||||
req.callbacks = [cb];
|
|
||||||
return reqs[url] = req;
|
|
||||||
};
|
|
||||||
})(),
|
|
||||||
cb: {
|
|
||||||
checked: function() {
|
|
||||||
$.set(this.name, this.checked);
|
|
||||||
return Conf[this.name] = this.checked;
|
|
||||||
},
|
|
||||||
value: function() {
|
|
||||||
$.set(this.name, this.value.trim());
|
|
||||||
return Conf[this.name] = this.value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
asap: function(test, cb) {
|
|
||||||
if (test()) {
|
|
||||||
return cb();
|
|
||||||
} else {
|
|
||||||
return setTimeout($.asap, 25, test, cb);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addStyle: function(css, id) {
|
|
||||||
var style;
|
|
||||||
|
|
||||||
style = $.el('style', {
|
|
||||||
id: id,
|
|
||||||
textContent: css
|
|
||||||
});
|
});
|
||||||
$.asap((function() {
|
req.callbacks = [cb];
|
||||||
return d.head;
|
return reqs[url] = req;
|
||||||
}), function() {
|
};
|
||||||
return $.add(d.head, style);
|
})();
|
||||||
});
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
x: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
|
||||||
},
|
|
||||||
X: function(path, root) {
|
|
||||||
root || (root = d.body);
|
|
||||||
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
||||||
},
|
|
||||||
addClass: function(el, className) {
|
|
||||||
return el.classList.add(className);
|
|
||||||
},
|
|
||||||
rmClass: function(el, className) {
|
|
||||||
return el.classList.remove(className);
|
|
||||||
},
|
|
||||||
toggleClass: function(el, className) {
|
|
||||||
return el.classList.toggle(className);
|
|
||||||
},
|
|
||||||
hasClass: function(el, className) {
|
|
||||||
return el.classList.contains(className);
|
|
||||||
},
|
|
||||||
rm: (function() {
|
|
||||||
if ('remove' in Element.prototype) {
|
|
||||||
return function(el) {
|
|
||||||
return el.remove();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(el) {
|
|
||||||
var _ref;
|
|
||||||
|
|
||||||
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
$.cb = {
|
||||||
};
|
checked: function() {
|
||||||
}
|
$.set(this.name, this.checked);
|
||||||
})(),
|
return Conf[this.name] = this.checked;
|
||||||
rmAll: function(root) {
|
|
||||||
var node;
|
|
||||||
|
|
||||||
while (node = root.firstChild) {
|
|
||||||
root.removeChild(node);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
tn: function(s) {
|
value: function() {
|
||||||
return d.createTextNode(s);
|
$.set(this.name, this.value.trim());
|
||||||
},
|
return Conf[this.name] = this.value;
|
||||||
frag: function() {
|
|
||||||
return d.createDocumentFragment();
|
|
||||||
},
|
|
||||||
nodes: function(nodes) {
|
|
||||||
var frag, node, _i, _len;
|
|
||||||
|
|
||||||
if (!(nodes instanceof Array)) {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
frag = $.frag();
|
|
||||||
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
|
||||||
node = nodes[_i];
|
|
||||||
frag.appendChild(node);
|
|
||||||
}
|
|
||||||
return frag;
|
|
||||||
},
|
|
||||||
add: function(parent, el) {
|
|
||||||
return parent.appendChild($.nodes(el));
|
|
||||||
},
|
|
||||||
prepend: function(parent, el) {
|
|
||||||
return parent.insertBefore($.nodes(el), parent.firstChild);
|
|
||||||
},
|
|
||||||
after: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
|
||||||
},
|
|
||||||
before: function(root, el) {
|
|
||||||
return root.parentNode.insertBefore($.nodes(el), root);
|
|
||||||
},
|
|
||||||
replace: function(root, el) {
|
|
||||||
return root.parentNode.replaceChild($.nodes(el), root);
|
|
||||||
},
|
|
||||||
el: function(tag, properties) {
|
|
||||||
var el;
|
|
||||||
|
|
||||||
el = d.createElement(tag);
|
|
||||||
if (properties) {
|
|
||||||
$.extend(el, properties);
|
|
||||||
}
|
|
||||||
return el;
|
|
||||||
},
|
|
||||||
on: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.addEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
off: function(el, events, handler) {
|
|
||||||
var event, _i, _len, _ref;
|
|
||||||
|
|
||||||
_ref = events.split(' ');
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
event = _ref[_i];
|
|
||||||
el.removeEventListener(event, handler, false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
event: function(event, detail, root) {
|
|
||||||
if (root == null) {
|
|
||||||
root = d;
|
|
||||||
}
|
|
||||||
return root.dispatchEvent(new CustomEvent(event, {
|
|
||||||
bubbles: true,
|
|
||||||
detail: detail
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
open: (function() {
|
|
||||||
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
|
||||||
return function(URL) {
|
|
||||||
var a;
|
|
||||||
|
|
||||||
a = $.el('a', {
|
|
||||||
href: URL
|
|
||||||
});
|
|
||||||
return GM_openInTab(a.href);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function(URL) {
|
|
||||||
return window.open(URL, '_blank');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
debounce: function(wait, fn) {
|
|
||||||
var args, exec, that, timeout;
|
|
||||||
|
|
||||||
timeout = null;
|
|
||||||
that = null;
|
|
||||||
args = null;
|
|
||||||
exec = function() {
|
|
||||||
fn.apply(that, args);
|
|
||||||
return timeout = null;
|
|
||||||
};
|
|
||||||
return function() {
|
|
||||||
args = arguments;
|
|
||||||
that = this;
|
|
||||||
if (timeout) {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
} else {
|
|
||||||
exec();
|
|
||||||
}
|
|
||||||
return timeout = setTimeout(exec, wait);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
queueTask: (function() {
|
|
||||||
var execTask, taskChannel, taskQueue;
|
|
||||||
|
|
||||||
taskQueue = [];
|
|
||||||
execTask = function() {
|
|
||||||
var args, func, task;
|
|
||||||
|
|
||||||
task = taskQueue.shift();
|
|
||||||
func = task[0];
|
|
||||||
args = Array.prototype.slice.call(task, 1);
|
|
||||||
return func.apply(func, args);
|
|
||||||
};
|
|
||||||
if (window.MessageChannel) {
|
|
||||||
taskChannel = new MessageChannel();
|
|
||||||
taskChannel.port1.onmessage = execTask;
|
|
||||||
return function() {
|
|
||||||
taskQueue.push(arguments);
|
|
||||||
return taskChannel.port2.postMessage(null);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return function() {
|
|
||||||
taskQueue.push(arguments);
|
|
||||||
return setTimeout(execTask, 0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})(),
|
|
||||||
globalEval: function(code) {
|
|
||||||
var script;
|
|
||||||
|
|
||||||
script = $.el('script', {
|
|
||||||
textContent: code
|
|
||||||
});
|
|
||||||
$.add(d.head || doc, script);
|
|
||||||
return $.rm(script);
|
|
||||||
},
|
|
||||||
bytesToString: function(size) {
|
|
||||||
var unit;
|
|
||||||
|
|
||||||
unit = 0;
|
|
||||||
while (size >= 1024) {
|
|
||||||
size /= 1024;
|
|
||||||
unit++;
|
|
||||||
}
|
|
||||||
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
|
||||||
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
|
||||||
},
|
|
||||||
minmax: function(value, min, max) {
|
|
||||||
return (value < min ? min : value > max ? max : value);
|
|
||||||
},
|
|
||||||
syncing: {},
|
|
||||||
sync: (function() {
|
|
||||||
chrome.storage.onChanged.addListener(function(changes) {
|
|
||||||
var cb, key;
|
|
||||||
|
|
||||||
for (key in changes) {
|
|
||||||
if (cb = $.syncing[key]) {
|
|
||||||
cb(changes[key].newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return function(key, cb) {
|
|
||||||
return $.syncing[key] = cb;
|
|
||||||
};
|
|
||||||
})(),
|
|
||||||
item: function(key, val) {
|
|
||||||
var item;
|
|
||||||
|
|
||||||
item = {};
|
|
||||||
item[key] = val;
|
|
||||||
return item;
|
|
||||||
},
|
|
||||||
"delete": function(keys) {
|
|
||||||
return chrome.storage.sync.remove(keys);
|
|
||||||
},
|
|
||||||
get: function(key, val, cb) {
|
|
||||||
var items;
|
|
||||||
|
|
||||||
if (typeof cb === 'function') {
|
|
||||||
items = $.item(key, val);
|
|
||||||
} else {
|
|
||||||
items = key;
|
|
||||||
cb = val;
|
|
||||||
}
|
|
||||||
return chrome.storage.sync.get(items, cb);
|
|
||||||
},
|
|
||||||
set: function(key, val) {
|
|
||||||
var items;
|
|
||||||
|
|
||||||
items = typeof key === 'string' ? $.item(key, val) : key;
|
|
||||||
return chrome.storage.sync.set(items);
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
$.asap = function(test, cb) {
|
||||||
|
if (test()) {
|
||||||
|
return cb();
|
||||||
|
} else {
|
||||||
|
return setTimeout($.asap, 25, test, cb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addStyle = function(css, id) {
|
||||||
|
var style;
|
||||||
|
|
||||||
|
style = $.el('style', {
|
||||||
|
id: id,
|
||||||
|
textContent: css
|
||||||
|
});
|
||||||
|
$.asap((function() {
|
||||||
|
return d.head;
|
||||||
|
}), function() {
|
||||||
|
return $.add(d.head, style);
|
||||||
|
});
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.x = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, 8, null).singleNodeValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.X = function(path, root) {
|
||||||
|
root || (root = d.body);
|
||||||
|
return d.evaluate(path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.addClass = function(el, className) {
|
||||||
|
return el.classList.add(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rmClass = function(el, className) {
|
||||||
|
return el.classList.remove(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.toggleClass = function(el, className) {
|
||||||
|
return el.classList.toggle(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.hasClass = function(el, className) {
|
||||||
|
return el.classList.contains(className);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.rm = (function() {
|
||||||
|
if ('remove' in Element.prototype) {
|
||||||
|
return function(el) {
|
||||||
|
return el.remove();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function(el) {
|
||||||
|
var _ref;
|
||||||
|
|
||||||
|
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.rmAll = function(root) {
|
||||||
|
var node;
|
||||||
|
|
||||||
|
while (node = root.firstChild) {
|
||||||
|
root.removeChild(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.tn = function(s) {
|
||||||
|
return d.createTextNode(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.frag = function() {
|
||||||
|
return d.createDocumentFragment();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.nodes = function(nodes) {
|
||||||
|
var frag, node, _i, _len;
|
||||||
|
|
||||||
|
if (!(nodes instanceof Array)) {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
frag = $.frag();
|
||||||
|
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
||||||
|
node = nodes[_i];
|
||||||
|
frag.appendChild(node);
|
||||||
|
}
|
||||||
|
return frag;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.add = function(parent, el) {
|
||||||
|
return parent.appendChild($.nodes(el));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.prepend = function(parent, el) {
|
||||||
|
return parent.insertBefore($.nodes(el), parent.firstChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.after = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.before = function(root, el) {
|
||||||
|
return root.parentNode.insertBefore($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.replace = function(root, el) {
|
||||||
|
return root.parentNode.replaceChild($.nodes(el), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.el = function(tag, properties) {
|
||||||
|
var el;
|
||||||
|
|
||||||
|
el = d.createElement(tag);
|
||||||
|
if (properties) {
|
||||||
|
$.extend(el, properties);
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.on = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.addEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.off = function(el, events, handler) {
|
||||||
|
var event, _i, _len, _ref;
|
||||||
|
|
||||||
|
_ref = events.split(' ');
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
event = _ref[_i];
|
||||||
|
el.removeEventListener(event, handler, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.event = function(event, detail, root) {
|
||||||
|
if (root == null) {
|
||||||
|
root = d;
|
||||||
|
}
|
||||||
|
return root.dispatchEvent(new CustomEvent(event, {
|
||||||
|
bubbles: true,
|
||||||
|
detail: detail
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
$.open = (function() {
|
||||||
|
if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) {
|
||||||
|
return function(URL) {
|
||||||
|
var a;
|
||||||
|
|
||||||
|
a = $.el('a', {
|
||||||
|
href: URL
|
||||||
|
});
|
||||||
|
return GM_openInTab(a.href);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function(URL) {
|
||||||
|
return window.open(URL, '_blank');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.debounce = function(wait, fn) {
|
||||||
|
var args, exec, that, timeout;
|
||||||
|
|
||||||
|
timeout = null;
|
||||||
|
that = null;
|
||||||
|
args = null;
|
||||||
|
exec = function() {
|
||||||
|
fn.apply(that, args);
|
||||||
|
return timeout = null;
|
||||||
|
};
|
||||||
|
return function() {
|
||||||
|
args = arguments;
|
||||||
|
that = this;
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
} else {
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
return timeout = setTimeout(exec, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$.queueTask = (function() {
|
||||||
|
var execTask, taskChannel, taskQueue;
|
||||||
|
|
||||||
|
taskQueue = [];
|
||||||
|
execTask = function() {
|
||||||
|
var args, func, task;
|
||||||
|
|
||||||
|
task = taskQueue.shift();
|
||||||
|
func = task[0];
|
||||||
|
args = Array.prototype.slice.call(task, 1);
|
||||||
|
return func.apply(func, args);
|
||||||
|
};
|
||||||
|
if (window.MessageChannel) {
|
||||||
|
taskChannel = new MessageChannel();
|
||||||
|
taskChannel.port1.onmessage = execTask;
|
||||||
|
return function() {
|
||||||
|
taskQueue.push(arguments);
|
||||||
|
return taskChannel.port2.postMessage(null);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return function() {
|
||||||
|
taskQueue.push(arguments);
|
||||||
|
return setTimeout(execTask, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.globalEval = function(code) {
|
||||||
|
var script;
|
||||||
|
|
||||||
|
script = $.el('script', {
|
||||||
|
textContent: code
|
||||||
|
});
|
||||||
|
$.add(d.head || doc, script);
|
||||||
|
return $.rm(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.bytesToString = function(size) {
|
||||||
|
var unit;
|
||||||
|
|
||||||
|
unit = 0;
|
||||||
|
while (size >= 1024) {
|
||||||
|
size /= 1024;
|
||||||
|
unit++;
|
||||||
|
}
|
||||||
|
size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size);
|
||||||
|
return "" + size + " " + ['B', 'KB', 'MB', 'GB'][unit];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.minmax = function(value, min, max) {
|
||||||
|
return (value < min ? min : value > max ? max : value);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.syncing = {};
|
||||||
|
|
||||||
|
$.sync = (function() {
|
||||||
|
chrome.storage.onChanged.addListener(function(changes) {
|
||||||
|
var cb, key;
|
||||||
|
|
||||||
|
for (key in changes) {
|
||||||
|
if (cb = $.syncing[key]) {
|
||||||
|
cb(changes[key].newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return function(key, cb) {
|
||||||
|
return $.syncing[key] = cb;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.item = function(key, val) {
|
||||||
|
var item;
|
||||||
|
|
||||||
|
item = {};
|
||||||
|
item[key] = val;
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
$["delete"] = function(keys) {
|
||||||
|
return chrome.storage.sync.remove(keys);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.get = function(key, val, cb) {
|
||||||
|
var items;
|
||||||
|
|
||||||
|
if (typeof cb === 'function') {
|
||||||
|
items = $.item(key, val);
|
||||||
|
} else {
|
||||||
|
items = key;
|
||||||
|
cb = val;
|
||||||
|
}
|
||||||
|
return chrome.storage.sync.get(items, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.set = function(key, val) {
|
||||||
|
var items;
|
||||||
|
|
||||||
|
items = typeof key === 'string' ? $.item(key, val) : key;
|
||||||
|
return chrome.storage.sync.set(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
$$ = function(selector, root) {
|
||||||
|
if (root == null) {
|
||||||
|
root = d.body;
|
||||||
|
}
|
||||||
|
return __slice.call(root.querySelectorAll(selector));
|
||||||
|
};
|
||||||
|
|
||||||
Build = {
|
Build = {
|
||||||
spoilerRange: {},
|
spoilerRange: {},
|
||||||
|
|||||||
717
src/lib/$.coffee
717
src/lib/$.coffee
@ -1,302 +1,335 @@
|
|||||||
|
String::capitalize = ->
|
||||||
|
@charAt(0).toUpperCase() + @slice(1);
|
||||||
|
|
||||||
|
String::contains = (string) ->
|
||||||
|
@indexOf(string) > -1
|
||||||
|
|
||||||
|
Array::add = (object, position) ->
|
||||||
|
keep = @slice position
|
||||||
|
@length = position
|
||||||
|
@push object
|
||||||
|
@pushArrays keep
|
||||||
|
|
||||||
|
Array::contains = (object) ->
|
||||||
|
@indexOf(object) > -1
|
||||||
|
|
||||||
|
Array::indexOf = (object) ->
|
||||||
|
i = @length
|
||||||
|
while i--
|
||||||
|
break if @[i] is object
|
||||||
|
return i
|
||||||
|
|
||||||
|
Array::pushArrays = ->
|
||||||
|
args = arguments
|
||||||
|
for arg in args
|
||||||
|
@push.apply @, arg
|
||||||
|
return
|
||||||
|
|
||||||
|
Array::remove = (object) ->
|
||||||
|
if (index = @indexOf object) > -1
|
||||||
|
@splice index, 1
|
||||||
|
else
|
||||||
|
false
|
||||||
|
|
||||||
# loosely follows the jquery api:
|
# loosely follows the jquery api:
|
||||||
# http://api.jquery.com/
|
# http://api.jquery.com/
|
||||||
# not chainable
|
# not chainable
|
||||||
$ = (selector, root=d.body) ->
|
$ = (selector, root=d.body) ->
|
||||||
root.querySelector selector
|
root.querySelector selector
|
||||||
|
|
||||||
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)))
|
|
||||||
|
|
||||||
$$ = (selector, root=d.body) ->
|
|
||||||
[root.querySelectorAll(selector)...]
|
|
||||||
|
|
||||||
$.extend = (object, properties) ->
|
$.extend = (object, properties) ->
|
||||||
for key, val of properties
|
for key, val of properties
|
||||||
continue unless properties.hasOwnProperty key
|
continue unless properties.hasOwnProperty key
|
||||||
object[key] = val
|
object[key] = val
|
||||||
return
|
return
|
||||||
|
|
||||||
# Various prototypes I've wanted or needed to add.
|
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)))
|
||||||
$.extend Array::,
|
|
||||||
add: (object, position) ->
|
|
||||||
keep = @slice position
|
|
||||||
@length = position
|
|
||||||
@push object
|
|
||||||
@pushArrays keep
|
|
||||||
|
|
||||||
contains: (object) ->
|
$.id = (id) ->
|
||||||
@indexOf(object) > -1
|
d.getElementById id
|
||||||
|
|
||||||
indexOf: (object) ->
|
$.ready = (fc) ->
|
||||||
i = @length
|
if d.readyState in ['interactive', 'complete']
|
||||||
while i--
|
$.queueTask fc
|
||||||
break if @[i] is object
|
|
||||||
return i
|
|
||||||
|
|
||||||
pushArrays: ->
|
|
||||||
args = arguments
|
|
||||||
for arg in args
|
|
||||||
@push.apply @, arg
|
|
||||||
return
|
return
|
||||||
|
cb = ->
|
||||||
remove: (object) ->
|
$.off d, 'DOMContentLoaded', cb
|
||||||
if (index = @indexOf object) > -1
|
fc()
|
||||||
@splice index, 1
|
$.on d, 'DOMContentLoaded', cb
|
||||||
|
|
||||||
|
$.formData = (form) ->
|
||||||
|
if form instanceof HTMLFormElement
|
||||||
|
return new FormData form
|
||||||
|
fd = new FormData()
|
||||||
|
for key, val of form
|
||||||
|
continue unless val
|
||||||
|
# XXX GM bug
|
||||||
|
# if val instanceof Blob
|
||||||
|
if val.size and val.name
|
||||||
|
fd.append key, val, val.name
|
||||||
else
|
else
|
||||||
false
|
fd.append key, val
|
||||||
|
fd
|
||||||
$.extend String::,
|
|
||||||
capitalize: ->
|
$.ajax = (url, callbacks, opts={}) ->
|
||||||
@charAt(0).toUpperCase() + @slice(1);
|
{type, cred, headers, upCallbacks, form, sync} = opts
|
||||||
|
r = new XMLHttpRequest()
|
||||||
contains: (string) ->
|
r.overrideMimeType 'text/html'
|
||||||
@indexOf(string) > -1
|
type or= form and 'post' or 'get'
|
||||||
|
r.open type, url, !sync
|
||||||
$.extend $,
|
for key, val of headers
|
||||||
id: (id) ->
|
r.setRequestHeader key, val
|
||||||
d.getElementById id
|
$.extend r, callbacks
|
||||||
ready: (fc) ->
|
$.extend r.upload, upCallbacks
|
||||||
if d.readyState in ['interactive', 'complete']
|
r.withCredentials = cred
|
||||||
$.queueTask fc
|
r.send form
|
||||||
return
|
r
|
||||||
cb = ->
|
|
||||||
$.off d, 'DOMContentLoaded', cb
|
$.cache = do ->
|
||||||
fc()
|
reqs = {}
|
||||||
$.on d, 'DOMContentLoaded', cb
|
(url, cb) ->
|
||||||
formData: (form) ->
|
if req = reqs[url]
|
||||||
if form instanceof HTMLFormElement
|
if req.readyState is 4
|
||||||
return new FormData form
|
cb.call req
|
||||||
fd = new FormData()
|
|
||||||
for key, val of form
|
|
||||||
continue unless val
|
|
||||||
# XXX GM bug
|
|
||||||
# if val instanceof Blob
|
|
||||||
if val.size and val.name
|
|
||||||
fd.append key, val, val.name
|
|
||||||
else
|
else
|
||||||
fd.append key, val
|
req.callbacks.push cb
|
||||||
fd
|
return
|
||||||
ajax: (url, callbacks, opts={}) ->
|
rm = -> delete reqs[url]
|
||||||
{type, cred, headers, upCallbacks, form, sync} = opts
|
req = $.ajax url,
|
||||||
r = new XMLHttpRequest()
|
onload: (e) ->
|
||||||
r.overrideMimeType 'text/html'
|
cb.call @, e for cb in @callbacks
|
||||||
type or= form and 'post' or 'get'
|
delete @callbacks
|
||||||
r.open type, url, !sync
|
onabort: rm
|
||||||
for key, val of headers
|
onerror: rm
|
||||||
r.setRequestHeader key, val
|
req.callbacks = [cb]
|
||||||
$.extend r, callbacks
|
reqs[url] = req
|
||||||
$.extend r.upload, upCallbacks
|
|
||||||
r.withCredentials = cred
|
$.cb =
|
||||||
r.send form
|
checked: ->
|
||||||
r
|
$.set @name, @checked
|
||||||
cache: do ->
|
Conf[@name] = @checked
|
||||||
reqs = {}
|
value: ->
|
||||||
(url, cb) ->
|
$.set @name, @value.trim()
|
||||||
if req = reqs[url]
|
Conf[@name] = @value
|
||||||
if req.readyState is 4
|
|
||||||
cb.call req
|
$.asap = (test, cb) ->
|
||||||
else
|
if test()
|
||||||
req.callbacks.push cb
|
cb()
|
||||||
return
|
else
|
||||||
rm = -> delete reqs[url]
|
setTimeout $.asap, 25, test, cb
|
||||||
req = $.ajax url,
|
|
||||||
onload: (e) ->
|
$.addStyle = (css, id) ->
|
||||||
cb.call @, e for cb in @callbacks
|
style = $.el 'style',
|
||||||
delete @callbacks
|
id: id
|
||||||
onabort: rm
|
textContent: css
|
||||||
onerror: rm
|
$.asap (-> d.head), ->
|
||||||
req.callbacks = [cb]
|
$.add d.head, style
|
||||||
reqs[url] = req
|
style
|
||||||
cb:
|
|
||||||
checked: ->
|
$.x = (path, root) ->
|
||||||
$.set @name, @checked
|
root or= d.body
|
||||||
Conf[@name] = @checked
|
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
|
||||||
value: ->
|
d.evaluate(path, root, null, 8, null).singleNodeValue
|
||||||
$.set @name, @value.trim()
|
|
||||||
Conf[@name] = @value
|
$.X = (path, root) ->
|
||||||
asap: (test, cb) ->
|
root or= d.body
|
||||||
if test()
|
d.evaluate path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null
|
||||||
cb()
|
|
||||||
else
|
$.addClass = (el, className) ->
|
||||||
setTimeout $.asap, 25, test, cb
|
el.classList.add className
|
||||||
addStyle: (css, id) ->
|
|
||||||
style = $.el 'style',
|
$.rmClass = (el, className) ->
|
||||||
id: id
|
el.classList.remove className
|
||||||
textContent: css
|
|
||||||
$.asap (-> d.head), ->
|
$.toggleClass = (el, className) ->
|
||||||
$.add d.head, style
|
el.classList.toggle className
|
||||||
style
|
|
||||||
x: (path, root) ->
|
$.hasClass = (el, className) ->
|
||||||
root or= d.body
|
el.classList.contains className
|
||||||
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
|
|
||||||
d.evaluate(path, root, null, 8, null).singleNodeValue
|
$.rm = do ->
|
||||||
X: (path, root) ->
|
if 'remove' of Element.prototype
|
||||||
root or= d.body
|
(el) -> el.remove()
|
||||||
d.evaluate path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null
|
else
|
||||||
addClass: (el, className) ->
|
(el) -> el.parentNode?.removeChild el
|
||||||
el.classList.add className
|
|
||||||
rmClass: (el, className) ->
|
$.rmAll = (root) ->
|
||||||
el.classList.remove className
|
# jsperf.com/emptify-element
|
||||||
toggleClass: (el, className) ->
|
while node = root.firstChild
|
||||||
el.classList.toggle className
|
# HTMLSelectElement.remove !== Element.remove
|
||||||
hasClass: (el, className) ->
|
root.removeChild node
|
||||||
el.classList.contains className
|
return
|
||||||
rm: do ->
|
|
||||||
if 'remove' of Element.prototype
|
$.tn = (s) ->
|
||||||
(el) -> el.remove()
|
d.createTextNode s
|
||||||
else
|
|
||||||
(el) -> el.parentNode?.removeChild el
|
$.frag = ->
|
||||||
rmAll: (root) ->
|
d.createDocumentFragment()
|
||||||
# jsperf.com/emptify-element
|
|
||||||
while node = root.firstChild
|
$.nodes = (nodes) ->
|
||||||
# HTMLSelectElement.remove !== Element.remove
|
unless nodes instanceof Array
|
||||||
root.removeChild node
|
return nodes
|
||||||
return
|
frag = $.frag()
|
||||||
tn: (s) ->
|
for node in nodes
|
||||||
d.createTextNode s
|
frag.appendChild node
|
||||||
frag: ->
|
frag
|
||||||
d.createDocumentFragment()
|
|
||||||
nodes: (nodes) ->
|
$.add = (parent, el) ->
|
||||||
unless nodes instanceof Array
|
parent.appendChild $.nodes el
|
||||||
return nodes
|
|
||||||
frag = $.frag()
|
$.prepend = (parent, el) ->
|
||||||
for node in nodes
|
parent.insertBefore $.nodes(el), parent.firstChild
|
||||||
frag.appendChild node
|
|
||||||
frag
|
$.after = (root, el) ->
|
||||||
add: (parent, el) ->
|
root.parentNode.insertBefore $.nodes(el), root.nextSibling
|
||||||
parent.appendChild $.nodes el
|
|
||||||
prepend: (parent, el) ->
|
$.before = (root, el) ->
|
||||||
parent.insertBefore $.nodes(el), parent.firstChild
|
root.parentNode.insertBefore $.nodes(el), root
|
||||||
after: (root, el) ->
|
|
||||||
root.parentNode.insertBefore $.nodes(el), root.nextSibling
|
$.replace = (root, el) ->
|
||||||
before: (root, el) ->
|
root.parentNode.replaceChild $.nodes(el), root
|
||||||
root.parentNode.insertBefore $.nodes(el), root
|
|
||||||
replace: (root, el) ->
|
$.el = (tag, properties) ->
|
||||||
root.parentNode.replaceChild $.nodes(el), root
|
el = d.createElement tag
|
||||||
el: (tag, properties) ->
|
$.extend el, properties if properties
|
||||||
el = d.createElement tag
|
el
|
||||||
$.extend el, properties if properties
|
|
||||||
el
|
$.on = (el, events, handler) ->
|
||||||
on: (el, events, handler) ->
|
for event in events.split ' '
|
||||||
for event in events.split ' '
|
el.addEventListener event, handler, false
|
||||||
el.addEventListener event, handler, false
|
return
|
||||||
return
|
|
||||||
off: (el, events, handler) ->
|
$.off = (el, events, handler) ->
|
||||||
for event in events.split ' '
|
for event in events.split ' '
|
||||||
el.removeEventListener event, handler, false
|
el.removeEventListener event, handler, false
|
||||||
return
|
return
|
||||||
event: (event, detail, root=d) ->
|
|
||||||
root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
|
$.event = (event, detail, root=d) ->
|
||||||
open: do ->
|
root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
|
||||||
if GM_openInTab?
|
|
||||||
(URL) ->
|
$.open = do ->
|
||||||
# XXX fix GM opening file://// for protocol-less URLs.
|
if GM_openInTab?
|
||||||
a = $.el 'a', href: URL
|
(URL) ->
|
||||||
GM_openInTab a.href
|
# XXX fix GM opening file://// for protocol-less URLs.
|
||||||
else
|
a = $.el 'a', href: URL
|
||||||
(URL) -> window.open URL, '_blank'
|
GM_openInTab a.href
|
||||||
debounce: (wait, fn) ->
|
else
|
||||||
|
(URL) -> window.open URL, '_blank'
|
||||||
|
|
||||||
|
$.debounce = (wait, fn) ->
|
||||||
|
timeout = null
|
||||||
|
that = null
|
||||||
|
args = null
|
||||||
|
exec = ->
|
||||||
|
fn.apply that, args
|
||||||
timeout = null
|
timeout = null
|
||||||
that = null
|
->
|
||||||
args = null
|
args = arguments
|
||||||
exec = ->
|
that = this
|
||||||
fn.apply that, args
|
if timeout
|
||||||
timeout = null
|
# stop current reset
|
||||||
->
|
clearTimeout timeout
|
||||||
args = arguments
|
else
|
||||||
that = this
|
exec()
|
||||||
if timeout
|
|
||||||
# stop current reset
|
|
||||||
clearTimeout timeout
|
|
||||||
else
|
|
||||||
exec()
|
|
||||||
|
|
||||||
# after wait, let next invocation execute immediately
|
# after wait, let next invocation execute immediately
|
||||||
timeout = setTimeout exec, wait
|
timeout = setTimeout exec, wait
|
||||||
queueTask: do ->
|
|
||||||
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
|
$.queueTask = do ->
|
||||||
taskQueue = []
|
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
|
||||||
execTask = ->
|
taskQueue = []
|
||||||
task = taskQueue.shift()
|
execTask = ->
|
||||||
func = task[0]
|
task = taskQueue.shift()
|
||||||
args = Array::slice.call task, 1
|
func = task[0]
|
||||||
func.apply func, args
|
args = Array::slice.call task, 1
|
||||||
if window.MessageChannel
|
func.apply func, args
|
||||||
taskChannel = new MessageChannel()
|
if window.MessageChannel
|
||||||
taskChannel.port1.onmessage = execTask
|
taskChannel = new MessageChannel()
|
||||||
->
|
taskChannel.port1.onmessage = execTask
|
||||||
taskQueue.push arguments
|
->
|
||||||
taskChannel.port2.postMessage null
|
taskQueue.push arguments
|
||||||
else # XXX Firefox
|
taskChannel.port2.postMessage null
|
||||||
->
|
else # XXX Firefox
|
||||||
taskQueue.push arguments
|
->
|
||||||
setTimeout execTask, 0
|
taskQueue.push arguments
|
||||||
globalEval: (code) ->
|
setTimeout execTask, 0
|
||||||
script = $.el 'script',
|
|
||||||
textContent: code
|
$.globalEval = (code) ->
|
||||||
$.add (d.head or doc), script
|
script = $.el 'script',
|
||||||
$.rm script
|
textContent: code
|
||||||
bytesToString: (size) ->
|
$.add (d.head or doc), script
|
||||||
unit = 0 # Bytes
|
$.rm script
|
||||||
while size >= 1024
|
|
||||||
size /= 1024
|
$.bytesToString = (size) ->
|
||||||
unit++
|
unit = 0 # Bytes
|
||||||
# Remove trailing 0s.
|
while size >= 1024
|
||||||
size =
|
size /= 1024
|
||||||
if unit > 1
|
unit++
|
||||||
# Keep the size as a float if the size is greater than 2^20 B.
|
# Remove trailing 0s.
|
||||||
# Round to hundredth.
|
size =
|
||||||
Math.round(size * 100) / 100
|
if unit > 1
|
||||||
|
# Keep the size as a float if the size is greater than 2^20 B.
|
||||||
|
# Round to hundredth.
|
||||||
|
Math.round(size * 100) / 100
|
||||||
|
else
|
||||||
|
# Round to an integer otherwise.
|
||||||
|
Math.round size
|
||||||
|
"#{size} #{['B', 'KB', 'MB', 'GB'][unit]}"
|
||||||
|
|
||||||
|
$.minmax = (value, min, max) ->
|
||||||
|
return (
|
||||||
|
if value < min
|
||||||
|
min
|
||||||
|
else
|
||||||
|
if value > max
|
||||||
|
max
|
||||||
else
|
else
|
||||||
# Round to an integer otherwise.
|
value
|
||||||
Math.round size
|
|
||||||
"#{size} #{['B', 'KB', 'MB', 'GB'][unit]}"
|
|
||||||
minmax: (value, min, max) ->
|
|
||||||
return (
|
|
||||||
if value < min
|
|
||||||
min
|
|
||||||
else
|
|
||||||
if value > max
|
|
||||||
max
|
|
||||||
else
|
|
||||||
value
|
|
||||||
)
|
)
|
||||||
syncing: {}
|
|
||||||
sync: do ->
|
$.syncing = {}
|
||||||
|
|
||||||
|
$.sync = do ->
|
||||||
<% if (type === 'crx') { %>
|
<% if (type === 'crx') { %>
|
||||||
chrome.storage.onChanged.addListener (changes) ->
|
chrome.storage.onChanged.addListener (changes) ->
|
||||||
for key of changes
|
for key of changes
|
||||||
if cb = $.syncing[key]
|
if cb = $.syncing[key]
|
||||||
cb changes[key].newValue
|
cb changes[key].newValue
|
||||||
return
|
return
|
||||||
(key, cb) -> $.syncing[key] = cb
|
(key, cb) -> $.syncing[key] = cb
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
window.addEventListener 'storage', (e) ->
|
window.addEventListener 'storage', (e) ->
|
||||||
if cb = $.syncing[e.key]
|
if cb = $.syncing[e.key]
|
||||||
cb JSON.parse e.newValue
|
cb JSON.parse e.newValue
|
||||||
, false
|
, false
|
||||||
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
|
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
|
||||||
<% } %>
|
<% } %>
|
||||||
item: (key, val) ->
|
|
||||||
item = {}
|
$.item = (key, val) ->
|
||||||
item[key] = val
|
item = {}
|
||||||
item
|
item[key] = val
|
||||||
|
item
|
||||||
<% if (type === 'crx') { %>
|
<% if (type === 'crx') { %>
|
||||||
# https://developer.chrome.com/extensions/storage.html
|
# https://developer.chrome.com/extensions/storage.html
|
||||||
delete: (keys) ->
|
|
||||||
chrome.storage.sync.remove keys
|
$.delete = (keys) ->
|
||||||
get: (key, val, cb) ->
|
chrome.storage.sync.remove keys
|
||||||
if typeof cb is 'function'
|
|
||||||
items = $.item key, val
|
$.get = (key, val, cb) ->
|
||||||
else
|
if typeof cb is 'function'
|
||||||
items = key
|
items = $.item key, val
|
||||||
cb = val
|
else
|
||||||
chrome.storage.sync.get items, cb
|
items = key
|
||||||
set: (key, val) ->
|
cb = val
|
||||||
items = if typeof key is 'string'
|
chrome.storage.sync.get items, cb
|
||||||
$.item key, val
|
|
||||||
else
|
$.set = (key, val) ->
|
||||||
key
|
items = if typeof key is 'string'
|
||||||
chrome.storage.sync.set items
|
$.item key, val
|
||||||
|
else
|
||||||
|
key
|
||||||
|
chrome.storage.sync.set items
|
||||||
|
|
||||||
<% } else if (type === 'userjs') { %>
|
<% } else if (type === 'userjs') { %>
|
||||||
do ->
|
do ->
|
||||||
# http://www.opera.com/docs/userjs/specs/#scriptstorage
|
# http://www.opera.com/docs/userjs/specs/#scriptstorage
|
||||||
@ -308,73 +341,79 @@ do ->
|
|||||||
# to the object.
|
# to the object.
|
||||||
{scriptStorage} = opera
|
{scriptStorage} = opera
|
||||||
$.delete = (keys) ->
|
$.delete = (keys) ->
|
||||||
unless keys instanceof Array
|
unless keys instanceof Array
|
||||||
keys = [keys]
|
keys = [keys]
|
||||||
for key in keys
|
for key in keys
|
||||||
key = g.NAMESPACE + key
|
key = g.NAMESPACE + key
|
||||||
localStorage.removeItem key
|
localStorage.removeItem key
|
||||||
delete scriptStorage[key]
|
delete scriptStorage[key]
|
||||||
return
|
return
|
||||||
$.get = (key, val, cb) ->
|
$.get = (key, val, cb) ->
|
||||||
if typeof cb is 'function'
|
if typeof cb is 'function'
|
||||||
items = $.item key, val
|
items = $.item key, val
|
||||||
else
|
else
|
||||||
items = key
|
items = key
|
||||||
cb = val
|
cb = val
|
||||||
$.queueTask ->
|
$.queueTask ->
|
||||||
for key of items
|
for key of items
|
||||||
if val = scriptStorage[g.NAMESPACE + key]
|
if val = scriptStorage[g.NAMESPACE + key]
|
||||||
items[key] = JSON.parse val
|
items[key] = JSON.parse val
|
||||||
cb items
|
cb items
|
||||||
$.set = do ->
|
$.set = do ->
|
||||||
set = (key, val) ->
|
set = (key, val) ->
|
||||||
key = g.NAMESPACE + key
|
key = g.NAMESPACE + key
|
||||||
val = JSON.stringify val
|
val = JSON.stringify val
|
||||||
if key of $.syncing
|
if key of $.syncing
|
||||||
# for `storage` events
|
# for `storage` events
|
||||||
localStorage.setItem key, val
|
localStorage.setItem key, val
|
||||||
scriptStorage[key] = val
|
scriptStorage[key] = val
|
||||||
(keys, val) ->
|
(keys, val) ->
|
||||||
if typeof keys is 'string'
|
if typeof keys is 'string'
|
||||||
set keys, val
|
set keys, val
|
||||||
return
|
|
||||||
for key, val of keys
|
|
||||||
set key, val
|
|
||||||
return
|
return
|
||||||
<% } else { %>
|
for key, val of keys
|
||||||
# http://wiki.greasespot.net/Main_Page
|
set key, val
|
||||||
delete: (keys) ->
|
|
||||||
unless keys instanceof Array
|
|
||||||
keys = [keys]
|
|
||||||
for key in keys
|
|
||||||
key = g.NAMESPACE + key
|
|
||||||
localStorage.removeItem key
|
|
||||||
GM_deleteValue key
|
|
||||||
return
|
return
|
||||||
get: (key, val, cb) ->
|
<% } else { %>
|
||||||
if typeof cb is 'function'
|
|
||||||
items = $.item key, val
|
# http://wiki.greasespot.net/Main_Page
|
||||||
else
|
$.delete = (keys) ->
|
||||||
items = key
|
unless keys instanceof Array
|
||||||
cb = val
|
keys = [keys]
|
||||||
$.queueTask ->
|
for key in keys
|
||||||
for key of items
|
key = g.NAMESPACE + key
|
||||||
if val = GM_getValue g.NAMESPACE + key
|
localStorage.removeItem key
|
||||||
items[key] = JSON.parse val
|
GM_deleteValue key
|
||||||
cb items
|
return
|
||||||
set: do ->
|
|
||||||
set = (key, val) ->
|
$.get = (key, val, cb) ->
|
||||||
key = g.NAMESPACE + key
|
if typeof cb is 'function'
|
||||||
val = JSON.stringify val
|
items = $.item key, val
|
||||||
if key of $.syncing
|
else
|
||||||
# for `storage` events
|
items = key
|
||||||
localStorage.setItem key, val
|
cb = val
|
||||||
GM_setValue key, val
|
$.queueTask ->
|
||||||
(keys, val) ->
|
for key of items
|
||||||
if typeof keys is 'string'
|
if val = GM_getValue g.NAMESPACE + key
|
||||||
set keys, val
|
items[key] = JSON.parse val
|
||||||
return
|
cb items
|
||||||
for key, val of keys
|
|
||||||
set key, val
|
$.set = do ->
|
||||||
|
set = (key, val) ->
|
||||||
|
key = g.NAMESPACE + key
|
||||||
|
val = JSON.stringify val
|
||||||
|
if key of $.syncing
|
||||||
|
# for `storage` events
|
||||||
|
localStorage.setItem key, val
|
||||||
|
GM_setValue key, val
|
||||||
|
(keys, val) ->
|
||||||
|
if typeof keys is 'string'
|
||||||
|
set keys, val
|
||||||
return
|
return
|
||||||
|
for key, val of keys
|
||||||
|
set key, val
|
||||||
|
return
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
$$ = (selector, root=d.body) ->
|
||||||
|
[root.querySelectorAll(selector)...]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user