Merge branch 'v3' of git://github.com/MayhemYDG/4chan-x into v3

Conflicts:
	src/features.coffee
	src/lib/$.coffee
This commit is contained in:
Zixaphir 2013-04-24 17:06:20 -07:00
commit 128a5ef40f
4 changed files with 1757 additions and 1609 deletions

View File

@ -299,6 +299,59 @@
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) {
if (root == null) {
root = d.body;
@ -306,15 +359,6 @@
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) {
var key, val;
@ -327,462 +371,451 @@
}
};
$.extend(Array.prototype, {
add: function(object, position) {
var keep;
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
keep = this.slice(position);
this.length = position;
this.push(object);
return this.pushArrays(keep);
},
contains: function(object) {
return this.indexOf(object) > -1;
},
indexOf: function(object) {
var i;
$.id = function(id) {
return d.getElementById(id);
};
i = this.length;
while (i--) {
if (this[i] === object) {
break;
}
$.ready = function(fc) {
var cb, _ref;
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;
},
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);
if (val.size && val.name) {
fd.append(key, val, val.name);
} else {
return false;
fd.append(key, val);
}
}
});
return fd;
};
$.extend(String.prototype, {
capitalize: function() {
return this.charAt(0).toUpperCase() + this.slice(1);
},
contains: function(string) {
return this.indexOf(string) > -1;
$.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;
};
$.extend($, {
id: function(id) {
return d.getElementById(id);
},
ready: function(fc) {
var cb, _ref;
$.cache = (function() {
var reqs;
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
$.queueTask(fc);
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;
}
cb = function() {
$.off(d, 'DOMContentLoaded', cb);
return fc();
rm = function() {
return delete reqs[url];
};
return $.on(d, 'DOMContentLoaded', cb);
},
formData: function(form) {
var fd, key, val;
req = $.ajax(url, {
onload: function(e) {
var _i, _len, _ref;
if (form instanceof HTMLFormElement) {
return new FormData(form);
}
fd = new FormData();
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);
_ref = this.callbacks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
cb.call(this, e);
}
return;
}
rm = function() {
return delete reqs[url];
};
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
return delete this.callbacks;
},
onabort: rm,
onerror: rm
});
$.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;
req.callbacks = [cb];
return reqs[url] = req;
};
})();
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
};
}
})(),
rmAll: function(root) {
var node;
while (node = root.firstChild) {
root.removeChild(node);
}
$.cb = {
checked: function() {
$.set(this.name, this.checked);
return Conf[this.name] = this.checked;
},
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;
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;
};
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() {
var scriptStorage;
var cb, items, key, keys, scriptStorage, _i, _len;
scriptStorage = opera.scriptStorage;
$["delete"] = function(keys) {
var key, _i, _len;
$["delete"] = function(keys) {};
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)) {
keys = [keys];
for (key in items) {
if (val = scriptStorage[g.NAMESPACE + key]) {
items[key] = JSON.parse(val);
}
}
for (_i = 0, _len = keys.length; _i < _len; _i++) {
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);
}
};
})();
return cb(items);
});
})();
$.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 = {
spoilerRange: {},
shortFilename: function(filename, isReply) {

View File

@ -296,6 +296,59 @@
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) {
if (root == null) {
root = d.body;
@ -303,15 +356,6 @@
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) {
var key, val;
@ -324,455 +368,449 @@
}
};
$.extend(Array.prototype, {
add: function(object, position) {
var keep;
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
keep = this.slice(position);
this.length = position;
this.push(object);
return this.pushArrays(keep);
},
contains: function(object) {
return this.indexOf(object) > -1;
},
indexOf: function(object) {
var i;
$.id = function(id) {
return d.getElementById(id);
};
i = this.length;
while (i--) {
if (this[i] === object) {
break;
}
$.ready = function(fc) {
var cb, _ref;
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;
},
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);
if (val.size && val.name) {
fd.append(key, val, val.name);
} else {
return false;
fd.append(key, val);
}
}
});
return fd;
};
$.extend(String.prototype, {
capitalize: function() {
return this.charAt(0).toUpperCase() + this.slice(1);
},
contains: function(string) {
return this.indexOf(string) > -1;
$.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;
};
$.extend($, {
id: function(id) {
return d.getElementById(id);
},
ready: function(fc) {
var cb, _ref;
$.cache = (function() {
var reqs;
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
$.queueTask(fc);
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;
}
cb = function() {
$.off(d, 'DOMContentLoaded', cb);
return fc();
rm = function() {
return delete reqs[url];
};
return $.on(d, 'DOMContentLoaded', cb);
},
formData: function(form) {
var fd, key, val;
req = $.ajax(url, {
onload: function(e) {
var _i, _len, _ref;
if (form instanceof HTMLFormElement) {
return new FormData(form);
}
fd = new FormData();
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);
_ref = this.callbacks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
cb.call(this, e);
}
return;
}
rm = function() {
return delete reqs[url];
};
req = $.ajax(url, {
onload: function(e) {
var _i, _len, _ref;
return delete this.callbacks;
},
onabort: rm,
onerror: rm
});
req.callbacks = [cb];
return reqs[url] = req;
};
})();
_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
$.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() {
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 reqs[url] = req;
return GM_openInTab(a.href);
};
})(),
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() {
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;
} 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() {
args = arguments;
that = this;
if (timeout) {
clearTimeout(timeout);
} else {
exec();
}
return timeout = setTimeout(exec, wait);
taskQueue.push(arguments);
return taskChannel.port2.postMessage(null);
};
},
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);
} else {
return function() {
taskQueue.push(arguments);
return setTimeout(execTask, 0);
};
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));
}
})(),
globalEval: function(code) {
var script;
}, false);
return function(key, cb) {
return $.syncing[g.NAMESPACE + key] = cb;
};
})();
script = $.el('script', {
textContent: code
});
$.add(d.head || doc, script);
return $.rm(script);
},
bytesToString: function(size) {
var unit;
$.item = function(key, val) {
var item;
unit = 0;
while (size >= 1024) {
size /= 1024;
unit++;
item = {};
item[key] = val;
return item;
};
$["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 "" + 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;
return cb(items);
});
};
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;
$.set = (function() {
var set;
item = {};
item[key] = val;
return item;
},
"delete": function(keys) {
var key, _i, _len;
if (!(keys instanceof Array)) {
keys = [keys];
set = function(key, val) {
key = g.NAMESPACE + key;
val = JSON.stringify(val);
if (key in $.syncing) {
localStorage.setItem(key, val);
}
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
key = g.NAMESPACE + key;
localStorage.removeItem(key);
GM_deleteValue(key);
return GM_setValue(key, val);
};
return function(keys, val) {
var key;
if (typeof keys === 'string') {
set(keys, val);
return;
}
},
get: function(key, val, cb) {
var items;
if (typeof cb === 'function') {
items = $.item(key, val);
} else {
items = key;
cb = val;
for (key in keys) {
val = keys[key];
set(key, 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) {
key = g.NAMESPACE + key;
val = JSON.stringify(val);
if (key in $.syncing) {
localStorage.setItem(key, val);
}
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);
}
};
})()
});
$$ = function(selector, root) {
if (root == null) {
root = d.body;
}
return __slice.call(root.querySelectorAll(selector));
};
Build = {
spoilerRange: {},

View File

@ -193,6 +193,59 @@
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) {
if (root == null) {
root = d.body;
@ -200,15 +253,6 @@
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) {
var key, val;
@ -221,422 +265,416 @@
}
};
$.extend(Array.prototype, {
add: function(object, position) {
var keep;
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)));
keep = this.slice(position);
this.length = position;
this.push(object);
return this.pushArrays(keep);
},
contains: function(object) {
return this.indexOf(object) > -1;
},
indexOf: function(object) {
var i;
$.id = function(id) {
return d.getElementById(id);
};
i = this.length;
while (i--) {
if (this[i] === object) {
break;
}
$.ready = function(fc) {
var cb, _ref;
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;
},
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);
if (val.size && val.name) {
fd.append(key, val, val.name);
} else {
return false;
fd.append(key, val);
}
}
});
return fd;
};
$.extend(String.prototype, {
capitalize: function() {
return this.charAt(0).toUpperCase() + this.slice(1);
},
contains: function(string) {
return this.indexOf(string) > -1;
$.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;
};
$.extend($, {
id: function(id) {
return d.getElementById(id);
},
ready: function(fc) {
var cb, _ref;
$.cache = (function() {
var reqs;
if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') {
$.queueTask(fc);
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;
}
cb = function() {
$.off(d, 'DOMContentLoaded', cb);
return fc();
rm = function() {
return delete reqs[url];
};
return $.on(d, 'DOMContentLoaded', cb);
},
formData: function(form) {
var fd, key, val;
req = $.ajax(url, {
onload: function(e) {
var _i, _len, _ref;
if (form instanceof HTMLFormElement) {
return new FormData(form);
}
fd = new FormData();
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);
_ref = this.callbacks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
cb.call(this, e);
}
return;
}
rm = function() {
return delete reqs[url];
};
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
return delete this.callbacks;
},
onabort: rm,
onerror: rm
});
$.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;
req.callbacks = [cb];
return reqs[url] = req;
};
})();
return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
};
}
})(),
rmAll: function(root) {
var node;
while (node = root.firstChild) {
root.removeChild(node);
}
$.cb = {
checked: function() {
$.set(this.name, this.checked);
return Conf[this.name] = this.checked;
},
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);
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;
};
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 = {
spoilerRange: {},

View File

@ -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:
# http://api.jquery.com/
# not chainable
$ = (selector, root=d.body) ->
root.querySelector selector
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)))
$$ = (selector, root=d.body) ->
[root.querySelectorAll(selector)...]
$.extend = (object, properties) ->
for key, val of properties
continue unless properties.hasOwnProperty key
object[key] = val
return
# Various prototypes I've wanted or needed to add.
$.extend Array::,
add: (object, position) ->
keep = @slice position
@length = position
@push object
@pushArrays keep
$.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)))
contains: (object) ->
@indexOf(object) > -1
indexOf: (object) ->
i = @length
while i--
break if @[i] is object
return i
pushArrays: ->
args = arguments
for arg in args
@push.apply @, arg
$.id = (id) ->
d.getElementById id
$.ready = (fc) ->
if d.readyState in ['interactive', 'complete']
$.queueTask fc
return
remove: (object) ->
if (index = @indexOf object) > -1
@splice index, 1
cb = ->
$.off d, 'DOMContentLoaded', cb
fc()
$.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
false
$.extend String::,
capitalize: ->
@charAt(0).toUpperCase() + @slice(1);
contains: (string) ->
@indexOf(string) > -1
$.extend $,
id: (id) ->
d.getElementById id
ready: (fc) ->
if d.readyState in ['interactive', 'complete']
$.queueTask fc
return
cb = ->
$.off d, 'DOMContentLoaded', cb
fc()
$.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
fd.append key, val
fd
$.ajax = (url, callbacks, opts={}) ->
{type, cred, headers, upCallbacks, form, sync} = opts
r = new XMLHttpRequest()
r.overrideMimeType 'text/html'
type or= form and 'post' or 'get'
r.open type, url, !sync
for key, val of headers
r.setRequestHeader key, val
$.extend r, callbacks
$.extend r.upload, upCallbacks
r.withCredentials = cred
r.send form
r
$.cache = do ->
reqs = {}
(url, cb) ->
if req = reqs[url]
if req.readyState is 4
cb.call req
else
fd.append key, val
fd
ajax: (url, callbacks, opts={}) ->
{type, cred, headers, upCallbacks, form, sync} = opts
r = new XMLHttpRequest()
r.overrideMimeType 'text/html'
type or= form and 'post' or 'get'
r.open type, url, !sync
for key, val of headers
r.setRequestHeader key, val
$.extend r, callbacks
$.extend r.upload, upCallbacks
r.withCredentials = cred
r.send form
r
cache: do ->
reqs = {}
(url, cb) ->
if req = reqs[url]
if req.readyState is 4
cb.call req
else
req.callbacks.push cb
return
rm = -> delete reqs[url]
req = $.ajax url,
onload: (e) ->
cb.call @, e for cb in @callbacks
delete @callbacks
onabort: rm
onerror: rm
req.callbacks = [cb]
reqs[url] = req
cb:
checked: ->
$.set @name, @checked
Conf[@name] = @checked
value: ->
$.set @name, @value.trim()
Conf[@name] = @value
asap: (test, cb) ->
if test()
cb()
else
setTimeout $.asap, 25, test, cb
addStyle: (css, id) ->
style = $.el 'style',
id: id
textContent: css
$.asap (-> d.head), ->
$.add d.head, style
style
x: (path, root) ->
root or= d.body
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
d.evaluate(path, root, null, 8, null).singleNodeValue
X: (path, root) ->
root or= d.body
d.evaluate path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null
addClass: (el, className) ->
el.classList.add className
rmClass: (el, className) ->
el.classList.remove className
toggleClass: (el, className) ->
el.classList.toggle className
hasClass: (el, className) ->
el.classList.contains className
rm: do ->
if 'remove' of Element.prototype
(el) -> el.remove()
else
(el) -> el.parentNode?.removeChild el
rmAll: (root) ->
# jsperf.com/emptify-element
while node = root.firstChild
# HTMLSelectElement.remove !== Element.remove
root.removeChild node
return
tn: (s) ->
d.createTextNode s
frag: ->
d.createDocumentFragment()
nodes: (nodes) ->
unless nodes instanceof Array
return nodes
frag = $.frag()
for node in nodes
frag.appendChild node
frag
add: (parent, el) ->
parent.appendChild $.nodes el
prepend: (parent, el) ->
parent.insertBefore $.nodes(el), parent.firstChild
after: (root, el) ->
root.parentNode.insertBefore $.nodes(el), root.nextSibling
before: (root, el) ->
root.parentNode.insertBefore $.nodes(el), root
replace: (root, el) ->
root.parentNode.replaceChild $.nodes(el), root
el: (tag, properties) ->
el = d.createElement tag
$.extend el, properties if properties
el
on: (el, events, handler) ->
for event in events.split ' '
el.addEventListener event, handler, false
return
off: (el, events, handler) ->
for event in events.split ' '
el.removeEventListener event, handler, false
return
event: (event, detail, root=d) ->
root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
open: do ->
if GM_openInTab?
(URL) ->
# XXX fix GM opening file://// for protocol-less URLs.
a = $.el 'a', href: URL
GM_openInTab a.href
else
(URL) -> window.open URL, '_blank'
debounce: (wait, fn) ->
req.callbacks.push cb
return
rm = -> delete reqs[url]
req = $.ajax url,
onload: (e) ->
cb.call @, e for cb in @callbacks
delete @callbacks
onabort: rm
onerror: rm
req.callbacks = [cb]
reqs[url] = req
$.cb =
checked: ->
$.set @name, @checked
Conf[@name] = @checked
value: ->
$.set @name, @value.trim()
Conf[@name] = @value
$.asap = (test, cb) ->
if test()
cb()
else
setTimeout $.asap, 25, test, cb
$.addStyle = (css, id) ->
style = $.el 'style',
id: id
textContent: css
$.asap (-> d.head), ->
$.add d.head, style
style
$.x = (path, root) ->
root or= d.body
# XPathResult.ANY_UNORDERED_NODE_TYPE === 8
d.evaluate(path, root, null, 8, null).singleNodeValue
$.X = (path, root) ->
root or= d.body
d.evaluate path, root, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null
$.addClass = (el, className) ->
el.classList.add className
$.rmClass = (el, className) ->
el.classList.remove className
$.toggleClass = (el, className) ->
el.classList.toggle className
$.hasClass = (el, className) ->
el.classList.contains className
$.rm = do ->
if 'remove' of Element.prototype
(el) -> el.remove()
else
(el) -> el.parentNode?.removeChild el
$.rmAll = (root) ->
# jsperf.com/emptify-element
while node = root.firstChild
# HTMLSelectElement.remove !== Element.remove
root.removeChild node
return
$.tn = (s) ->
d.createTextNode s
$.frag = ->
d.createDocumentFragment()
$.nodes = (nodes) ->
unless nodes instanceof Array
return nodes
frag = $.frag()
for node in nodes
frag.appendChild node
frag
$.add = (parent, el) ->
parent.appendChild $.nodes el
$.prepend = (parent, el) ->
parent.insertBefore $.nodes(el), parent.firstChild
$.after = (root, el) ->
root.parentNode.insertBefore $.nodes(el), root.nextSibling
$.before = (root, el) ->
root.parentNode.insertBefore $.nodes(el), root
$.replace = (root, el) ->
root.parentNode.replaceChild $.nodes(el), root
$.el = (tag, properties) ->
el = d.createElement tag
$.extend el, properties if properties
el
$.on = (el, events, handler) ->
for event in events.split ' '
el.addEventListener event, handler, false
return
$.off = (el, events, handler) ->
for event in events.split ' '
el.removeEventListener event, handler, false
return
$.event = (event, detail, root=d) ->
root.dispatchEvent new CustomEvent event, {bubbles: true, detail}
$.open = do ->
if GM_openInTab?
(URL) ->
# XXX fix GM opening file://// for protocol-less URLs.
a = $.el 'a', href: URL
GM_openInTab a.href
else
(URL) -> window.open URL, '_blank'
$.debounce = (wait, fn) ->
timeout = null
that = null
args = null
exec = ->
fn.apply that, args
timeout = null
that = null
args = null
exec = ->
fn.apply that, args
timeout = null
->
args = arguments
that = this
if timeout
# stop current reset
clearTimeout timeout
else
exec()
->
args = arguments
that = this
if timeout
# stop current reset
clearTimeout timeout
else
exec()
# after wait, let next invocation execute immediately
timeout = setTimeout exec, wait
queueTask: do ->
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
taskQueue = []
execTask = ->
task = taskQueue.shift()
func = task[0]
args = Array::slice.call task, 1
func.apply func, args
if window.MessageChannel
taskChannel = new MessageChannel()
taskChannel.port1.onmessage = execTask
->
taskQueue.push arguments
taskChannel.port2.postMessage null
else # XXX Firefox
->
taskQueue.push arguments
setTimeout execTask, 0
globalEval: (code) ->
script = $.el 'script',
textContent: code
$.add (d.head or doc), script
$.rm script
bytesToString: (size) ->
unit = 0 # Bytes
while size >= 1024
size /= 1024
unit++
# Remove trailing 0s.
size =
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
# after wait, let next invocation execute immediately
timeout = setTimeout exec, wait
$.queueTask = do ->
# inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
taskQueue = []
execTask = ->
task = taskQueue.shift()
func = task[0]
args = Array::slice.call task, 1
func.apply func, args
if window.MessageChannel
taskChannel = new MessageChannel()
taskChannel.port1.onmessage = execTask
->
taskQueue.push arguments
taskChannel.port2.postMessage null
else # XXX Firefox
->
taskQueue.push arguments
setTimeout execTask, 0
$.globalEval = (code) ->
script = $.el 'script',
textContent: code
$.add (d.head or doc), script
$.rm script
$.bytesToString = (size) ->
unit = 0 # Bytes
while size >= 1024
size /= 1024
unit++
# Remove trailing 0s.
size =
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
# 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
value
value
)
syncing: {}
sync: do ->
$.syncing = {}
$.sync = do ->
<% if (type === 'crx') { %>
chrome.storage.onChanged.addListener (changes) ->
for key of changes
if cb = $.syncing[key]
cb changes[key].newValue
return
(key, cb) -> $.syncing[key] = cb
chrome.storage.onChanged.addListener (changes) ->
for key of changes
if cb = $.syncing[key]
cb changes[key].newValue
return
(key, cb) -> $.syncing[key] = cb
<% } else { %>
window.addEventListener 'storage', (e) ->
if cb = $.syncing[e.key]
cb JSON.parse e.newValue
, false
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
window.addEventListener 'storage', (e) ->
if cb = $.syncing[e.key]
cb JSON.parse e.newValue
, false
(key, cb) -> $.syncing[g.NAMESPACE + key] = cb
<% } %>
item: (key, val) ->
item = {}
item[key] = val
item
$.item = (key, val) ->
item = {}
item[key] = val
item
<% if (type === 'crx') { %>
# https://developer.chrome.com/extensions/storage.html
delete: (keys) ->
chrome.storage.sync.remove keys
get: (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
chrome.storage.sync.get items, cb
set: (key, val) ->
items = if typeof key is 'string'
$.item key, val
else
key
chrome.storage.sync.set items
$.delete = (keys) ->
chrome.storage.sync.remove keys
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
chrome.storage.sync.get items, cb
$.set = (key, val) ->
items = if typeof key is 'string'
$.item key, val
else
key
chrome.storage.sync.set items
<% } else if (type === 'userjs') { %>
do ->
# http://www.opera.com/docs/userjs/specs/#scriptstorage
@ -308,73 +341,79 @@ do ->
# to the object.
{scriptStorage} = opera
$.delete = (keys) ->
unless keys instanceof Array
keys = [keys]
for key in keys
key = g.NAMESPACE + key
localStorage.removeItem key
delete scriptStorage[key]
return
unless keys instanceof Array
keys = [keys]
for key in keys
key = g.NAMESPACE + key
localStorage.removeItem key
delete scriptStorage[key]
return
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
$.queueTask ->
for key of items
if val = scriptStorage[g.NAMESPACE + key]
items[key] = JSON.parse val
cb items
$.set = do ->
set = (key, val) ->
key = g.NAMESPACE + key
val = JSON.stringify val
if key of $.syncing
# for `storage` events
localStorage.setItem key, val
scriptStorage[key] = val
(keys, val) ->
if typeof keys is 'string'
set keys, val
return
for key, val of keys
set key, val
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
$.queueTask ->
for key of items
if val = scriptStorage[g.NAMESPACE + key]
items[key] = JSON.parse val
cb items
$.set = do ->
set = (key, val) ->
key = g.NAMESPACE + key
val = JSON.stringify val
if key of $.syncing
# for `storage` events
localStorage.setItem key, val
scriptStorage[key] = val
(keys, val) ->
if typeof keys is 'string'
set keys, val
return
<% } else { %>
# http://wiki.greasespot.net/Main_Page
delete: (keys) ->
unless keys instanceof Array
keys = [keys]
for key in keys
key = g.NAMESPACE + key
localStorage.removeItem key
GM_deleteValue key
for key, val of keys
set key, val
return
get: (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
$.queueTask ->
for key of items
if val = GM_getValue g.NAMESPACE + key
items[key] = JSON.parse val
cb items
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
for key, val of keys
set key, val
<% } else { %>
# http://wiki.greasespot.net/Main_Page
$.delete = (keys) ->
unless keys instanceof Array
keys = [keys]
for key in keys
key = g.NAMESPACE + key
localStorage.removeItem key
GM_deleteValue key
return
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
else
items = key
cb = val
$.queueTask ->
for key of items
if val = GM_getValue g.NAMESPACE + key
items[key] = JSON.parse val
cb items
$.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
for key, val of keys
set key, val
return
<% } %>
$$ = (selector, root=d.body) ->
[root.querySelectorAll(selector)...]