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

Conflicts:
	CHANGELOG.md
	Gruntfile.js
	LICENSE
	lib/$.coffee
	package.json
	src/banner.js
	src/config.coffee
	src/css/style.css
	src/features.coffee
	src/metadata.js
This commit is contained in:
Zixaphir 2013-04-26 00:31:19 -07:00
commit 6cc5ac8dd2
13 changed files with 4789 additions and 232 deletions

View File

@ -1,3 +1,7 @@
mayhemydg:
- Minor fixes.
- Chrome only: Due to technical limitations, Filter lists and Custom CSS will not by synchronized across devices anymore.
seaweedchan:
- Allow thread watcher to load on catalog
@ -69,4 +73,4 @@ zixaphir:
- Fix unread post count for filtered posts
- Fix issues when switching from ihavenoface's fork
- Fix backlinks not receiving filtered class
- Fix QR position not saving on refresh
- Fix QR position not saving on refresh

35
LICENSE
View File

@ -1,11 +1,9 @@
/*
* 4chan X - Version 1.1.0 - 2013-04-25
* 4chan X - Version 1.1.0 - 2013-04-26
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
*
* Appchan X Copyright © 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
@ -14,12 +12,6 @@
* http://seaweedchan.github.io/4chan-x/
* 4chan x Copyright © 2012-2013 ihavenoface
* http://ihavenoface.github.io/4chan-x/
* OneeChan Copyright © 2011-2013 Jordan Bates <saudrapsmann@gmail.com>
* http://seaweedchan.github.io/oneechan/
* 4chan SS Copyright © 2011-2013 Ahodesuka
* https://github.com/ahodesuka/4chan-Style-Script/
* Raphael Icons Copyright © 2013 Dmitry Baranovskiy
* http://raphaeljs.com/icons/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -70,11 +62,24 @@
*/
/*
* Linkify based on:
* http://downloads.mozdev.org/greasemonkey/linkify.user.js
* https://github.com/MayhemYDG/LinkifyPlusFork
* Contains data from external sources:
*
* audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
* cc-by-nc-3.0
*
* 4chan/4chan-JS (https://github.com/4chan/4chan-JS)
* Copyright (c) 2012-2013, 4chan LLC
* All rights reserved.
*
* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*
* Linkify: (http://userscripts.org/scripts/show/1352)
* Copyright (c) 2011, Anthony Lieuallen
* All rights reserved.
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*
* license: http://userscripts.org/scripts/review/1352
*
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*/

View File

@ -3,11 +3,7 @@
// @version 1.1.0
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @copyright 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
// @copyright 2013-2013 Jordan Bates <saudrapsmann@gmail.com>
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
// @match *://api.4chan.org/*
// @match *://boards.4chan.org/*
// @match *://images.4chan.org/*
@ -22,13 +18,11 @@
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// ==/UserScript==
/*
* 4chan X - Version 1.1.0 - 2013-04-25
* 4chan X - Version 1.1.0 - 2013-04-26
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
*
* Appchan X Copyright © 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
@ -37,12 +31,6 @@
* http://seaweedchan.github.io/4chan-x/
* 4chan x Copyright © 2012-2013 ihavenoface
* http://ihavenoface.github.io/4chan-x/
* OneeChan Copyright © 2011-2013 Jordan Bates <saudrapsmann@gmail.com>
* http://seaweedchan.github.io/oneechan/
* 4chan SS Copyright © 2011-2013 Ahodesuka
* https://github.com/ahodesuka/4chan-Style-Script/
* Raphael Icons Copyright © 2013 Dmitry Baranovskiy
* http://raphaeljs.com/icons/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -93,13 +81,26 @@
*/
/*
* Linkify based on:
* http://downloads.mozdev.org/greasemonkey/linkify.user.js
* https://github.com/MayhemYDG/LinkifyPlusFork
* Contains data from external sources:
*
* audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
* cc-by-nc-3.0
*
* 4chan/4chan-JS (https://github.com/4chan/4chan-JS)
* Copyright (c) 2012-2013, 4chan LLC
* All rights reserved.
*
* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*
* Linkify: (http://userscripts.org/scripts/show/1352)
* Copyright (c) 2011, Anthony Lieuallen
* All rights reserved.
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*
* license: http://userscripts.org/scripts/review/1352
*
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*/
(function() {
var $, $$, Anonymize, ArchiveLink, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DataBoards, DeleteLink, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Get, Header, IDColor, ImageExpand, ImageHover, ImageReplace, Keybinds, Linkify, Main, Menu, Nav, Notification, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
@ -639,41 +640,28 @@
}));
};
$.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');
};
}
})();
$.open = function(URL) {
return window.open(URL, '_blank');
};
$.debounce = function(wait, fn) {
var args, exec, that, timeout;
var args, exec, lastCall, that, timeout;
lastCall = 0;
timeout = null;
that = null;
args = null;
exec = function() {
fn.apply(that, args);
return timeout = null;
lastCall = Date.now();
return fn.apply(that, args);
};
return function() {
args = arguments;
that = this;
if (timeout) {
clearTimeout(timeout);
} else {
exec();
if (lastCall < Date.now() - wait) {
return exec();
}
clearTimeout(timeout);
return timeout = setTimeout(exec, wait);
};
};
@ -1459,7 +1447,7 @@
});
}
now = Date.now();
if ((this.data.lastChecked || 0) < now - 12 * $.HOUR) {
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
this.ajaxClean(boardID);
@ -8154,7 +8142,7 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
innerHTML: 'Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.'
innerHTML: "Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.\n[<a href=\"https://github.com/MayhemYDG/4chan-x/wiki/FAQ#what-does-connection-error-you-may-have-been-banned-mean\" target=_blank>FAQ</a>]"
}));
}
};

View File

@ -3,11 +3,7 @@
// @version 1.1.0
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @copyright 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
// @copyright 2013-2013 Jordan Bates <saudrapsmann@gmail.com>
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
// @match *://api.4chan.org/*
// @match *://boards.4chan.org/*
// @match *://images.4chan.org/*

View File

@ -3,11 +3,7 @@
// @version 1.1.0
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
// @copyright 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
// @copyright 2013-2013 Jordan Bates <saudrapsmann@gmail.com>
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
// @match *://api.4chan.org/*
// @match *://boards.4chan.org/*
// @match *://images.4chan.org/*
@ -22,13 +18,11 @@
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
// ==/UserScript==
/*
* 4chan X - Version 1.1.0 - 2013-04-25
* 4chan X - Version 1.1.0 - 2013-04-26
*
* Licensed under the MIT license.
* https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
*
* Appchan X Copyright © 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
@ -37,12 +31,6 @@
* http://seaweedchan.github.io/4chan-x/
* 4chan x Copyright © 2012-2013 ihavenoface
* http://ihavenoface.github.io/4chan-x/
* OneeChan Copyright © 2011-2013 Jordan Bates <saudrapsmann@gmail.com>
* http://seaweedchan.github.io/oneechan/
* 4chan SS Copyright © 2011-2013 Ahodesuka
* https://github.com/ahodesuka/4chan-Style-Script/
* Raphael Icons Copyright © 2013 Dmitry Baranovskiy
* http://raphaeljs.com/icons/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -93,13 +81,26 @@
*/
/*
* Linkify based on:
* http://downloads.mozdev.org/greasemonkey/linkify.user.js
* https://github.com/MayhemYDG/LinkifyPlusFork
* Contains data from external sources:
*
* audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
* cc-by-nc-3.0
*
* 4chan/4chan-JS (https://github.com/4chan/4chan-JS)
* Copyright (c) 2012-2013, 4chan LLC
* All rights reserved.
*
* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*
* Linkify: (http://userscripts.org/scripts/show/1352)
* Copyright (c) 2011, Anthony Lieuallen
* All rights reserved.
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*
* license: http://userscripts.org/scripts/review/1352
*
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*/
(function() {
var $, $$, Anonymize, ArchiveLink, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DataBoards, DeleteLink, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Get, Header, IDColor, ImageExpand, ImageHover, ImageReplace, Keybinds, Linkify, Main, Menu, Nav, Notification, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
@ -636,41 +637,30 @@
}));
};
$.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');
};
}
})();
$.open = function(URL) {
return GM_openInTab(($.el('a', {
href: URL
})).href);
};
$.debounce = function(wait, fn) {
var args, exec, that, timeout;
var args, exec, lastCall, that, timeout;
lastCall = 0;
timeout = null;
that = null;
args = null;
exec = function() {
fn.apply(that, args);
return timeout = null;
lastCall = Date.now();
return fn.apply(that, args);
};
return function() {
args = arguments;
that = this;
if (timeout) {
clearTimeout(timeout);
} else {
exec();
if (lastCall < Date.now() - wait) {
return exec();
}
clearTimeout(timeout);
return timeout = setTimeout(exec, wait);
};
};
@ -1453,7 +1443,7 @@
});
}
now = Date.now();
if ((this.data.lastChecked || 0) < now - 12 * $.HOUR) {
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
this.ajaxClean(boardID);
@ -8174,7 +8164,7 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
innerHTML: 'Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.'
innerHTML: "Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.\n[<a href=\"https://github.com/MayhemYDG/4chan-x/wiki/FAQ#what-does-connection-error-you-may-have-been-banned-mean\" target=_blank>FAQ</a>]"
}));
}
};

View File

@ -1,9 +1,9 @@
(function() {
var $, $$, Anonymize, ArchiveLink, Board, Build, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DataBoards, DeleteLink, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Get, Header, IDColor, ImageExpand, ImageHover, ImageReplace, Keybinds, Linkify, Main, Menu, Nav, Notification, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Config = {
main: {
@ -533,41 +533,28 @@
}));
};
$.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');
};
}
})();
$.open = function(URL) {
return window.open(URL, '_blank');
};
$.debounce = function(wait, fn) {
var args, exec, that, timeout;
var args, exec, lastCall, that, timeout;
lastCall = 0;
timeout = null;
that = null;
args = null;
exec = function() {
fn.apply(that, args);
return timeout = null;
lastCall = Date.now();
return fn.apply(that, args);
};
return function() {
args = arguments;
that = this;
if (timeout) {
clearTimeout(timeout);
} else {
exec();
if (lastCall < Date.now() - wait) {
return exec();
}
clearTimeout(timeout);
return timeout = setTimeout(exec, wait);
};
};
@ -650,12 +637,14 @@
return item;
};
$.localKeys = ['name', 'uniqueID', 'tripcode', 'capcode', 'email', 'subject', 'comment', 'flag', 'filename', 'dimensions', 'filesize', 'MD5', 'usercss'];
$["delete"] = function(keys) {
return chrome.storage.sync.remove(keys);
};
$.get = function(key, val, cb) {
var items;
var count, done, items, localItems, syncItems;
if (typeof cb === 'function') {
items = $.item(key, val);
@ -663,15 +652,69 @@
items = key;
cb = val;
}
return chrome.storage.sync.get(items, cb);
localItems = null;
syncItems = null;
for (key in items) {
val = items[key];
if (__indexOf.call($.localKeys, key) >= 0) {
(localItems || (localItems = {}))[key] = val;
} else {
(syncItems || (syncItems = {}))[key] = val;
}
}
items = {};
count = 0;
done = function(item) {
$.extend(items, item);
if (!--count) {
return cb(items);
}
};
if (localItems) {
count++;
chrome.storage.local.get(localItems, done);
}
if (syncItems) {
count++;
return chrome.storage.sync.get(syncItems, done);
}
};
$.set = function(key, val) {
var items;
$.set = (function() {
var items, localItems, set;
items = typeof key === 'string' ? $.item(key, val) : key;
return chrome.storage.sync.set(items);
};
items = {};
localItems = {};
set = $.debounce($.SECOND, function() {
var err, key, _i, _len, _ref;
_ref = $.localKeys;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
key = _ref[_i];
if (key in items) {
(localItems || (localItems = {}))[key] = items[key];
delete items[key];
}
}
try {
chrome.storage.local.set(localItems);
chrome.storage.sync.set(items);
items = {};
return localItems = {};
} catch (_error) {
err = _error;
return c.error(err);
}
});
return function(key, val) {
if (typeof key === 'string') {
items[key] = val;
} else {
$.extend(items, key);
}
return set();
};
})();
$$ = function(selector, root) {
if (root == null) {
@ -1317,7 +1360,7 @@
});
}
now = Date.now();
if ((this.data.lastChecked || 0) < now - 12 * $.HOUR) {
if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
this.data.lastChecked = now;
for (boardID in this.data.boards) {
this.ajaxClean(boardID);
@ -8019,7 +8062,7 @@
QR.cooldown.auto = false;
QR.status();
return QR.error($.el('span', {
innerHTML: 'Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.'
innerHTML: "Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.\n[<a href=\"https://github.com/MayhemYDG/4chan-x/wiki/FAQ#what-does-connection-error-you-may-have-been-banned-mean\" target=_blank>FAQ</a>]"
}));
}
};

BIN
img/changelog/3.2.0/0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

4475
src/features.coffee Normal file

File diff suppressed because it is too large Load Diff

View File

@ -979,7 +979,10 @@ QR =
QR.cooldown.auto = false
QR.status()
QR.error $.el 'span',
innerHTML: 'Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.'
innerHTML: """
Connection error. You may have been <a href=//www.4chan.org/banned target=_blank>banned</a>.
[<a href="https://github.com/MayhemYDG/4chan-x/wiki/FAQ#what-does-connection-error-you-may-have-been-banned-mean" target=_blank>FAQ</a>]
"""
opts =
cred: true
form: $.formData postData

View File

@ -47,7 +47,7 @@ $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000)))
$.id = (id) ->
d.getElementById id
$.ready = (fc) ->
if d.readyState in ['interactive', 'complete']
$.queueTask fc
@ -56,7 +56,7 @@ $.ready = (fc) ->
$.off d, 'DOMContentLoaded', cb
fc()
$.on d, 'DOMContentLoaded', cb
$.formData = (form) ->
if form instanceof HTMLFormElement
return new FormData form
@ -70,7 +70,7 @@ $.formData = (form) ->
else
fd.append key, val
fd
$.ajax = (url, callbacks, opts={}) ->
{type, cred, headers, upCallbacks, form, sync} = opts
r = new XMLHttpRequest()
@ -84,7 +84,7 @@ $.ajax = (url, callbacks, opts={}) ->
r.withCredentials = cred
r.send form
r
$.cache = do ->
reqs = {}
(url, cb) ->
@ -103,7 +103,7 @@ $.cache = do ->
onerror: rm
req.callbacks = [cb]
reqs[url] = req
$.cb =
checked: ->
$.set @name, @checked
@ -111,13 +111,13 @@ $.cb =
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
@ -125,47 +125,47 @@ $.addStyle = (css, id) ->
$.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
@ -173,65 +173,64 @@ $.nodes = (nodes) ->
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'
$.open = (URL) ->
<% if (type === 'userscript') { %>
# XXX fix GM opening file://// for protocol-less URLs.
# https://github.com/greasemonkey/greasemonkey/issues/1719
GM_openInTab ($.el 'a', href: URL).href
<% } else { %>
window.open URL, '_blank'
<% } %>
$.debounce = (wait, fn) ->
timeout = null
that = null
args = null
exec = ->
lastCall = 0
timeout = null
that = null
args = null
exec = ->
lastCall = Date.now()
fn.apply that, args
timeout = null
->
args = arguments
that = this
if timeout
# stop current reset
clearTimeout timeout
else
exec()
if lastCall < Date.now() - wait
return exec()
# stop current reset
clearTimeout timeout
# after wait, let next invocation execute immediately
timeout = setTimeout exec, wait
@ -253,13 +252,13 @@ $.queueTask = do ->
->
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
@ -275,7 +274,7 @@ $.bytesToString = (size) ->
# Round to an integer otherwise.
Math.round size
"#{size} #{['B', 'KB', 'MB', 'GB'][unit]}"
$.minmax = (value, min, max) ->
return (
if value < min
@ -286,7 +285,7 @@ $.minmax = (value, min, max) ->
else
value
)
$.syncing = {}
$.sync = do ->
@ -310,26 +309,79 @@ $.item = (key, val) ->
item[key] = val
item
<% if (type === 'crx') { %>
# https://developer.chrome.com/extensions/storage.html
$.localKeys = [
# filters
'name',
'uniqueID',
'tripcode',
'capcode',
'email',
'subject',
'comment',
'flag',
'filename',
'dimensions',
'filesize',
'MD5',
# custom css
'usercss'
]
# 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
localItems = null
syncItems = null
for key, val of items
if key in $.localKeys
(localItems or= {})[key] = val
else
(syncItems or= {})[key] = val
items = {}
count = 0
done = (item) ->
$.extend items, item
cb items unless --count
if localItems
count++
chrome.storage.local.get localItems, done
if syncItems
count++
chrome.storage.sync.get syncItems, done
$.set = do ->
items = {}
localItems = {}
set = $.debounce $.SECOND, ->
for key in $.localKeys
if key of items
(localItems or= {})[key] = items[key]
delete items[key]
try
chrome.storage.local.set localItems
chrome.storage.sync.set items
items = {}
localItems = {}
catch err
c.error err
(key, val) ->
if typeof key is 'string'
items[key] = val
else
$.extend items, key
set()
<% } else if (type === 'userjs') { %>
do ->
# http://www.opera.com/docs/userjs/specs/#scriptstorage
@ -386,7 +438,7 @@ $.delete = (keys) ->
localStorage.removeItem key
GM_deleteValue key
return
$.get = (key, val, cb) ->
if typeof cb is 'function'
items = $.item key, val
@ -398,7 +450,7 @@ $.get = (key, val, cb) ->
if val = GM_getValue g.NAMESPACE + key
items[key] = JSON.parse val
cb items
$.set = do ->
set = (key, val) ->
key = g.NAMESPACE + key

View File

@ -63,7 +63,7 @@ class DataBoard
@deleteIfEmpty {boardID}
now = Date.now()
if (@data.lastChecked or 0) < now - 12 * $.HOUR
if (@data.lastChecked or 0) < now - 2 * $.HOUR
@data.lastChecked = now
for boardID of @data.boards
@ajaxClean boardID

View File

@ -4,8 +4,6 @@
* Licensed under the MIT license.
* <%= meta.repo %>blob/master/LICENSE
*
* Appchan X Copyright © 2013-<%= grunt.template.today('yyyy') %> Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-<%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
@ -14,12 +12,6 @@
* http://seaweedchan.github.io/4chan-x/
* 4chan x Copyright © 2012-<%= grunt.template.today('yyyy') %> ihavenoface
* http://ihavenoface.github.io/4chan-x/
* OneeChan Copyright © 2011-<%= grunt.template.today('yyyy') %> Jordan Bates <saudrapsmann@gmail.com>
* http://seaweedchan.github.io/oneechan/
* 4chan SS Copyright © 2011-<%= grunt.template.today('yyyy') %> Ahodesuka
* https://github.com/ahodesuka/4chan-Style-Script/
* Raphael Icons Copyright © <%= grunt.template.today('yyyy') %> Dmitry Baranovskiy
* http://raphaeljs.com/icons/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -70,11 +62,24 @@
*/
/*
* Linkify based on:
* http://downloads.mozdev.org/greasemonkey/linkify.user.js
* https://github.com/MayhemYDG/LinkifyPlusFork
* Contains data from external sources:
*
* audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
* cc-by-nc-3.0
*
* 4chan/4chan-JS (https://github.com/4chan/4chan-JS)
* Copyright (c) 2012-2013, 4chan LLC
* All rights reserved.
*
* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
*
* Linkify: (http://userscripts.org/scripts/show/1352)
* Copyright (c) 2011, Anthony Lieuallen
* All rights reserved.
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*
* license: http://userscripts.org/scripts/review/1352
*
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*/

View File

@ -3,11 +3,7 @@
// @version <%= version %>
// @namespace <%= name %>
// @description <%= description %>
// @copyright 2013-<%= grunt.template.today('yyyy') %> Zixaphir <zixaphirmoxphar@gmail.com>
// @copyright 2013-<%= grunt.template.today('yyyy') %> Jordan Bates <saudrapsmann@gmail.com>
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
// @copyright 2012-<%= grunt.template.today('yyyy') %> Nicolas Stepien <stepien.nicolas@gmail.com>
// @license MIT; http://en.wikipedia.org/wiki/Mit_license
// @license MIT; <%= meta.repo %>blob/<%= meta.mainBranch %>/LICENSE
<%=
meta.matches.map(function(match) {
return '// @match ' + match;