Merge branch 'index'

This commit is contained in:
ccd0 2016-01-22 21:58:13 -08:00
commit 526be3737e
2 changed files with 116 additions and 117 deletions

View File

@ -1,10 +1,10 @@
Index = Index =
showHiddenThreads: false showHiddenThreads: false
changed: {}
init: -> init: ->
return if g.BOARD.ID is 'f' or !Conf['JSON Navigation'] or g.VIEW isnt 'index' return if g.BOARD.ID is 'f' or !Conf['JSON Navigation'] or g.VIEW isnt 'index'
@board = "#{g.BOARD}"
CatalogThread.callbacks.push CatalogThread.callbacks.push
name: 'Catalog Features' name: 'Catalog Features'
cb: @catalogNode cb: @catalogNode
@ -13,11 +13,13 @@ Index =
if history.state?.mode if history.state?.mode
Conf['Index Mode'] = history.state?.mode Conf['Index Mode'] = history.state?.mode
@currentPage = @getCurrentPage() @currentPage = @getCurrentPage()
@pushState @processHash()
# XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304
command: location.href.match(/#(.*)/)?[1]
replace: true
$.addClass doc, 'index-loading', "#{Conf['Index Mode'].replace /\ /g, '-'}-mode"
$.on window, 'popstate', @cb.popstate
$.on d, 'scroll', Index.scroll
# Header refresh button
@button = $.el 'a', @button = $.el 'a',
className: 'index-refresh-shortcut fa fa-refresh' className: 'index-refresh-shortcut fa fa-refresh'
title: 'Refresh' title: 'Refresh'
@ -26,6 +28,7 @@ Index =
$.on @button, 'click', -> Index.update() $.on @button, 'click', -> Index.update()
Header.addShortcut @button, 1 Header.addShortcut @button, 1
# Header "Index Navigation" submenu
repliesEntry = el: UI.checkbox 'Show Replies', 'Show replies' repliesEntry = el: UI.checkbox 'Show Replies', 'Show replies'
pinEntry = el: UI.checkbox 'Pin Watched Threads', 'Pin watched threads' pinEntry = el: UI.checkbox 'Pin Watched Threads', 'Pin watched threads'
anchorEntry = el: UI.checkbox 'Anchor Hidden Threads', 'Anchor hidden threads' anchorEntry = el: UI.checkbox 'Anchor Hidden Threads', 'Anchor hidden threads'
@ -49,30 +52,27 @@ Index =
order: 100 order: 100
subEntries: [repliesEntry, pinEntry, anchorEntry, refNavEntry] subEntries: [repliesEntry, pinEntry, anchorEntry, refNavEntry]
$.addClass doc, 'index-loading', "#{Conf['Index Mode'].replace /\ /g, '-'}-mode" # Navigation links at top of index
@root = $.el 'div', className: 'board' @navLinks = $.el 'div', className: 'navLinks json-index'
@cb.size()
@pagelist = $.el 'div', className: 'pagelist'
$.extend @pagelist, <%= importHTML('General/Index/PageList') %>
$('.cataloglink a', @pagelist).href = CatalogLinks.catalog()
@navLinks = $.el 'div', className: 'navLinks'
$.extend @navLinks, <%= importHTML('General/Index/NavLinks') %> $.extend @navLinks, <%= importHTML('General/Index/NavLinks') %>
$('.cataloglink a', @navLinks).href = CatalogLinks.catalog() $('.cataloglink a', @navLinks).href = CatalogLinks.catalog()
$('.archlistlink', @navLinks).hidden = true if g.BOARD.ID in ['b', 'trash'] $('.archlistlink', @navLinks).hidden = true if g.BOARD.ID in ['b', 'trash']
$.on $('#index-last-refresh a', @navLinks), 'click', @cb.refreshFront
# Search field
@searchInput = $ '#index-search', @navLinks @searchInput = $ '#index-search', @navLinks
@setupSearch() @setupSearch()
@hideLabel = $ '#hidden-label', @navLinks
@selectMode = $ '#index-mode', @navLinks
@selectSort = $ '#index-sort', @navLinks
@selectSize = $ '#index-size', @navLinks
$.on window, 'popstate', @cb.popstate
$.on d, 'scroll', Index.scroll
$.on @pagelist, 'click', @cb.pageNav
$.on @searchInput, 'input', @onSearchInput $.on @searchInput, 'input', @onSearchInput
$.on $('#index-last-refresh a', @navLinks), 'click', @cb.refreshFront $.on $('#index-search-clear', @navLinks), 'click', @clearSearch
$.on $('#index-search-clear', @navLinks), 'click', @clearSearch
$.on $('#hidden-toggle a', @navLinks), 'click', @cb.toggleHiddenThreads # Hidden threads toggle
@hideLabel = $ '#hidden-label', @navLinks
$.on $('#hidden-toggle a', @navLinks), 'click', @cb.toggleHiddenThreads
# Drop-down menus
@selectMode = $ '#index-mode', @navLinks
@selectSort = $ '#index-sort', @navLinks
@selectSize = $ '#index-size', @navLinks
$.on @selectMode, 'change', @cb.mode $.on @selectMode, 'change', @cb.mode
for select in [@selectMode, @selectSort, @selectSize] for select in [@selectMode, @selectSort, @selectSize]
select.value = Conf[select.name] select.value = Conf[select.name]
@ -80,13 +80,22 @@ Index =
$.on @selectSort, 'change', @cb.sort $.on @selectSort, 'change', @cb.sort
$.on @selectSize, 'change', @cb.size $.on @selectSize, 'change', @cb.size
# Thread container
@root = $.el 'div', className: 'board json-index'
@cb.size()
# Page list
@pagelist = $.el 'div', className: 'pagelist json-index'
$.extend @pagelist, <%= importHTML('General/Index/PageList') %>
$('.cataloglink a', @pagelist).href = CatalogLinks.catalog()
$.on @pagelist, 'click', @cb.pageNav
@update() @update()
$.asap (-> $('title + *', doc) or d.readyState isnt 'loading'), -> $.onExists doc, 'title + *', ->
d.title = d.title.replace /\ -\ Page\ \d+/, '' d.title = d.title.replace /\ -\ Page\ \d+/, ''
$.asap (-> $('.board > .thread > .postContainer', doc) or d.readyState isnt 'loading'), -> $.onExists doc, '.board > .thread > .postContainer, .board + *', ->
return unless Main.isThisPageLegit()
Index.hat = $ '.board > .thread > img:first-child' Index.hat = $ '.board > .thread > img:first-child'
if Index.hat if Index.hat
if Index.nodes if Index.nodes
@ -114,8 +123,7 @@ Index =
$.before topNavPos, $.el 'hr' $.before topNavPos, $.el 'hr'
$.before topNavPos, Index.navLinks $.before topNavPos, Index.navLinks
$.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), -> Main.ready ->
return unless Main.isThisPageLegit()
if pagelist = $('.pagelist') if pagelist = $('.pagelist')
$.replace pagelist, Index.pagelist $.replace pagelist, Index.pagelist
else else
@ -124,7 +132,7 @@ Index =
scroll: -> scroll: ->
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight)) return if Index.req or Conf['Index Mode'] isnt 'infinite' or (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight))
Index.pageNum = Index.getCurrentPage() unless Index.pageNum? # Avoid having to pushState to keep track of the current page Index.pageNum ?= Index.currentPage # Avoid having to pushState to keep track of the current page
pageNum = ++Index.pageNum pageNum = ++Index.pageNum
return Index.endNotice() if pageNum > Index.pagesNum return Index.endNotice() if pageNum > Index.pagesNum
@ -208,7 +216,8 @@ Index =
unless mode is 'catalog' unless mode is 'catalog'
Conf['Previous Index Mode'] = mode Conf['Previous Index Mode'] = mode
$.set 'Previous Index Mode', mode $.set 'Previous Index Mode', mode
Index.pageLoad Index.pushState {mode} Index.pushState {mode}
Index.pageLoad false
sort: -> sort: ->
Index.sort() Index.sort()
@ -234,26 +243,13 @@ Index =
popstate: (e) -> popstate: (e) ->
if e?.state if e?.state
{searched, mode} = e.state {searched, mode} = e.state
state = {}
if Index.search isnt searched
state.search = Index.search = searched
if Conf['Index Mode'] isnt mode
state.mode = mode
Index.saveMode mode
page = Index.getCurrentPage() page = Index.getCurrentPage()
if Index.currentPage isnt page Index.setState {search: searched, mode, page}
state.page = Index.currentPage = page Index.pageLoad false
if state.search? or state.mode? or state.page?
Index.pageLoad state
else else
# page load or hash change # page load or hash change
state = Index.pushState if Index.processHash()
# XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304 Index[if Conf['Refreshed Navigation'] then 'update' else 'pageLoad']()
command: location.href.match(/#(.*)/)?[1]
replace: true
scroll: true
if state.command
Index[if Conf['Refreshed Navigation'] then 'update' else 'pageLoad'] state
pageNav: (e) -> pageNav: (e) ->
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0 return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
@ -270,83 +266,86 @@ Index =
Index.userPageNav +a.pathname.split(/\/+/)[2] or 1 Index.userPageNav +a.pathname.split(/\/+/)[2] or 1
refreshFront: -> refreshFront: ->
Index.update Index.pushState {page: 1, scroll: true} Index.pushState {page: 1}
Index.update()
scrollToIndex: -> scrollToIndex: ->
Header.scrollToIfNeeded Index.navLinks Header.scrollToIfNeeded Index.navLinks
getCurrentPage: -> getCurrentPage: ->
if Conf['Index Mode'] in ['all pages', 'catalog'] +window.location.pathname.split(/\/+/)[2] or 1
1
else
+window.location.pathname.split(/\/+/)[2] or 1
userPageNav: (page) -> userPageNav: (page) ->
state = Index.pushState {page, scroll: true} Index.pushState {page}
if Conf['Refreshed Navigation'] if Conf['Refreshed Navigation']
Index.update state Index.update()
else else
Index.pageLoad state if state.page Index.pageLoad()
processHash: ->
# XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304
hash = location.href.match(/#.*/)?[0] or ''
command = hash[1..]
state =
replace: true
if command in ['paged', 'infinite', 'all-pages', 'catalog']
state.mode = command.replace /-/g, ' '
else if command is 'index'
state.mode = Conf['Previous Index Mode']
state.page = 1
else if /^s=/.test command
state.search = decodeURIComponent(command[2..]).replace(/\+/g, ' ').trim()
else
state.hash = hash
Index.pushState state
!state.hash?
pushState: (state) -> pushState: (state) ->
{pathname, hash} = location {search, hash, replace} = state
pageBeforeSearch = history.state?.oldpage pageBeforeSearch = history.state?.oldpage
if state.command? if search? and search isnt Index.search
{command} = state
if command in ['paged', 'infinite', 'all-pages', 'catalog']
state.mode = command.replace /-/g, ' '
else if command is 'index'
state.mode = Conf['Previous Index Mode']
state.page = 1
else if /^s=/.test command
state.search = decodeURIComponent(command[2..]).replace(/\+/g, ' ').trim()
hash = ''
else
delete state.command
if state.search?
{search} = state
state.page = if search then 1 else (pageBeforeSearch or 1) state.page = if search then 1 else (pageBeforeSearch or 1)
if !search if !search
pageBeforeSearch = undefined pageBeforeSearch = undefined
else if !Index.search else if !Index.search
pageBeforeSearch = Index.currentPage pageBeforeSearch = Index.currentPage
Index.search = search Index.setState state
if state.mode? pathname = if Index.currentPage is 1 then "/#{g.BOARD}/" else "/#{g.BOARD}/#{Index.currentPage}"
{mode} = state hash or= ''
delete state.mode if mode is Conf['Index Mode'] history[if replace then 'replaceState' else 'pushState']
Index.saveMode mode
state.page = 1 if mode in ['all pages', 'catalog']
hash = ''
if state.page?
{page} = state
delete state.page if page is Index.currentPage
Index.currentPage = page
pathname = if page is 1 then "/#{g.BOARD}/" else "/#{g.BOARD}/#{page}"
hash = ''
history[if state.replace then 'replaceState' else 'pushState']
mode: Conf['Index Mode'] mode: Conf['Index Mode']
searched: Index.search searched: Index.search
oldpage: pageBeforeSearch oldpage: pageBeforeSearch
, '', "#{location.protocol}//#{location.host}#{pathname}#{hash}" , '', "#{location.protocol}//#{location.host}#{pathname}#{hash}"
state
saveMode: (mode) -> setState: ({search, mode, page}) ->
unless Conf['Index Mode'] is mode if search? and search isnt Index.search
Index.changed.search = true
Index.search = search
if mode? and mode isnt Conf['Index Mode']
Index.changed.mode = true
Conf['Index Mode'] = mode Conf['Index Mode'] = mode
$.set 'Index Mode', mode $.set 'Index Mode', mode
unless mode is 'catalog' or Conf['Previous Index Mode'] is mode unless mode is 'catalog' or Conf['Previous Index Mode'] is mode
Conf['Previous Index Mode'] = mode Conf['Previous Index Mode'] = mode
$.set 'Previous Index Mode', mode $.set 'Previous Index Mode', mode
page = 1 if Conf['Index Mode'] in ['all pages', 'catalog']
if page? and page isnt Index.currentPage
Index.changed.page = true
Index.currentPage = page
pageLoad: ({sort, search, mode, scroll}) -> pageLoad: (scroll=true) ->
if sort or search? {threads, search, mode, page} = Index.changed
if threads or search
Index.sort() Index.sort()
Index.buildPagelist() Index.buildPagelist()
Index.setupSearch() if search? Index.setupSearch() if search
Index.applyMode() if mode? Index.applyMode() if mode
Index.buildIndex() if threads or search or mode or page
Index.setPage() Index.buildIndex()
Index.setPage()
Index.scrollToIndex() if scroll Index.scrollToIndex() if scroll
Index.changed = {}
applyMode: -> applyMode: ->
for mode in ['paged', 'infinite', 'all pages', 'catalog'] for mode in ['paged', 'infinite', 'all pages', 'catalog']
@ -379,7 +378,7 @@ Index =
$.add pagesRoot, nodes $.add pagesRoot, nodes
setPage: -> setPage: ->
pageNum = Index.getCurrentPage() pageNum = Index.currentPage
maxPageNum = Index.getMaxPageNum() maxPageNum = Index.getMaxPageNum()
pagesRoot = $ '.pages', Index.pagelist pagesRoot = $ '.pages', Index.pagelist
@ -418,7 +417,7 @@ Index =
else else
"#{hiddenCount} hidden threads" "#{hiddenCount} hidden threads"
update: (state) -> update: ->
Index.req?.abort() Index.req?.abort()
Index.notice?.close() Index.notice?.close()
@ -435,12 +434,12 @@ Index =
), 3 * $.SECOND - (Date.now() - now) ), 3 * $.SECOND - (Date.now() - now)
Index.req = $.ajax "//a.4cdn.org/#{g.BOARD}/catalog.json", Index.req = $.ajax "//a.4cdn.org/#{g.BOARD}/catalog.json",
onloadend: (e) -> Index.load e, state onloadend: Index.load
, ,
whenModified: 'Index' whenModified: 'Index'
$.addClass Index.button, 'fa-spin' $.addClass Index.button, 'fa-spin'
load: (e, state) -> load: (e) ->
$.rmClass Index.button, 'fa-spin' $.rmClass Index.button, 'fa-spin'
{req, notice, nTimeout} = Index {req, notice, nTimeout} = Index
clearTimeout nTimeout if nTimeout clearTimeout nTimeout if nTimeout
@ -465,9 +464,9 @@ Index =
try try
if req.status is 200 if req.status is 200
Index.parse req.response, state Index.parse req.response
else if req.status is 304 and state? else if req.status is 304
Index.pageLoad state Index.pageLoad()
catch err catch err
c.error "Index failure: #{err.message}", err.stack c.error "Index failure: #{err.message}", err.stack
# network error or non-JSON content for example. # network error or non-JSON content for example.
@ -490,15 +489,13 @@ Index =
timeEl = $ '#index-last-refresh time', Index.navLinks timeEl = $ '#index-last-refresh time', Index.navLinks
timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified' timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified'
RelativeDates.update timeEl RelativeDates.update timeEl
Index.scrollToIndex()
parse: (pages, state) -> parse: (pages) ->
$.cleanCache (url) -> /^\/\/a\.4cdn\.org\//.test url $.cleanCache (url) -> /^\/\/a\.4cdn\.org\//.test url
Index.parseThreadList pages Index.parseThreadList pages
Index.buildThreads() Index.buildThreads()
state or= {} Index.changed.threads = true
state.sort = true Index.pageLoad()
Index.pageLoad state
parseThreadList: (pages) -> parseThreadList: (pages) ->
Index.pagesNum = pages.length Index.pagesNum = pages.length
@ -637,10 +634,11 @@ Index =
i = 0 i = 0
i++ while Index.followedThreadID isnt Get.threadFromRoot(Index.sortedNodes[i]).ID i++ while Index.followedThreadID isnt Get.threadFromRoot(Index.sortedNodes[i]).ID
page = i // Index.threadsNumPerPage + 1 page = i // Index.threadsNumPerPage + 1
if page isnt Index.getCurrentPage() if page isnt Index.currentPage
Index.currentPage = page
Index.pushState {page} Index.pushState {page}
Index.setPage() Index.setPage()
nodes = Index.buildSinglePage Index.getCurrentPage() nodes = Index.buildSinglePage Index.currentPage
delete Index.pageNum delete Index.pageNum
$.rmAll Index.root $.rmAll Index.root
$.rmAll Header.hover $.rmAll Header.hover
@ -672,8 +670,8 @@ Index =
Index.onSearchInput() Index.onSearchInput()
Index.searchInput.focus() Index.searchInput.focus()
setupSearch: (noUpdate) -> setupSearch: ->
Index.searchInput.value = Index.search unless noUpdate Index.searchInput.value = Index.search
if Index.search if Index.search
Index.searchInput.dataset.searching = 1 Index.searchInput.dataset.searching = 1
else else
@ -683,9 +681,10 @@ Index =
onSearchInput: -> onSearchInput: ->
search = Index.searchInput.value.trim() search = Index.searchInput.value.trim()
return if search is Index.search return if search is Index.search
Index.pageLoad Index.pushState Index.pushState
search: search search: search
replace: !!search is !!Index.search replace: !!search is !!Index.search
Index.pageLoad false
querySearch: (query) -> querySearch: (query) ->
return unless keywords = query.toLowerCase().match /\S+/g return unless keywords = query.toLowerCase().match /\S+/g

View File

@ -638,9 +638,9 @@ div[data-checked="false"] > .suboption-list {
} }
/* Index */ /* Index */
:root.index-loading .navLinks, :root.index-loading .navLinks:not(.json-index),
:root.index-loading .board, :root.index-loading .board:not(.json-index),
:root.index-loading .pagelist, :root.index-loading .pagelist:not(.json-index),
:root.infinite-mode .pagelist, :root.infinite-mode .pagelist,
:root.all-pages-mode .pagelist, :root.all-pages-mode .pagelist,
:root.catalog-mode .pagelist, :root.catalog-mode .pagelist,