diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c160c311..7bcba0d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ## v1.13.0 +**v1.13.0.18** *(2016-10-31)* - [[Userscript](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.0.18/builds/4chan-X-noupdate.user.js)] [[Chrome extension](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.0.18/builds/4chan-X-noupdate.crx)] +- Improve robustness against invalid settings data, including thread watcher timestamps from future. + **v1.13.0.17** *(2016-10-30)* - [[Userscript](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.0.17/builds/4chan-X-noupdate.user.js)] [[Chrome extension](https://raw.githubusercontent.com/ccd0/4chan-x/1.13.0.17/builds/4chan-X-noupdate.crx)] - Various regression and bug fixes. diff --git a/README.md b/README.md index d7ba52e8c..a5d66f4f6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ ![screenshot](https://ccd0.github.io/4chan-x/img/screenshot.png) # 4chan X -Adds various features to 4chan. -Previously developed by [aeosynth](https://github.com/aeosynth/4chan-x), [Mayhem](https://github.com/MayhemYDG/4chan-x), [ihavenoface](https://github.com/ihavenoface/4chan-x), [Zixaphir](https://github.com/zixaphir/appchan-x), [Seaweed](https://github.com/seaweedchan/4chan-x), and [Spittie](https://github.com/Spittie/4chan-x), with contributions from many others. +4chan X is an unofficial script written by users of 4chan to add various features to the site. + +It was previously developed by [aeosynth](https://github.com/aeosynth/4chan-x), [Mayhem](https://github.com/MayhemYDG/4chan-x), [ihavenoface](https://github.com/ihavenoface/4chan-x), [Zixaphir](https://github.com/zixaphir/appchan-x), [Seaweed](https://github.com/seaweedchan/4chan-x), and [Spittie](https://github.com/Spittie/4chan-x), with contributions from many others. If you're looking for a maintained fork of OneeChan (a style script used in addition to 4chan X), try https://github.com/Nebukazar/OneeChan. diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 1c7590353..830d3c115 100644 Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js index 1ca3c2b35..6df20c1cf 100644 --- a/builds/4chan-X-beta.meta.js +++ b/builds/4chan-X-beta.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.13.0.17 +// @version 1.13.0.18 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js index 208cd7491..13337e2a0 100644 --- a/builds/4chan-X-beta.user.js +++ b/builds/4chan-X-beta.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.13.0.17 +// @version 1.13.0.18 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.0.17', + VERSION: '1.13.0.18', NAMESPACE: '4chan X.', boards: {} }; @@ -5321,7 +5321,7 @@ DataBoard = (function() { }; DataBoard.prototype.clean = function() { - var boardID, now, ref, val; + var boardID, now, ref, ref1, val; $.forceSync(this.key); ref = this.data.boards; for (boardID in ref) { @@ -5331,7 +5331,7 @@ DataBoard = (function() { }); } now = Date.now(); - if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) { + if (!((now - 2 * $.HOUR < (ref1 = this.data.lastChecked || 0) && ref1 <= now))) { this.data.lastChecked = now; for (boardID in this.data.boards) { this.ajaxClean(boardID); @@ -6617,9 +6617,13 @@ Redirect = (function() { { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": false, "software": "foolfuuka", "boards": [ "h", "hc", "hm", "r", "s", "soc" ], "files": [ "h", "hc", "hm", "r", "s", "soc" ] } ], init: function() { + var now, ref; this.selectArchives(); - if (Conf['archiveAutoUpdate'] && Conf['lastarchivecheck'] < Date.now() - 2 * $.DAY) { - return this.update(); + if (Conf['archiveAutoUpdate']) { + now = Date.now(); + if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { + return this.update(); + } } }, selectArchives: function() { @@ -7891,7 +7895,9 @@ BoardConfig = (function() { BoardConfig = { cbs: [], init: function() { - if ((Conf['boardConfig'].lastChecked || 0) < Date.now() - 2 * $.HOUR) { + var now, ref; + now = Date.now(); + if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { return $.ajax('//a.4cdn.org/boards.json', { onloadend: this.load }); @@ -10068,6 +10074,8 @@ Index = (function() { }).map(function(post) { return post.no; }); + default: + return liveThreadIDs; } })(); if (Index.search && (threadIDs = Index.querySearch(Index.search))) { @@ -18172,7 +18180,7 @@ ThreadWatcher = (function() { return ThreadWatcher.clearRequests(); }, fetchAuto: function() { - var db, interval, now; + var db, interval, now, ref; clearTimeout(ThreadWatcher.timeout); if (!Conf['Auto Update Thread Watcher']) { return; @@ -18180,7 +18188,7 @@ ThreadWatcher = (function() { db = ThreadWatcher.db; interval = ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] ? 5 * $.MINUTE : 2 * $.HOUR; now = Date.now(); - if (now >= (db.data.lastChecked || 0) + interval) { + if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now))) { ThreadWatcher.fetchAllStatus(); db.data.lastChecked = now; db.save(); diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 2e4e8120d..ae5b5ec53 100644 Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js index c06ecc7c7..0f02249a4 100644 --- a/builds/4chan-X-noupdate.user.js +++ b/builds/4chan-X-noupdate.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.0.17 +// @version 1.13.0.18 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.0.17', + VERSION: '1.13.0.18', NAMESPACE: '4chan X.', boards: {} }; @@ -5321,7 +5321,7 @@ DataBoard = (function() { }; DataBoard.prototype.clean = function() { - var boardID, now, ref, val; + var boardID, now, ref, ref1, val; $.forceSync(this.key); ref = this.data.boards; for (boardID in ref) { @@ -5331,7 +5331,7 @@ DataBoard = (function() { }); } now = Date.now(); - if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) { + if (!((now - 2 * $.HOUR < (ref1 = this.data.lastChecked || 0) && ref1 <= now))) { this.data.lastChecked = now; for (boardID in this.data.boards) { this.ajaxClean(boardID); @@ -6617,9 +6617,13 @@ Redirect = (function() { { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": false, "software": "foolfuuka", "boards": [ "h", "hc", "hm", "r", "s", "soc" ], "files": [ "h", "hc", "hm", "r", "s", "soc" ] } ], init: function() { + var now, ref; this.selectArchives(); - if (Conf['archiveAutoUpdate'] && Conf['lastarchivecheck'] < Date.now() - 2 * $.DAY) { - return this.update(); + if (Conf['archiveAutoUpdate']) { + now = Date.now(); + if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { + return this.update(); + } } }, selectArchives: function() { @@ -7891,7 +7895,9 @@ BoardConfig = (function() { BoardConfig = { cbs: [], init: function() { - if ((Conf['boardConfig'].lastChecked || 0) < Date.now() - 2 * $.HOUR) { + var now, ref; + now = Date.now(); + if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { return $.ajax('//a.4cdn.org/boards.json', { onloadend: this.load }); @@ -10068,6 +10074,8 @@ Index = (function() { }).map(function(post) { return post.no; }); + default: + return liveThreadIDs; } })(); if (Index.search && (threadIDs = Index.querySearch(Index.search))) { @@ -18172,7 +18180,7 @@ ThreadWatcher = (function() { return ThreadWatcher.clearRequests(); }, fetchAuto: function() { - var db, interval, now; + var db, interval, now, ref; clearTimeout(ThreadWatcher.timeout); if (!Conf['Auto Update Thread Watcher']) { return; @@ -18180,7 +18188,7 @@ ThreadWatcher = (function() { db = ThreadWatcher.db; interval = ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] ? 5 * $.MINUTE : 2 * $.HOUR; now = Date.now(); - if (now >= (db.data.lastChecked || 0) + interval) { + if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now))) { ThreadWatcher.fetchAllStatus(); db.data.lastChecked = now; db.save(); diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 09ebb78fd..8b6461861 100644 Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index f94c9d2a1..74a191934 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.0.17 +// @version 1.13.0.18 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 0bfd0ed3d..e6a706f52 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.13.0.17 +// @version 1.13.0.18 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -147,7 +147,7 @@ docSet = function() { }; g = { - VERSION: '1.13.0.17', + VERSION: '1.13.0.18', NAMESPACE: '4chan X.', boards: {} }; @@ -5321,7 +5321,7 @@ DataBoard = (function() { }; DataBoard.prototype.clean = function() { - var boardID, now, ref, val; + var boardID, now, ref, ref1, val; $.forceSync(this.key); ref = this.data.boards; for (boardID in ref) { @@ -5331,7 +5331,7 @@ DataBoard = (function() { }); } now = Date.now(); - if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) { + if (!((now - 2 * $.HOUR < (ref1 = this.data.lastChecked || 0) && ref1 <= now))) { this.data.lastChecked = now; for (boardID in this.data.boards) { this.ajaxClean(boardID); @@ -6617,9 +6617,13 @@ Redirect = (function() { { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": false, "software": "foolfuuka", "boards": [ "h", "hc", "hm", "r", "s", "soc" ], "files": [ "h", "hc", "hm", "r", "s", "soc" ] } ], init: function() { + var now, ref; this.selectArchives(); - if (Conf['archiveAutoUpdate'] && Conf['lastarchivecheck'] < Date.now() - 2 * $.DAY) { - return this.update(); + if (Conf['archiveAutoUpdate']) { + now = Date.now(); + if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { + return this.update(); + } } }, selectArchives: function() { @@ -7891,7 +7895,9 @@ BoardConfig = (function() { BoardConfig = { cbs: [], init: function() { - if ((Conf['boardConfig'].lastChecked || 0) < Date.now() - 2 * $.HOUR) { + var now, ref; + now = Date.now(); + if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { return $.ajax('//a.4cdn.org/boards.json', { onloadend: this.load }); @@ -10068,6 +10074,8 @@ Index = (function() { }).map(function(post) { return post.no; }); + default: + return liveThreadIDs; } })(); if (Index.search && (threadIDs = Index.querySearch(Index.search))) { @@ -18172,7 +18180,7 @@ ThreadWatcher = (function() { return ThreadWatcher.clearRequests(); }, fetchAuto: function() { - var db, interval, now; + var db, interval, now, ref; clearTimeout(ThreadWatcher.timeout); if (!Conf['Auto Update Thread Watcher']) { return; @@ -18180,7 +18188,7 @@ ThreadWatcher = (function() { db = ThreadWatcher.db; interval = ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] ? 5 * $.MINUTE : 2 * $.HOUR; now = Date.now(); - if (now >= (db.data.lastChecked || 0) + interval) { + if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now))) { ThreadWatcher.fetchAllStatus(); db.data.lastChecked = now; db.save(); diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index a6c41352e..e01ecfaa1 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml index 47991ee2f..806732ec1 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@ - + diff --git a/builds/updates.xml b/builds/updates.xml index 7160ceab2..6cb5fae3f 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/index.html b/index.html index aec98a9f2..fb5f73ed9 100644 --- a/index.html +++ b/index.html @@ -17,8 +17,8 @@ Screenshot -

Adds various features to 4chan. -Previously developed by aeosynth, Mayhem, ihavenoface, Zixaphir, Seaweed, and Spittie, with contributions from many others.

+

4chan X is an unofficial script written by users of 4chan to add various features to the site.

+

It was previously developed by aeosynth, Mayhem, ihavenoface, Zixaphir, Seaweed, and Spittie, with contributions from many others.

If you're looking for a maintained fork of OneeChan (a style script used in addition to 4chan X), try https://github.com/Nebukazar/OneeChan.

Please note

diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index fb847bc84..82b8bb296 100644 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -9,7 +9,9 @@ Redirect = init: -> @selectArchives() - @update() if Conf['archiveAutoUpdate'] and Conf['lastarchivecheck'] < Date.now() - 2 * $.DAY + if Conf['archiveAutoUpdate'] + now = Date.now() + @update() unless now - 2 * $.DAY < Conf['lastarchivecheck'] <= now selectArchives: -> o = diff --git a/src/General/BoardConfig.coffee b/src/General/BoardConfig.coffee index 721283edc..206d78d49 100644 --- a/src/General/BoardConfig.coffee +++ b/src/General/BoardConfig.coffee @@ -2,7 +2,8 @@ BoardConfig = cbs: [] init: -> - if (Conf['boardConfig'].lastChecked or 0) < Date.now() - 2 * $.HOUR + now = Date.now() + unless now - 2 * $.HOUR < (Conf['boardConfig'].lastChecked or 0) <= now $.ajax '//a.4cdn.org/boards.json', onloadend: @load else diff --git a/src/General/Get.coffee b/src/General/Get.coffee index 1834f2830..240760d1d 100644 --- a/src/General/Get.coffee +++ b/src/General/Get.coffee @@ -18,7 +18,7 @@ Get = index = root.dataset.clone if index then post.clones[index] else post postFromNode: (root) -> - Get.postFromRoot $.x '(ancestor::div[contains(@class,"postContainer")][1]|following::div[contains(@class,"postContainer")][1])', root + Get.postFromRoot $.x 'ancestor::div[contains(@class,"postContainer")][1]', root postDataFromLink: (link) -> if link.hostname is 'boards.4chan.org' path = link.pathname.split /\/+/ diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 6eeda43a3..9beefd233 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -95,17 +95,20 @@ Index = @hideLabel = $ '#hidden-label', @navLinks $.on $('#hidden-toggle a', @navLinks), 'click', @cb.toggleHiddenThreads - # Drop-down menus + # Drop-down menus and reverse sort toggle + @selectRev = $ '#index-rev', @navLinks @selectMode = $ '#index-mode', @navLinks @selectSort = $ '#index-sort', @navLinks @selectSize = $ '#index-size', @navLinks + $.on @selectRev, 'change', @cb.sort $.on @selectMode, 'change', @cb.mode $.on @selectSort, 'change', @cb.sort $.on @selectSize, 'change', $.cb.value $.on @selectSize, 'change', @cb.size for select in [@selectMode, @selectSize] select.value = Conf[select.name] - @selectSort.value = Index.currentSort + @selectRev.checked = /-rev$/.test Index.currentSort + @selectSort.value = Index.currentSort.replace /-rev$/, '' # Thread container @root = $.el 'div', className: 'board json-index' @@ -252,7 +255,8 @@ Index = Index.pageLoad false sort: -> - Index.pushState {sort: @value} + value = if Index.selectRev.checked then Index.selectSort.value + "-rev" else Index.selectSort.value + Index.pushState {sort: value} Index.pageLoad false resort: (e) -> @@ -342,12 +346,12 @@ Index = 'all-pages': 'all pages' 'catalog': 'catalog' sort: - 'bump-order': 'bump' - 'last-reply': 'lastreply' - 'last-long-reply': 'lastlong' - 'creation-date': 'birth' - 'reply-count': 'replycount' - 'file-count': 'filecount' + 'bump-order': 'bump' + 'last-reply': 'lastreply' + 'last-long-reply': 'lastlong' + 'creation-date': 'birth' + 'reply-count': 'replycount' + 'file-count': 'filecount' processHash: -> # XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304 @@ -362,8 +366,9 @@ Index = else if command is 'index' state.mode = Conf['Previous Index Mode'] state.page = 1 - else if (sort = Index.hashCommands.sort[command]) + else if (sort = Index.hashCommands.sort[command.replace(/-rev$/, '')]) state.sort = sort + state.sort += '-rev' if /-rev$/.test(command) else if /^s=/.test command state.search = decodeURIComponent(command[2..]).replace(/\+/g, ' ').trim() else @@ -446,7 +451,8 @@ Index = $('#hidden-toggle a', Index.navLinks).textContent = 'Show' setupSort: -> - Index.selectSort.value = Index.currentSort + Index.selectRev.checked = /-rev$/.test Index.currentSort + Index.selectSort.value = Index.currentSort.replace /-rev$/, '' getPagesNum: -> if Index.search @@ -744,7 +750,7 @@ Index = sort: -> {liveThreadIDs, liveThreadData} = Index return unless liveThreadData - Index.sortedThreadIDs = switch Index.currentSort + Index.sortedThreadIDs = switch Index.currentSort.replace(/-rev$/, '') when 'lastreply' [liveThreadData...].sort((a, b) -> a = num[num.length - 1] if (num = a.last_replies) @@ -764,6 +770,8 @@ Index = when 'replycount' then [liveThreadData...].sort((a, b) -> b.replies - a.replies).map (post) -> post.no when 'filecount' then [liveThreadData...].sort((a, b) -> b.images - a.images ).map (post) -> post.no else liveThreadIDs + if /-rev$/.test(Index.currentSort) + Index.sortedThreadIDs = [Index.sortedThreadIDs...].reverse() if Index.search and (threadIDs = Index.querySearch Index.search) Index.sortedThreadIDs = threadIDs # Sticky threads diff --git a/src/General/Index/NavLinks.html b/src/General/Index/NavLinks.html index 90d1794fc..e69e93af2 100644 --- a/src/General/Index/NavLinks.html +++ b/src/General/Index/NavLinks.html @@ -6,6 +6,7 @@ × +