diff --git a/builds/4chan-X.js b/builds/4chan-X.js index af7489afd..7d314d336 100644 --- a/builds/4chan-X.js +++ b/builds/4chan-X.js @@ -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) { diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index a44f22104..255b85e7c 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -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: {}, diff --git a/builds/crx/script.js b/builds/crx/script.js index b926cf861..573f669d9 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -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: {}, diff --git a/src/lib/$.coffee b/src/lib/$.coffee index bfefd49b5..a92d19ac3 100644 --- a/src/lib/$.coffee +++ b/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: # 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)...]