diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 90d950df7..20466b21f 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1775,9 +1775,9 @@ $.ready(function() { var a, cs, footer; _this.footer = footer = $.id('boardNavDesktopFoot'); + $.on(a, 'click', Main.navigate); if (a = $("a[href*='/" + g.BOARD + "/']", footer)) { a.className = 'current'; - $.on(a, 'click', Index.cb.link); } cs = $.el('a', { id: 'settingsWindowLink', @@ -1808,15 +1808,19 @@ id: 'scroll-marker' }), setBoardList: function() { - var a, boardList, btn, fourchannav, fullBoardList; + var a, boardList, btn, fourchannav, fullBoardList, _i, _len, _ref; fourchannav = $.id('boardNavDesktop'); boardList = $.el('span', { id: 'board-list', innerHTML: "" }); - if (a = $("a[href*='/" + g.BOARD + "/']", boardList)) { - a.className = 'current'; - $.on(a, 'click', Index.cb.link); + _ref = $$('a', boardList); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + a = _ref[_i]; + $.on(a, 'click', Main.navigate); + if (a.pathname.split('/')[0] === g.BOARD.ID) { + a.className = 'current'; + } } fullBoardList = $('#full-board-list', boardList); btn = $('.hide-board-list-button', fullBoardList); @@ -1838,7 +1842,7 @@ } as = $$('#full-board-list a[title]', Header.bar); nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) { - var a, board, current, m, _i, _len; + var a, board, m, _i, _len; if (/^[^\w@]/.test(t)) { return $.tn(t); } @@ -1864,11 +1868,8 @@ a = as[_i]; if (a.textContent === board) { a = a.cloneNode(true); - current = $.hasClass(a, 'current'); - if (current) { - $.on(a, 'click', Index.cb.link); - } - a.textContent = /-title/.test(t) || /-replace/.test(t) && current ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent; + $.on(a, 'click', Main.navigate); + a.textContent = /-title/.test(t) || /-replace/.test(t) && $.hasClass(a, 'current') ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent; if (m = t.match(/-(index|catalog)/)) { a.dataset.only = m[1]; a.href = "//boards.4chan.org/" + board + "/"; @@ -12752,13 +12753,18 @@ 'Banner': Banner }, clean: function() { - var id, _results; - for (id in g.posts) { - delete g.posts[id]; + var id, posts, threads, _results; + posts = g.posts, threads = g.threads; + for (id in posts) { + if (posts.hasOwnProperty(id)) { + delete posts[id]; + } } _results = []; - for (id in g.threads) { - _results.push(delete g.threads[id]); + for (id in threads) { + if (threads.hasOwnProperty(id)) { + _results.push(delete threads[id]); + } } return _results; }, @@ -12775,15 +12781,82 @@ Thread.callbacks.clear(); return $.rmAll($('.board')); }, - navigate: function(context) { - var boardID, threadID, view; - boardID = context.boardID, view = context.view, threadID = context.threadID; + navigate: function(e) { + var boardID, threadID, view, _, _ref; + if (this.hostname !== 'boards.4chan.org') { + return; + } + _ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3]; + if (view === 'catalog') { + return; + } + e.preventDefault(); + if (threadID) { + view = 'thread'; + } else { + view = view || 'index'; + } + Main.clean(); if (view === g.VIEW) { - return Main.refresh(context); + if (view === 'index') { + if (boardID === g.BOARD.ID) { + return Index.update(); + } + Main.clean(); + Main.updateBoard(boardID); + return Index.update(); + } else { + return Main.refresh(context); + } } else { return Main.disconnect(); } }, + updateBoard: function(boardID) { + var onload, req; + g.BOARD = new Board(boardID); + req = null; + onload = function(e) { + var board, err, o, _i, _len, _ref; + if (e.type === 'abort') { + req.onloadend = null; + return; + } + try { + if (req.status !== 200) { + return; + } + o = JSON.parse(req.response); + _ref = o.boards; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + board = _ref[_i]; + if (board.board === boardID) { + break; + } + } + return Main.updateTitle(board); + } catch (_error) { + err = _error; + return Main.handleErrors([ + { + message: "Index Failure.", + error: err + } + ]); + } + }; + return req = $.ajax('//a.4cdn.org/boards.json', { + onabort: onload, + onloadend: onload + }); + }, + updateTitle: function(board) { + var subtitle; + if (subtitle = $('.boardSubtitle')) { + $.rm(subtitle); + } + return $('.boardTitle').innerHTML = "/" + board.board + "/ - " + board.title; + }, refresh: function(context) { var boardID, name, threadID, view, _results, _results1; boardID = context.boardID, view = context.view, threadID = context.threadID; diff --git a/builds/crx/script.js b/builds/crx/script.js index 4ba8d95fa..db5f807bd 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1785,9 +1785,9 @@ $.ready(function() { var a, cs, footer; _this.footer = footer = $.id('boardNavDesktopFoot'); + $.on(a, 'click', Main.navigate); if (a = $("a[href*='/" + g.BOARD + "/']", footer)) { a.className = 'current'; - $.on(a, 'click', Index.cb.link); } cs = $.el('a', { id: 'settingsWindowLink', @@ -1818,15 +1818,19 @@ id: 'scroll-marker' }), setBoardList: function() { - var a, boardList, btn, fourchannav, fullBoardList; + var a, boardList, btn, fourchannav, fullBoardList, _i, _len, _ref; fourchannav = $.id('boardNavDesktop'); boardList = $.el('span', { id: 'board-list', innerHTML: "" }); - if (a = $("a[href*='/" + g.BOARD + "/']", boardList)) { - a.className = 'current'; - $.on(a, 'click', Index.cb.link); + _ref = $$('a', boardList); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + a = _ref[_i]; + $.on(a, 'click', Main.navigate); + if (a.pathname.split('/')[0] === g.BOARD.ID) { + a.className = 'current'; + } } fullBoardList = $('#full-board-list', boardList); btn = $('.hide-board-list-button', fullBoardList); @@ -1848,7 +1852,7 @@ } as = $$('#full-board-list a[title]', Header.bar); nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) { - var a, board, current, m, _i, _len; + var a, board, m, _i, _len; if (/^[^\w@]/.test(t)) { return $.tn(t); } @@ -1874,11 +1878,8 @@ a = as[_i]; if (a.textContent === board) { a = a.cloneNode(true); - current = $.hasClass(a, 'current'); - if (current) { - $.on(a, 'click', Index.cb.link); - } - a.textContent = /-title/.test(t) || /-replace/.test(t) && current ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent; + $.on(a, 'click', Main.navigate); + a.textContent = /-title/.test(t) || /-replace/.test(t) && $.hasClass(a, 'current') ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent; if (m = t.match(/-(index|catalog)/)) { a.dataset.only = m[1]; a.href = "//boards.4chan.org/" + board + "/"; @@ -12726,13 +12727,18 @@ 'Banner': Banner }, clean: function() { - var id, _results; - for (id in g.posts) { - delete g.posts[id]; + var id, posts, threads, _results; + posts = g.posts, threads = g.threads; + for (id in posts) { + if (posts.hasOwnProperty(id)) { + delete posts[id]; + } } _results = []; - for (id in g.threads) { - _results.push(delete g.threads[id]); + for (id in threads) { + if (threads.hasOwnProperty(id)) { + _results.push(delete threads[id]); + } } return _results; }, @@ -12749,15 +12755,82 @@ Thread.callbacks.clear(); return $.rmAll($('.board')); }, - navigate: function(context) { - var boardID, threadID, view; - boardID = context.boardID, view = context.view, threadID = context.threadID; + navigate: function(e) { + var boardID, threadID, view, _, _ref; + if (this.hostname !== 'boards.4chan.org') { + return; + } + _ref = this.pathname.split('/'), _ = _ref[0], boardID = _ref[1], view = _ref[2], threadID = _ref[3]; + if (view === 'catalog') { + return; + } + e.preventDefault(); + if (threadID) { + view = 'thread'; + } else { + view = view || 'index'; + } + Main.clean(); if (view === g.VIEW) { - return Main.refresh(context); + if (view === 'index') { + if (boardID === g.BOARD.ID) { + return Index.update(); + } + Main.clean(); + Main.updateBoard(boardID); + return Index.update(); + } else { + return Main.refresh(context); + } } else { return Main.disconnect(); } }, + updateBoard: function(boardID) { + var onload, req; + g.BOARD = new Board(boardID); + req = null; + onload = function(e) { + var board, err, o, _i, _len, _ref; + if (e.type === 'abort') { + req.onloadend = null; + return; + } + try { + if (req.status !== 200) { + return; + } + o = JSON.parse(req.response); + _ref = o.boards; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + board = _ref[_i]; + if (board.board === boardID) { + break; + } + } + return Main.updateTitle(board); + } catch (_error) { + err = _error; + return Main.handleErrors([ + { + message: "Index Failure.", + error: err + } + ]); + } + }; + return req = $.ajax('//a.4cdn.org/boards.json', { + onabort: onload, + onloadend: onload + }); + }, + updateTitle: function(board) { + var subtitle; + if (subtitle = $('.boardSubtitle')) { + $.rm(subtitle); + } + return $('.boardTitle').innerHTML = "/" + board.board + "/ - " + board.title; + }, refresh: function(context) { var boardID, name, threadID, view, _results, _results1; boardID = context.boardID, view = context.view, threadID = context.threadID; diff --git a/src/General/Header.coffee b/src/General/Header.coffee index 13c55afa6..33cdf5da9 100755 --- a/src/General/Header.coffee +++ b/src/General/Header.coffee @@ -102,9 +102,9 @@ Header = $.ready => @footer = footer = $.id 'boardNavDesktopFoot' + $.on a, 'click', Main.navigate if a = $ "a[href*='/#{g.BOARD}/']", footer a.className = 'current' - $.on a, 'click', Index.cb.link cs = $.el 'a', id: 'settingsWindowLink' @@ -138,9 +138,10 @@ Header = boardList = $.el 'span', id: 'board-list' innerHTML: "" - if a = $ "a[href*='/#{g.BOARD}/']", boardList - a.className = 'current' - $.on a, 'click', Index.cb.link + for a in $$ 'a', boardList + $.on a, 'click', Main.navigate + if a.pathname.split('/')[0] is g.BOARD.ID + a.className = 'current' fullBoardList = $ '#full-board-list', boardList btn = $ '.hide-board-list-button', fullBoardList $.on btn, 'click', Header.toggleBoardList @@ -184,11 +185,9 @@ Header = if a.textContent is board a = a.cloneNode true - current = $.hasClass a, 'current' - if current - $.on a, 'click', Index.cb.link + $.on a, 'click', Main.navigate - a.textContent = if /-title/.test(t) or /-replace/.test(t) and current + a.textContent = if /-title/.test(t) or /-replace/.test(t) and $.hasClass a, 'current' a.title else if /-full/.test t "/#{board}/ - #{a.title}" @@ -379,6 +378,7 @@ Header = return if (Get.postFromRoot post).isHidden Header.scrollTo post + scrollTo: (root, down, needed) -> if down x = Header.getBottomOf root @@ -386,14 +386,17 @@ Header = else x = Header.getTopOf root window.scrollBy 0, x unless needed and x >= 0 + scrollToIfNeeded: (root, down) -> Header.scrollTo root, down, true + getTopOf: (root) -> {top} = root.getBoundingClientRect() if Conf['Fixed Header'] and not Conf['Bottom Header'] headRect = Header.toggle.getBoundingClientRect() top -= headRect.top + headRect.height top + getBottomOf: (root) -> {clientHeight} = doc bottom = clientHeight - root.getBoundingClientRect().bottom diff --git a/src/General/Main.coffee b/src/General/Main.coffee index a6d44859b..5efd717cd 100755 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -320,8 +320,9 @@ Main = 'Banner': Banner clean: -> - delete g.posts[id] for id of g.posts - delete g.threads[id] for id of g.threads + {posts, threads} = g + delete posts[id] for id of posts when posts.hasOwnProperty id + delete threads[id] for id of threads when threads.hasOwnProperty id disconnect: -> # Disconnect active features that _can_ be disconnected @@ -334,17 +335,69 @@ Main = # Clean the board, as we'll be dumping shit here $.rmAll $ '.board' - navigate: (context) -> + navigate: (e) -> + return unless @hostname is 'boards.4chan.org' # Lets have a good idea of what we should we should be expecting for this kind of feature - {boardID, view, threadID} = context + [_, boardID, view, threadID] = @pathname.split '/' + + return if view is 'catalog' + e.preventDefault() + + if threadID + view = 'thread' + else + view = view or 'index' + Main.clean() # Moving from thread to thread or index to index. if view is g.VIEW - Main.refresh context + if view is 'index' + if boardID is g.BOARD.ID + return Index.update() + Main.clean() + Main.updateBoard boardID + Index.update() + + else + Main.refresh context else Main.disconnect() + updateBoard: (boardID) -> + g.BOARD = new Board boardID + + req = null + + onload = (e) -> + if e.type is 'abort' + req.onloadend = null + return + + try + return unless req.status is 200 + + o = JSON.parse req.response + for board in o.boards + if board.board is boardID + break + + Main.updateTitle board + + catch err + Main.handleErrors [ + message: "Index Failure." + error: err + ] + + req = $.ajax '//a.4cdn.org/boards.json', + onabort: onload + onloadend: onload + + updateTitle: (board) -> + $.rm subtitle if subtitle = $ '.boardSubtitle' + $('.boardTitle').innerHTML = "/#{board.board}/ - #{board.title}" + refresh: (context) -> {boardID, view, threadID} = context @@ -354,6 +407,5 @@ Main = else # Refresh index features Main.features[name].index() for name of Main.features - Main.init()