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:
commit
6cc5ac8dd2
@ -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
35
LICENSE
@ -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.
|
||||
*/
|
||||
@ -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>]"
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -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/*
|
||||
|
||||
@ -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>]"
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -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
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
4475
src/features.coffee
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
184
src/lib/$.coffee
184
src/lib/$.coffee
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user