From 4c139b3b0f0f554e1a4b48acf69618cbef88a7d8 Mon Sep 17 00:00:00 2001 From: ccd0 Date: Thu, 6 Dec 2018 18:20:21 -0800 Subject: [PATCH] Support refreshing 4chan threads in Thread Watcher from other sites. --- src/Monitoring/ThreadWatcher.coffee | 43 +++++++++++++++-------------- src/classes/DataBoard.coffee | 4 +-- src/css/style.css | 3 ++ src/meta/eventPage.coffee | 4 +++ src/platform/CrossOrigin.coffee | 22 +++++++++------ src/site/SW.yotsuba.coffee | 3 ++ 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 67c28f937..b9def448f 100644 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -24,8 +24,6 @@ ThreadWatcher = $.on @refreshButton, 'click', @buttonFetchAll $.on @closeButton, 'click', @toggleWatcher - @refreshButton.hidden = true unless Site.software is 'yotsuba' - @menu.addHeaderMenuEntry() $.onExists doc, 'body', @addDialog @@ -184,13 +182,12 @@ ThreadWatcher = ThreadWatcher.clearRequests() fetchAuto: -> - return unless Site.software is 'yotsuba' clearTimeout ThreadWatcher.timeout return unless Conf['Auto Update Thread Watcher'] {db} = ThreadWatcher interval = if ThreadWatcher.unreadEnabled and Conf['Show Unread Count'] then 5 * $.MINUTE else 2 * $.HOUR now = Date.now() - unless now - interval < (db.data[Site.hostname].lastChecked or 0) <= now or d.hidden or not d.hasFocus() + unless now - interval < (db.data.lastChecked or 0) <= now or d.hidden or not d.hasFocus() ThreadWatcher.fetchAllStatus() db.setLastChecked() ThreadWatcher.timeout = setTimeout ThreadWatcher.fetchAuto, interval @@ -202,7 +199,6 @@ ThreadWatcher = ThreadWatcher.fetchAllStatus() fetchAllStatus: -> - return unless Site.software is 'yotsuba' dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter((x) -> x) n = 0 for db in dbs @@ -215,18 +211,26 @@ ThreadWatcher = fetchStatus: (thread, force) -> {siteID, boardID, threadID, data} = thread - return unless Site.software is 'yotsuba' and siteID is Site.hostname + return unless Conf['siteProperties'][siteID]?.software is 'yotsuba' return if data.isDead and not force if ThreadWatcher.requests.length is 0 ThreadWatcher.status.textContent = '...' $.addClass ThreadWatcher.refreshButton, 'fa-spin' - req = $.ajax "#{location.protocol}//a.4cdn.org/#{boardID}/thread/#{threadID}.json", - onloadend: -> + url = "#{location.protocol}//a.4cdn.org/#{boardID}/thread/#{threadID}.json" + if Site.hasCORS?(url) or url.split('/')[...3].join('/') is location.origin + req = $.ajax url, + onloadend: -> + ThreadWatcher.parseStatus.call @, thread + timeout: $.MINUTE + else + req = {abort: () -> req.aborted = true} + CrossOrigin.json url, -> + return if req.aborted ThreadWatcher.parseStatus.call @, thread - timeout: $.MINUTE + , true, $.MINUTE ThreadWatcher.requests.push req - parseStatus: ({boardID, threadID, data}) -> + parseStatus: ({siteID, boardID, threadID, data}) -> ThreadWatcher.fetched++ if ThreadWatcher.fetched is ThreadWatcher.requests.length ThreadWatcher.clearRequests() @@ -237,24 +241,20 @@ ThreadWatcher = last = @response.posts[@response.posts.length-1].no isDead = !!@response.posts[0].archived if isDead and Conf['Auto Prune'] - ThreadWatcher.db.delete {boardID, threadID} + ThreadWatcher.db.delete {siteID, boardID, threadID} ThreadWatcher.refresh() return return if last is data.last and isDead is data.isDead - lastReadPost = ThreadWatcher.unreaddb.get - boardID: boardID - threadID: threadID - defaultValue: 0 - + lastReadPost = ThreadWatcher.unreaddb.get {siteID, boardID, threadID, defaultValue: 0} unread = 0 quotingYou = false - youOP = !!QuoteYou.db?.get {boardID, threadID, postID: threadID} + youOP = !!QuoteYou.db?.get {siteID, boardID, threadID, postID: threadID} for postObj in @response.posts continue unless postObj.no > lastReadPost - continue if QuoteYou.db?.get {boardID, threadID, postID: postObj.no} + continue if QuoteYou.db?.get {siteID, boardID, threadID, postID: postObj.no} unread++ @@ -268,6 +268,7 @@ ThreadWatcher = regexp = /]*\bhref="(?:(?:\/\/boards\.4chan(?:nel)?\.org)?\/([^\/]+)\/thread\/)?(\d+)?(?:#p(\d+))?"/g while match = regexp.exec postObj.com if QuoteYou.db.get { + siteID boardID: match[1] or boardID threadID: match[2] or threadID postID: match[3] or match[2] or threadID @@ -278,14 +279,14 @@ ThreadWatcher = quotingYou = true updated = (isDead isnt data.isDead or unread isnt data.unread or quotingYou isnt data.quotingYou) - ThreadWatcher.db.extend {boardID, threadID, val: {last, isDead, unread, quotingYou}} + ThreadWatcher.db.extend {siteID, boardID, threadID, val: {last, isDead, unread, quotingYou}} ThreadWatcher.refresh() if updated else if @status is 404 if Conf['Auto Prune'] - ThreadWatcher.db.delete {boardID, threadID} + ThreadWatcher.db.delete {siteID, boardID, threadID} else - ThreadWatcher.db.extend {boardID, threadID, val: {isDead: true}, rm: ['unread', 'quotingYou']} + ThreadWatcher.db.extend {siteID, boardID, threadID, val: {isDead: true}, rm: ['unread', 'quotingYou']} ThreadWatcher.refresh() diff --git a/src/classes/DataBoard.coffee b/src/classes/DataBoard.coffee index f6581dc65..ca0fa5ce3 100644 --- a/src/classes/DataBoard.coffee +++ b/src/classes/DataBoard.coffee @@ -90,9 +90,9 @@ class DataBoard @setUnsafe {siteID, boardID, threadID, postID, val: oldVal} , cb - setLastChecked: (siteID=Site.hostname) -> + setLastChecked: -> @save => - @data[siteID].lastChecked = Date.now() + @data.lastChecked = Date.now() get: ({siteID, boardID, threadID, postID, defaultValue}) -> siteID or= Site.hostname diff --git a/src/css/style.css b/src/css/style.css index 8a1dd798a..e1fbb2bfa 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1174,6 +1174,9 @@ span.hide-announcement { -webkit-flex: 0 1 auto; flex: 0 1 auto; } +.replies-quoting-you > a, #watcher-link.replies-quoting-you { + color: #F00; +} #thread-watcher a { text-decoration: none; } diff --git a/src/meta/eventPage.coffee b/src/meta/eventPage.coffee index a740cce05..6769586f1 100644 --- a/src/meta/eventPage.coffee +++ b/src/meta/eventPage.coffee @@ -26,6 +26,7 @@ ajax = (request, sender, sendResponse) -> xhr = new XMLHttpRequest() xhr.open 'GET', request.url, true xhr.responseType = request.responseType + xhr.timeout = request.timeout xhr.addEventListener 'load', -> {status, statusText, response} = @ if @readyState is @DONE && xhr.status is 200 @@ -43,4 +44,7 @@ ajax = (request, sender, sendResponse) -> xhr.addEventListener 'abort', -> chrome.tabs.sendMessage sender.tab.id, {id, error: true} , false + xhr.addEventListener 'timeout', -> + chrome.tabs.sendMessage sender.tab.id, {id, error: true} + , false xhr.send() diff --git a/src/platform/CrossOrigin.coffee b/src/platform/CrossOrigin.coffee index ae381666e..18ee05f6c 100644 --- a/src/platform/CrossOrigin.coffee +++ b/src/platform/CrossOrigin.coffee @@ -4,8 +4,8 @@ eventPageRequest = do -> chrome.runtime.onMessage.addListener (data) -> callbacks[data.id] data delete callbacks[data.id] - (url, responseType, cb) -> - chrome.runtime.sendMessage {url, responseType}, (id) -> + (url, responseType, cb, timeout) -> + chrome.runtime.sendMessage {url, responseType, timeout}, (id) -> callbacks[id] = cb <% } %> @@ -85,7 +85,7 @@ CrossOrigin = $.queueTask -> cb.call {} delete callbacks[url] - (url, cb, bypassCache) -> + (url, cb, bypassCache, timeout) -> <% if (type === 'userscript') { %> unless GM?.xmlHttpRequest? or GM_xmlhttpRequest? if bypassCache @@ -99,18 +99,20 @@ CrossOrigin = if bypassCache delete results[url] - if results[url] - cb.call results[url] - return - if callbacks[url] - callbacks[url].push cb - return + else + if results[url] + cb.call results[url] + return + if callbacks[url] + callbacks[url].push cb + return callbacks[url] = [cb] <% if (type === 'userscript') { %> (GM?.xmlHttpRequest or GM_xmlhttpRequest) method: "GET" url: url+'' + timeout: timeout onload: (xhr) -> {status, statusText} = xhr try @@ -120,6 +122,7 @@ CrossOrigin = failure url onerror: -> failure(url) onabort: -> failure(url) + ontimeout: -> failure(url) <% } %> <% if (type === 'crx') { %> eventPageRequest url, 'json', (result) -> @@ -127,4 +130,5 @@ CrossOrigin = success url, result else failure url + , timeout <% } %> diff --git a/src/site/SW.yotsuba.coffee b/src/site/SW.yotsuba.coffee index 873cde70a..787b0ea38 100644 --- a/src/site/SW.yotsuba.coffee +++ b/src/site/SW.yotsuba.coffee @@ -140,3 +140,6 @@ SW.yotsuba = for node in $$ '.prettyprint', bq $.replace node, [$.tn('[code]'), node.childNodes..., $.tn '[/code]'] return + + hasCORS: (url) -> + url.split('/')[...3].join('/') is location.protocol + '//a.4cdn.org'