Merge branch 'v3'
Conflicts: CHANGELOG.md LICENSE builds/appchan-x.user.js builds/crx/script.js src/General/Config.coffee src/General/css/style.css src/Miscellaneous/AnnouncementHiding.coffee src/Miscellaneous/InfiniScroll.coffee src/Posting/QR.coffee
This commit is contained in:
commit
e459069ae6
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,9 @@
|
||||
**Mayhem**:
|
||||
- Bugfixes
|
||||
|
||||
**Zixaphir**:
|
||||
- Bugfixes
|
||||
|
||||
### v2.9.3
|
||||
*2014-03-11*
|
||||
|
||||
@ -69,7 +75,7 @@
|
||||
<li> Filter (hiding, highlighting)
|
||||
<li> Thread Hiding
|
||||
<li> Linkify
|
||||
<li> Auto-GIF
|
||||
<li> Thumbnail Replacemenu
|
||||
<li> Image Hover
|
||||
</ul>
|
||||
- Support for the official catalog will be removed in the future, once the catalog mode for the index is deemed satisfactory.
|
||||
@ -86,7 +92,10 @@
|
||||
**Vampiricwulf**
|
||||
- Flash embedding and other Flash features.
|
||||
|
||||
**Zixaphir**
|
||||
**Zixaphir**
|
||||
- Update Custom Navigation legend to reflect index mode changes.
|
||||
- JSON Navigation now works for backlinks (when Quote Inlining is disabled) and backlink hashlinks.
|
||||
- JSON Navigation (Index, Catalog) performance improvements.
|
||||
- Added a nifty bread-crumb for the JSON Navigation.
|
||||
- Many spiffy performance, state awareness, and sanity improvements to JSON Navigation.
|
||||
- Bugfixes.
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* appchan x - Version 2.9.3 - 2014-03-11
|
||||
* appchan x - Version 2.9.3 - 2014-03-13
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,26 +0,0 @@
|
||||
<input type="search" id="index-search" class="field" placeholder="Search">
|
||||
<a id="index-search-clear" class="fa fa-times-circle" href="javascript:;"></a>
|
||||
|
||||
<time id="index-last-refresh" title="Last index refresh">...</time>
|
||||
<span id="hidden-label" hidden> — <span id="hidden-count"></span> <span id="hidden-toggle">[<a href="javascript:;">Show</a>]</span></span>
|
||||
<span style="flex:1"></span>
|
||||
<select id="index-mode" name="Index Mode">
|
||||
<option disabled>Index Mode</option>
|
||||
<option value="paged">Paged</option>
|
||||
<option value="infinite">Infinite Scrolling</option>
|
||||
<option value="all pages">All threads</option>
|
||||
<option value="catalog">Catalog</option>
|
||||
</select>
|
||||
<select id="index-sort" name="Index Sort">
|
||||
<option disabled>Index Sort</option>
|
||||
<option value="bump">Bump order</option>
|
||||
<option value="lastreply">Last reply</option>
|
||||
<option value="birth">Creation date</option>
|
||||
<option value="replycount">Reply count</option>
|
||||
<option value="filecount">File count</option>
|
||||
</select>
|
||||
<select id="index-size" name="Index Size">
|
||||
<option disabled>Image Size</option>
|
||||
<option value="small">Small</option>
|
||||
<option value="large">Large</option>
|
||||
</select>
|
||||
@ -1,4 +0,0 @@
|
||||
<button class="export">Export Settings</button>
|
||||
<button class="import">Import Settings</button>
|
||||
<button class="reset">Reset Settings</button>
|
||||
<input type="file" hidden>
|
||||
@ -1,15 +0,0 @@
|
||||
<div id="fourchanx-settings" class="dialog">
|
||||
<nav>
|
||||
<div class="sections-list"></div>
|
||||
<div class="credits">
|
||||
<a href="<%= meta.page %>" target="_blank"><%= meta.name %></a>
|
||||
|
|
||||
<a href="<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md" target="_blank">#{g.VERSION}</a>
|
||||
|
|
||||
<a href="<%= meta.repo %>blob/<%= meta.mainBranch %>/CONTRIBUTING.md#reporting-bugs-and-suggestions" target="_blank">Issues</a>
|
||||
|
|
||||
<a href="javascript:;" class="close fa fa-times" title="Close"></a>
|
||||
</div>
|
||||
</nav>
|
||||
<section></section>
|
||||
</div>
|
||||
@ -1,35 +0,0 @@
|
||||
<div>
|
||||
<input type="checkbox" id="autohide" title="Auto-hide">
|
||||
<select data-name="thread" title="Create a new thread / Reply">
|
||||
<option value="new">New thread</option>
|
||||
</select>
|
||||
<span class="move"></span>
|
||||
<a href="javascript:;" class="close fa fa-times" title="Close"></a>
|
||||
</div>
|
||||
<form>
|
||||
<div class="persona">
|
||||
<input type="button" id="dump-button" title="Dump list" value="+">
|
||||
<input data-name="name" name="name" list="list-name" placeholder="Name" class="field">
|
||||
<input data-name="email" name="email" list="list-email" placeholder="E-mail" class="field">
|
||||
<input data-name="sub" name="sub" list="list-sub" placeholder="Subject" class="field">
|
||||
</div>
|
||||
<div id="dump-list"></div>
|
||||
<a href="javascript:;" id="add-post" class="fa fa-plus" title="Add a post"></a>
|
||||
<div class="textarea">
|
||||
<textarea data-name="com" placeholder="Comment" class="field"></textarea>
|
||||
<span id="char-count"></span>
|
||||
</div>
|
||||
<div id="file-n-submit">
|
||||
<input type="file" hidden multiple>
|
||||
<input type="submit">
|
||||
<input type="button" id="qr-file-button" value="Choose files">
|
||||
<span id="qr-no-file">No selected file</span>
|
||||
<input id="qr-filename" data-name="filename" spellcheck="false">
|
||||
<span id="qr-filesize"></span>
|
||||
<a href="javascript:;" id="qr-filerm" class="fa fa-times-circle" title="Remove file"></a>
|
||||
<input type="checkbox" id="qr-file-spoiler" title="Spoiler image">
|
||||
</div>
|
||||
</form>
|
||||
<datalist id="list-name"></datalist>
|
||||
<datalist id="list-email"></datalist>
|
||||
<datalist id="list-sub"></datalist>
|
||||
@ -114,6 +114,6 @@
|
||||
"https": true,
|
||||
"withCredentials": true,
|
||||
"software": "foolfuuka",
|
||||
"boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "mlp", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
|
||||
"boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
|
||||
"files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"]
|
||||
}]
|
||||
|
||||
@ -30,13 +30,13 @@
|
||||
"font-awesome": "~4.0.3",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-bump": "~0.0.13",
|
||||
"grunt-concurrent": "~0.4.3",
|
||||
"grunt-concurrent": "~0.5.0",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-contrib-coffee": "~0.10.0",
|
||||
"grunt-contrib-compress": "~0.7.0",
|
||||
"grunt-contrib-concat": "~0.3.0",
|
||||
"grunt-contrib-copy": "~0.5.0",
|
||||
"grunt-contrib-watch": "~0.5.3",
|
||||
"grunt-contrib-watch": "~0.6.0",
|
||||
"grunt-shell": "~0.6.4",
|
||||
"load-grunt-tasks": "~0.4.0"
|
||||
},
|
||||
|
||||
@ -148,6 +148,7 @@ PostHiding =
|
||||
el: $.el 'a', href: 'javascript:;'
|
||||
order: 20
|
||||
open: (post) ->
|
||||
return false if post.isReply
|
||||
@el.textContent = if post.isHidden
|
||||
'Unhide thread'
|
||||
else
|
||||
|
||||
@ -181,7 +181,7 @@ Build =
|
||||
''
|
||||
|
||||
if isOP and g.VIEW is 'index'
|
||||
pageNum = Index.liveThreadIDs.indexOf(postID) // Index.threadsNumPerPage
|
||||
pageNum = Index.liveThreadData.keys.indexOf("#{postID}") // Index.threadsNumPerPage
|
||||
pageIcon = " <span class=page-num title='This thread is on page #{pageNum} in the original index.'>Page #{pageNum}</span>"
|
||||
replyLink = " <span>[<a href='/#{boardID}/res/#{threadID}' class=replylink>Reply</a>]</span>"
|
||||
else
|
||||
@ -237,11 +237,11 @@ Build =
|
||||
|
||||
catalogThread: (thread) ->
|
||||
{staticPath, gifIcon} = Build
|
||||
data = Index.liveThreadData[Index.liveThreadIDs.indexOf thread.ID]
|
||||
data = Index.liveThreadData[thread.ID]
|
||||
|
||||
postCount = data.replies + 1
|
||||
fileCount = data.images + !!data.ext
|
||||
pageCount = Index.liveThreadIDs.indexOf(thread.ID) // Index.threadsNumPerPage
|
||||
pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage
|
||||
|
||||
subject = if thread.OP.info.subject
|
||||
"<div class='subject'>#{thread.OP.info.subject}</div>"
|
||||
|
||||
@ -13,10 +13,6 @@ Config =
|
||||
false
|
||||
'Link to external catalog instead of the internal one.'
|
||||
]
|
||||
'Announcement Hiding': [
|
||||
true
|
||||
'Add button to hide 4chan announcements.'
|
||||
]
|
||||
'Desktop Notifications': [
|
||||
false
|
||||
'Enables desktop notifications across various <%= meta.name %> features.'
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
Header =
|
||||
init: ->
|
||||
|
||||
@menu = new UI.Menu 'header'
|
||||
|
||||
menuButton = $.el 'span',
|
||||
@ -245,25 +246,13 @@ Header =
|
||||
|
||||
setBarVisibility: (hide) ->
|
||||
Header.headerToggler.checked = hide
|
||||
$.event 'CloseMenu'
|
||||
(if hide then $.addClass else $.rmClass) Header.bar, 'autohide'
|
||||
(if hide then $.addClass else $.rmClass) doc, 'autohide'
|
||||
|
||||
toggleBarVisibility: ->
|
||||
hide = if @nodeName is 'INPUT'
|
||||
@checked
|
||||
else
|
||||
!$.hasClass Header.bar, 'autohide'
|
||||
# set checked status if called from keybind
|
||||
@checked = hide
|
||||
|
||||
$.set 'Header auto-hide', Conf['Header auto-hide'] = hide
|
||||
toggleBarVisibility: (e) ->
|
||||
hide = @checked
|
||||
Conf['Header auto-hide'] = hide
|
||||
$.set 'Header auto-hide', hide
|
||||
Header.setBarVisibility hide
|
||||
message = "The header bar will #{if hide
|
||||
'automatically hide itself.'
|
||||
else
|
||||
'remain visible.'}"
|
||||
new Notice 'info', message, 2
|
||||
|
||||
setHideBarOnScroll: (hide) ->
|
||||
Header.scrollHeaderToggler.checked = hide
|
||||
|
||||
@ -96,7 +96,7 @@ Index =
|
||||
|
||||
@searchInput = $ '#index-search', @navLinks
|
||||
|
||||
@searchTest()
|
||||
@searchTest true
|
||||
|
||||
@hideLabel = $ '#hidden-label', @navLinks
|
||||
@selectMode = $ '#index-mode', @navLinks
|
||||
@ -153,8 +153,8 @@ Index =
|
||||
$.after $.id('delform'), Index.pagelist
|
||||
$.rmClass doc, 'index-loading'
|
||||
|
||||
scroll: $.debounce 100, ->
|
||||
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (doc.scrollTop <= doc.scrollHeight - (300 + window.innerHeight)) or g.VIEW is 'thread'
|
||||
scroll: ->
|
||||
return if Index.req or Conf['Index Mode'] isnt 'infinite' or (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight)) or g.VIEW is 'thread'
|
||||
Index.pageNum = (Index.pageNum or Index.getCurrentPage()) + 1 # Avoid having to pushState to keep track of the current page
|
||||
|
||||
return Index.endNotice() if Index.pageNum >= Index.pagesNum
|
||||
@ -270,11 +270,15 @@ Index =
|
||||
{hash} = window.location
|
||||
window.location = './' + hash
|
||||
|
||||
searchTest: ->
|
||||
return unless hash = window.location.hash
|
||||
return unless match = hash.match /s=([\w]+)/
|
||||
searchTest: (init) ->
|
||||
return false unless hash = window.location.hash
|
||||
return false unless match = hash.match /s=([\w]+)/
|
||||
@searchInput.value = match[1]
|
||||
$.on d, '4chanXInitFinished', @onSearchInput
|
||||
if init
|
||||
$.on d, '4chanXInitFinished', Index.onSearchInput
|
||||
else
|
||||
Index.onSearchInput()
|
||||
return true
|
||||
|
||||
setupNavLinks: ->
|
||||
for el in $$ '.navLinks.desktop > a'
|
||||
@ -410,7 +414,7 @@ Index =
|
||||
Index.pageNav pageNum
|
||||
|
||||
pageNav: (pageNum) ->
|
||||
return if Index.currentPage is pageNum
|
||||
return if Index.currentPage is pageNum and not Index.root.parentElement
|
||||
history.pushState null, '', if pageNum is 0 then './' else pageNum
|
||||
Index.pageLoad pageNum
|
||||
|
||||
@ -475,7 +479,7 @@ Index =
|
||||
updateHideLabel: ->
|
||||
hiddenCount = 0
|
||||
for threadID, thread of g.BOARD.threads when thread.isHidden
|
||||
hiddenCount++ if thread.ID in Index.liveThreadIDs
|
||||
hiddenCount++ if thread.ID in Index.liveThreadData.keys
|
||||
unless hiddenCount
|
||||
Index.hideLabel.hidden = true
|
||||
Index.cb.toggleHiddenThreads() if Index.showHiddenThreads
|
||||
@ -496,6 +500,10 @@ Index =
|
||||
delete Index.pageNum
|
||||
Index.req?.abort()
|
||||
Index.notice?.close()
|
||||
|
||||
{sortedThreads} = Index
|
||||
if sortedThreads
|
||||
board = sortedThreads[0].board.ID
|
||||
|
||||
# This notice only displays if Index Refresh is taking too long
|
||||
now = Date.now()
|
||||
@ -507,11 +515,11 @@ Index =
|
||||
|
||||
pageNum = null if typeof pageNum isnt 'number' # event
|
||||
onload = (e) -> Index.load e, pageNum
|
||||
Index.req = $.ajax "//a.4cdn.org/#{g.BOARD}/catalog.json",
|
||||
Index.req = $.ajax "//a.4cdn.org/#{g.BOARD.ID}/catalog.json",
|
||||
onabort: onload
|
||||
onloadend: onload
|
||||
,
|
||||
whenModified: Index.board is "#{g.BOARD}"
|
||||
whenModified: board is g.BOARD.ID
|
||||
$.addClass Index.button, 'fa-spin'
|
||||
|
||||
load: (e, pageNum) ->
|
||||
@ -539,13 +547,11 @@ Index =
|
||||
|
||||
Navigate.title()
|
||||
|
||||
Index.board = "#{g.BOARD}"
|
||||
|
||||
try
|
||||
if req.status is 200
|
||||
Index.parse req.response, pageNum
|
||||
else if req.status is 304 and pageNum?
|
||||
Index.pageNav pageNum
|
||||
else if req.status is 304
|
||||
Index.pageNav pageNum or 0
|
||||
catch err
|
||||
c.error "Index failure: #{err.message}", err.stack
|
||||
# network error or non-JSON content for example.
|
||||
@ -574,26 +580,25 @@ Index =
|
||||
parseThreadList: (pages) ->
|
||||
Index.threadsNumPerPage = pages[0].threads.length
|
||||
|
||||
live = []
|
||||
live = new SimpleDict()
|
||||
i = 0
|
||||
while page = pages[i++]
|
||||
live = live.concat page.threads
|
||||
j = 0
|
||||
{threads} = page
|
||||
while thread = threads[j++]
|
||||
live.push thread.no, thread
|
||||
|
||||
data = []
|
||||
i = 0
|
||||
while thread = live[i++]
|
||||
data.push thread.no
|
||||
|
||||
Index.liveThreadData = live
|
||||
Index.liveThreadIDs = data
|
||||
Index.liveThreadData = live
|
||||
|
||||
g.BOARD.threads.forEach (thread) ->
|
||||
thread.collect() unless thread.ID in Index.liveThreadIDs
|
||||
thread.collect() unless thread.ID in Index.liveThreadData.keys
|
||||
|
||||
buildThreads: ->
|
||||
threads = []
|
||||
posts = []
|
||||
for threadData, i in Index.liveThreadData
|
||||
errors = null
|
||||
|
||||
Index.liveThreadData.forEach (threadData) ->
|
||||
threadRoot = Build.thread g.BOARD, threadData
|
||||
if thread = g.BOARD.threads[threadData.no]
|
||||
thread.setPage i // Index.threadsNumPerPage
|
||||
@ -601,52 +606,48 @@ Index =
|
||||
thread.setCount 'file', threadData.images + !!threadData.ext, threadData.imagelimit
|
||||
thread.setStatus 'Sticky', !!threadData.sticky
|
||||
thread.setStatus 'Closed', !!threadData.closed
|
||||
|
||||
else
|
||||
thread = new Thread threadData.no, g.BOARD
|
||||
threads.push thread
|
||||
continue if thread.ID of thread.posts
|
||||
|
||||
return if thread.ID of thread.posts
|
||||
|
||||
try
|
||||
posts.push new Post $('.opContainer', threadRoot), thread, g.BOARD
|
||||
|
||||
catch err
|
||||
# Skip posts that we failed to parse.
|
||||
errors = [] unless errors
|
||||
errors.push
|
||||
message: "Parsing of Thread No.#{thread} failed. Thread will be skipped."
|
||||
error: err
|
||||
Main.handleErrors errors if errors
|
||||
|
||||
Main.handleErrors errors if errors
|
||||
Main.callbackNodes Thread, threads
|
||||
Main.callbackNodes Post, posts
|
||||
Index.updateHideLabel()
|
||||
|
||||
$.event 'IndexRefresh'
|
||||
|
||||
buildHRs: (threadRoots) ->
|
||||
nodes = []
|
||||
i = 0
|
||||
while node = threadRoots[i++]
|
||||
nodes.push node, $.el 'hr'
|
||||
nodes
|
||||
|
||||
buildReplies: (threads) ->
|
||||
buildReplies: (thread) ->
|
||||
return unless Conf['Show Replies']
|
||||
posts = []
|
||||
for thread in threads
|
||||
i = Index.liveThreadIDs.indexOf thread.ID
|
||||
continue unless lastReplies = Index.liveThreadData[i].last_replies
|
||||
nodes = []
|
||||
for data in lastReplies
|
||||
if post = thread.posts[data.no]
|
||||
nodes.push post.nodes.root
|
||||
continue
|
||||
nodes.push node = Build.postFromObject data, thread.board.ID
|
||||
try
|
||||
posts.push new Post node, thread, thread.board
|
||||
catch err
|
||||
# Skip posts that we failed to parse.
|
||||
errors = [] unless errors
|
||||
errors.push
|
||||
message: "Parsing of Post No.#{data.no} failed. Post will be skipped."
|
||||
error: err
|
||||
return unless lastReplies = Index.liveThreadData[thread.ID].last_replies
|
||||
nodes = []
|
||||
for data in lastReplies
|
||||
if post = thread.posts[data.no]
|
||||
nodes.push post.nodes.root
|
||||
continue
|
||||
nodes.push node = Build.postFromObject data, thread.board.ID
|
||||
try
|
||||
posts.push new Post node, thread, thread.board
|
||||
catch err
|
||||
# Skip posts that we failed to parse.
|
||||
errors = [] unless errors
|
||||
errors.push
|
||||
message: "Parsing of Post No.#{data.no} failed. Post will be skipped."
|
||||
error: err
|
||||
$.add thread.OP.nodes.root.parentNode, nodes
|
||||
|
||||
Main.handleErrors errors if errors
|
||||
@ -679,11 +680,14 @@ Index =
|
||||
sortedThreads = []
|
||||
sortedThreadIDs = []
|
||||
|
||||
liveData = []
|
||||
Index.liveThreadData.forEach (data) -> liveData.push data
|
||||
|
||||
{
|
||||
'bump': ->
|
||||
sortedThreadIDs = Index.liveThreadIDs
|
||||
sortedThreadIDs = Index.liveThreadData.keys
|
||||
'lastreply': ->
|
||||
liveData = [Index.liveThreadData...].sort (a, b) ->
|
||||
liveData.sort (a, b) ->
|
||||
[..., a] = a.last_replies if 'last_replies' of a
|
||||
[..., b] = b.last_replies if 'last_replies' of b
|
||||
b.no - a.no
|
||||
@ -692,15 +696,17 @@ Index =
|
||||
sortedThreadIDs.push data.no
|
||||
return
|
||||
'birth': ->
|
||||
sortedThreadIDs = [Index.liveThreadIDs...].sort (a, b) -> b - a
|
||||
sortedThreadIDs = [Index.liveThreadData.keys...].sort (a, b) -> b - a
|
||||
'replycount': ->
|
||||
liveData = [Index.liveThreadData...].sort((a, b) -> b.replies - a.replies)
|
||||
liveData.sort (a, b) -> b.replies - a.replies
|
||||
i = 0
|
||||
while data = liveData[i++]
|
||||
sortedThreadIDs.push data.no
|
||||
return
|
||||
'filecount': ->
|
||||
liveData = [Index.liveThreadData...].sort((a, b) -> b.images - a.images)
|
||||
liveData = []
|
||||
Index.liveThreadData.forEach (data) -> liveData.push data
|
||||
liveData.sort (a, b) -> b.images - a.images
|
||||
i = 0
|
||||
while data = liveData[i++]
|
||||
sortedThreadIDs.push data.no
|
||||
@ -730,6 +736,7 @@ Index =
|
||||
return
|
||||
|
||||
buildIndex: (infinite) ->
|
||||
{sortedThreads} = Index
|
||||
switch Conf['Index Mode']
|
||||
when 'paged', 'infinite'
|
||||
pageNum = Index.getCurrentPage()
|
||||
@ -738,21 +745,30 @@ Index =
|
||||
Index.pageNav Index.getMaxPageNum()
|
||||
return
|
||||
threadsPerPage = Index.getThreadsNumPerPage()
|
||||
threads = Index.sortedThreads[threadsPerPage * pageNum ... threadsPerPage * (pageNum + 1)]
|
||||
nodes = []
|
||||
nodes.push thread.OP.nodes.root.parentNode for thread in threads
|
||||
Index.buildReplies threads
|
||||
nodes = Index.buildHRs nodes
|
||||
|
||||
nodes = []
|
||||
threads = []
|
||||
i = threadsPerPage * pageNum
|
||||
max = i + threadsPerPage
|
||||
while i < max and thread = sortedThreads[i++]
|
||||
threads.push thread
|
||||
nodes.push thread.OP.nodes.root.parentNode, $.el 'hr'
|
||||
Index.buildReplies thread
|
||||
|
||||
Index.buildPagelist()
|
||||
Index.setPage()
|
||||
|
||||
when 'catalog'
|
||||
nodes = Index.buildCatalogViews()
|
||||
Index.sizeCatalogViews nodes
|
||||
|
||||
else
|
||||
nodes = []
|
||||
nodes.push thread.OP.nodes.root.parentNode for thread in Index.sortedThreads
|
||||
Index.buildReplies Index.sortedThreads
|
||||
nodes = Index.buildHRs nodes
|
||||
i = 0
|
||||
while thread = sortedThreads[i++]
|
||||
nodes.push thread.OP.nodes.root.parentNode, $.el 'hr'
|
||||
Index.buildReplies thread
|
||||
|
||||
$.rmAll Index.root unless infinite
|
||||
$.add Index.root, nodes
|
||||
$.event 'IndexBuild', nodes
|
||||
|
||||
@ -11,7 +11,7 @@ Navigate =
|
||||
|
||||
@title = -> return
|
||||
|
||||
@el = $.el 'div',
|
||||
@el = $.el 'span',
|
||||
id: 'breadCrumb'
|
||||
|
||||
Thread.callbacks.push
|
||||
@ -165,14 +165,16 @@ Navigate =
|
||||
|
||||
navigate: (e) ->
|
||||
return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org'
|
||||
return if e and (e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0)) # Not simply a left click
|
||||
|
||||
if e
|
||||
if e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0) # Not simply a left click
|
||||
return
|
||||
|
||||
if @pathname is Navigate.path
|
||||
if g.VIEW is 'thread'
|
||||
ThreadUpdater.update()
|
||||
else
|
||||
Index.update()
|
||||
unless Index.searchTest()
|
||||
Index.update()
|
||||
e.preventDefault()
|
||||
return
|
||||
|
||||
|
||||
@ -77,11 +77,19 @@ body > hr {
|
||||
display: none;
|
||||
}
|
||||
/* Index Features */
|
||||
#index-menu {
|
||||
display: flex;
|
||||
}
|
||||
:root.thread #index-menu,
|
||||
:root.index-loading .navLinks,
|
||||
:root.index-loading .board,
|
||||
:root.index-loading .pagelist,
|
||||
.index #returnlink {
|
||||
:root.thread .pagelist {
|
||||
display: none;
|
||||
}
|
||||
:root:not(.catalog-mode) #index-size,
|
||||
:root:not(.catalog-mode) #index-size + .selectrice,
|
||||
.index:not(.catalog-mode) #returnlink {
|
||||
display: none;
|
||||
}
|
||||
#index-menu .selectrice {
|
||||
@ -107,23 +115,6 @@ body > hr {
|
||||
#index-search:not([data-searching]) + #index-search-clear {
|
||||
display: none;
|
||||
}
|
||||
.index #returnlink,
|
||||
.index #bottomlink,
|
||||
.thread #index-last-refresh,
|
||||
.thread #index-search-clear,
|
||||
.thread #index-search {
|
||||
display: none;
|
||||
}
|
||||
#returnlink::before,
|
||||
#bottomlink::before,
|
||||
#index-last-refresh::before {
|
||||
content: '[';
|
||||
}
|
||||
#returnlink::after,
|
||||
#bottomlink::after,
|
||||
#index-last-refresh::after {
|
||||
content: ']';
|
||||
}
|
||||
.catalog-mode .board {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
1553
src/General/css/style.css
Executable file
1553
src/General/css/style.css
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,10 @@
|
||||
<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span>
|
||||
<span class=brackets-wrap id=bottomlink><a href="#bottom">Bottom</a></span>
|
||||
<span id="index-menu">
|
||||
<input type="search" id="index-search" class="field" placeholder="Search">
|
||||
<a id="index-search-clear" class="fa fa-times-circle" href="javascript:;"></a>
|
||||
|
||||
<time id="index-last-refresh" title="Last index refresh">...</time>
|
||||
<span id="hidden-label" hidden> — <span id="hidden-count"></span> <span id="hidden-toggle">[<a href="javascript:;">Show</a>]</span></span>
|
||||
<span style='flex: 1'></span>
|
||||
<select id="index-mode" name="Index Mode">
|
||||
<option disabled>Index Mode</option>
|
||||
<option value="paged">Paged</option>
|
||||
@ -26,4 +25,6 @@
|
||||
<option value="small">Small</option>
|
||||
<option value="large">Large</option>
|
||||
</select>
|
||||
</span>
|
||||
</span>
|
||||
<span class=brackets-wrap id=returnlink><a href=.././>Return</a></span>
|
||||
<span class=brackets-wrap id=bottomlink><a href="#bottom">Bottom</a></span>
|
||||
@ -23,6 +23,8 @@ Linkify =
|
||||
|
||||
return
|
||||
|
||||
return unless Linkify.regString.test @info.comment
|
||||
|
||||
test = /[^\s'"]+/g
|
||||
space = /[\s'"]/
|
||||
|
||||
|
||||
@ -35,4 +35,5 @@ Menu =
|
||||
clone
|
||||
|
||||
toggle: (e) ->
|
||||
Menu.menu.toggle e, @, Get.postFromNode @
|
||||
fullID = $.x('ancestor::*[@data-full-i-d]', @).dataset.fullID
|
||||
Menu.menu.toggle e, @, g.posts[fullID]
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
PSAHiding =
|
||||
init: ->
|
||||
return unless Conf['Announcement Hiding']
|
||||
$.addClass doc, 'hide-announcement'
|
||||
$.on d, '4chanXInitFinished', @setup
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ ThreadStats =
|
||||
if Conf['Updater and Stats in Header']
|
||||
Header.rmShortcut @dialog
|
||||
else
|
||||
$.rm d.body, sc
|
||||
$.rm @dialog
|
||||
|
||||
clearTimeout @timeout # a possible race condition might be that this won't clear in time, but the resulting error will prevent issues anyways.
|
||||
|
||||
|
||||
@ -606,6 +606,7 @@ QR =
|
||||
|
||||
flagsInput: ->
|
||||
{nodes} = QR
|
||||
return unless nodes
|
||||
if nodes.flag
|
||||
$.rm nodes.flag
|
||||
delete nodes.flag
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user