From a8209eaa89857be9eec27820a13c6e262cd6c162 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 9 Nov 2013 21:59:01 +0100 Subject: [PATCH 01/20] Add index searching. Close #1318 --- CHANGELOG.md | 8 +++++ css/style.css | 1 + html/General/Index-navlinks.html | 2 ++ src/General/Config.coffee | 56 +++++++++++++++---------------- src/General/Index.coffee | 44 ++++++++++++++++++++---- src/General/Post.coffee | 2 +- src/Miscellaneous/Keybinds.coffee | 2 +- 7 files changed, 78 insertions(+), 37 deletions(-) create mode 100644 html/General/Index-navlinks.html diff --git a/CHANGELOG.md b/CHANGELOG.md index ba2930ee9..fcc3a9335 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +- Searching in the index will now show matched OPs by: + - comment + - subject + - filename + - name + - tripcode + - e-mail + ### 3.12.1 - *2013-11-04* - The index refreshing notification will now only appear on initial page load with slow connections. diff --git a/css/style.css b/css/style.css index 7968c10b4..07d983a9d 100644 --- a/css/style.css +++ b/css/style.css @@ -363,6 +363,7 @@ a[href="javascript:;"] { } /* Index */ +:root.index-loading .navLinks, :root.index-loading .board, :root.index-loading .pagelist { display: none; diff --git a/html/General/Index-navlinks.html b/html/General/Index-navlinks.html new file mode 100644 index 000000000..3ac6b2437 --- /dev/null +++ b/html/General/Index-navlinks.html @@ -0,0 +1,2 @@ +[Catalog]  + diff --git a/src/General/Config.coffee b/src/General/Config.coffee index 715822858..e1818ec89 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -162,39 +162,39 @@ Config = usercss: '' hotkeys: # Header, QR & Options - 'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'] - 'Open empty QR': ['q', 'Open QR without post number inserted.'] - 'Open QR': ['Shift+q', 'Open QR with post number inserted.'] - 'Open settings': ['Alt+o', 'Open Settings.'] - 'Close': ['Esc', 'Close Settings, Notifications or QR.'] - 'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'] - 'Code tags': ['Alt+c', 'Insert code tags.'] - 'Eqn tags': ['Alt+e', 'Insert eqn tags.'] - 'Math tags': ['Alt+m', 'Insert math tags.'] - 'Submit QR': ['Alt+s', 'Submit post.'] + 'Toggle board list': ['Ctrl+b', 'Toggle the full board list.'] + 'Open empty QR': ['q', 'Open QR without post number inserted.'] + 'Open QR': ['Shift+q', 'Open QR with post number inserted.'] + 'Open settings': ['Alt+o', 'Open Settings.'] + 'Close': ['Esc', 'Close Settings, Notifications or QR.'] + 'Spoiler tags': ['Ctrl+s', 'Insert spoiler tags.'] + 'Code tags': ['Alt+c', 'Insert code tags.'] + 'Eqn tags': ['Alt+e', 'Insert eqn tags.'] + 'Math tags': ['Alt+m', 'Insert math tags.'] + 'Submit QR': ['Alt+s', 'Submit post.'] # Index/Thread related - 'Update': ['r', 'Refresh the index/thread.'] - 'Watch': ['w', 'Watch thread.'] + 'Update': ['r', 'Refresh the index/thread.'] + 'Watch': ['w', 'Watch thread.'] # Images - 'Expand image': ['Shift+e', 'Expand selected image.'] - 'Expand images': ['e', 'Expand all images.'] + 'Expand image': ['Shift+e', 'Expand selected image.'] + 'Expand images': ['e', 'Expand all images.'] # Board Navigation - 'Front page': ['0', 'Jump to page 0.'] - 'Open front page': ['Shift+0', 'Open page 0 in a new tab.'] - 'Next page': ['Right', 'Jump to the next page.'] - 'Previous page': ['Left', 'Jump to the previous page.'] - 'Search form': ['Ctrl+Alt+s', 'Open the search field on the board index.'] + 'Front page': ['0', 'Jump to page 0.'] + 'Open front page': ['Shift+0', 'Open page 0 in a new tab.'] + 'Next page': ['Right', 'Jump to the next page.'] + 'Previous page': ['Left', 'Jump to the previous page.'] + 'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'] # Thread Navigation - 'Next thread': ['Down', 'See next thread.'] - 'Previous thread': ['Up', 'See previous thread.'] - 'Expand thread': ['Ctrl+e', 'Expand thread.'] - 'Open thread': ['o', 'Open thread in current tab.'] - 'Open thread tab': ['Shift+o', 'Open thread in new tab.'] + 'Next thread': ['Down', 'See next thread.'] + 'Previous thread': ['Up', 'See previous thread.'] + 'Expand thread': ['Ctrl+e', 'Expand thread.'] + 'Open thread': ['o', 'Open thread in current tab.'] + 'Open thread tab': ['Shift+o', 'Open thread in new tab.'] # Reply Navigation - 'Next reply': ['j', 'Select next reply.'] - 'Previous reply': ['k', 'Select previous reply.'] - 'Deselect reply': ['Shift+d', 'Deselect reply.'] - 'Hide': ['x', 'Hide thread.'] + 'Next reply': ['j', 'Select next reply.'] + 'Previous reply': ['k', 'Select previous reply.'] + 'Deselect reply': ['Shift+d', 'Deselect reply.'] + 'Hide': ['x', 'Hide thread.'] updater: checkbox: 'Beep': [false, 'Beep on new post to completely read thread.'] diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 60dfed9e9..4591ee706 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -50,13 +50,21 @@ Index = className: 'pagelist' hidden: true innerHTML: <%= importHTML('General/Index-pagelist') %> + @navLinks = $.el 'div', + className: 'navLinks' + innerHTML: <%= importHTML('General/Index-navlinks') %> + @searchInput = $ '#index-search', @navLinks @currentPage = @getCurrentPage() $.on window, 'popstate', @cb.popstate $.on @pagelist, 'click', @cb.pageNav + $.on @searchInput, 'input', @onSearchInput $.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), -> $.replace $('.board'), Index.root $.replace $('.pagelist'), Index.pagelist $.rmClass doc, 'index-loading' + for navLink in $$ '.navLinks' + $.rm navLink + $.after $.x('child::form/preceding-sibling::hr'), Index.navLinks cb: mode: -> @@ -276,13 +284,14 @@ Index = offset = 0 for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isSticky Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)... - return unless Conf['Filter'] - # Put the highlighted thread &
on top of the index - # while keeping the original order they appear in. - offset = 0 - for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isOnTop - Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)... - return + if Conf['Filter'] + # Put the highlighted thread &
on top of the index + # while keeping the original order they appear in. + offset = 0 + for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isOnTop + Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)... + if Index.searchInput.value + Index.sortedNodes = Index.querySearch(Index.searchInput.value) or Index.sortedNodes buildIndex: -> if Conf['Index Mode'] is 'paged' pageNum = Index.getCurrentPage() @@ -294,3 +303,24 @@ Index = Index.buildReplies nodes $.event 'IndexBuild', nodes $.add Index.root, nodes + + onSearchInput: -> + Index.sort() + Index.buildIndex() + querySearch: (query) -> + return unless keywords = query.toLowerCase().match /\S+/g + Index.search keywords + search: (keywords) -> + found = [] + for threadRoot, i in Index.sortedNodes by 2 + {OP} = Get.threadFromRoot threadRoot + text = [] + for key in ['comment', 'subject', 'name', 'tripcode', 'email'] + text.push OP.info[key] if key of OP.info + text.push OP.file.name if 'file' of OP + text = text.join(' ').toLowerCase() + for keyword in keywords + continue if -1 is text.indexOf keyword + found.push Index.sortedNodes[i], Index.sortedNodes[i + 1] + break + found diff --git a/src/General/Post.coffee b/src/General/Post.coffee index 901405495..5cb484309 100644 --- a/src/General/Post.coffee +++ b/src/General/Post.coffee @@ -49,7 +49,7 @@ class Post @parseComment() @parseQuotes() - @parseFile(that) + @parseFile that @clones = [] g.posts[@fullID] = thread.posts[@] = board.posts[@] = @ diff --git a/src/Miscellaneous/Keybinds.coffee b/src/Miscellaneous/Keybinds.coffee index 5388ebc89..76d817825 100644 --- a/src/Miscellaneous/Keybinds.coffee +++ b/src/Miscellaneous/Keybinds.coffee @@ -87,7 +87,7 @@ Keybinds = return unless g.VIEW is 'index' and Conf['Index Mode'] is 'paged' $('.prev button', Index.pagelist).click() when Conf['Search form'] - $.id('search-btn').click() + Index.searchInput.focus() # Thread Navigation when Conf['Next thread'] return if g.VIEW isnt 'index' From dcdb530d1969eb8bf2c1e35d962aefa9380737e9 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 10 Nov 2013 00:58:18 +0100 Subject: [PATCH 02/20] Searches should match all keywords. --- src/General/Index.coffee | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 4591ee706..53b9b8b54 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -313,14 +313,16 @@ Index = search: (keywords) -> found = [] for threadRoot, i in Index.sortedNodes by 2 - {OP} = Get.threadFromRoot threadRoot - text = [] - for key in ['comment', 'subject', 'name', 'tripcode', 'email'] - text.push OP.info[key] if key of OP.info - text.push OP.file.name if 'file' of OP - text = text.join(' ').toLowerCase() - for keyword in keywords - continue if -1 is text.indexOf keyword + if Index.searchMatch Get.threadFromRoot(threadRoot), keywords found.push Index.sortedNodes[i], Index.sortedNodes[i + 1] - break found + searchMatch: (thread, keywords) -> + {info, file} = thread.OP + text = [] + for key in ['comment', 'subject', 'name', 'tripcode', 'email'] + text.push info[key] if key of info + text.push file.name if file + text = text.join(' ').toLowerCase() + for keyword in keywords + return false if -1 is text.indexOf keyword + return true From bd2fe915eb9f39f53118ab62f44a08bcae4dcdd8 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sun, 10 Nov 2013 21:01:23 +0100 Subject: [PATCH 03/20] Fix position of navlinks on Firefox. --- src/General/Index.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 53b9b8b54..f00b50fd5 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -64,7 +64,7 @@ Index = $.rmClass doc, 'index-loading' for navLink in $$ '.navLinks' $.rm navLink - $.after $.x('child::form/preceding-sibling::hr'), Index.navLinks + $.after $.x('child::form/preceding-sibling::hr[1]'), Index.navLinks cb: mode: -> From 564e799d31f77756376ddf458f47926801a3f6c7 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Mon, 11 Nov 2013 18:50:25 +0100 Subject: [PATCH 04/20] Indicate the elapsed time since the last index refresh at the top of the index. --- CHANGELOG.md | 3 ++- html/General/Index-navlinks.html | 1 + src/General/Index.coffee | 7 ++++++ src/Miscellaneous/RelativeDates.coffee | 34 +++++++++++++++++--------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcc3a9335..3c64ceeaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ -- Searching in the index will now show matched OPs by: +- Searching in the index is now possible and will show matched OPs by: - comment - subject - filename - name - tripcode - e-mail +- The elapsed time since the last index refresh is now indicated at the top of the index. ### 3.12.1 - *2013-11-04* diff --git a/html/General/Index-navlinks.html b/html/General/Index-navlinks.html index 3ac6b2437..dc185f087 100644 --- a/html/General/Index-navlinks.html +++ b/html/General/Index-navlinks.html @@ -1,2 +1,3 @@ +[]  [Catalog diff --git a/src/General/Index.coffee b/src/General/Index.coffee index f00b50fd5..77b10aa5f 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -192,6 +192,13 @@ Index = notice.el.lastElementChild.textContent = 'Index refreshed!' setTimeout notice.close, $.SECOND + timeEl = $ '#index-last-refresh', Index.navLinks + timeEl.dataset.utc = e.timeStamp + if timeEl.dataset.init + RelativeDates.setUpdate el: timeEl + delete timeEl.dataset.init + else + RelativeDates.flush() Index.scrollToIndex() parse: (pages) -> Index.parseThreadList pages diff --git a/src/Miscellaneous/RelativeDates.coffee b/src/Miscellaneous/RelativeDates.coffee index d678ecb23..b856a19fd 100644 --- a/src/Miscellaneous/RelativeDates.coffee +++ b/src/Miscellaneous/RelativeDates.coffee @@ -1,13 +1,17 @@ RelativeDates = INTERVAL: $.MINUTE / 2 init: -> - return if g.VIEW is 'catalog' or !Conf['Relative Post Dates'] - - # Flush when page becomes visible again or when the thread updates. - $.on d, 'visibilitychange ThreadUpdate', @flush - - # Start the timeout. - @flush() + switch g.VIEW + when 'index' + @flush() + $.on d, 'visibilitychange', @flush + return unless Conf['Relative Post Dates'] + when 'thread' + return unless Conf['Relative Post Dates'] + @flush() + $.on d, 'visibilitychange ThreadUpdate', @flush if g.VIEW is 'thread' + else + return Post.callbacks.push name: 'Relative Post Dates' @@ -21,7 +25,7 @@ RelativeDates = dateEl = @nodes.date dateEl.title = dateEl.textContent - RelativeDates.setUpdate @ + RelativeDates.setUpdate post: @ # diff is milliseconds from now. relative: (diff, now, date) -> @@ -81,7 +85,7 @@ RelativeDates = # Create function `update()`, closed over post, that, when called # from `flush()`, updates the elements, and re-calls `setOwnTimeout()` to # re-add `update()` to the stale list later. - setUpdate: (post) -> + setUpdate: ({post, el}) -> setOwnTimeout = (diff) -> delay = if diff < $.MINUTE $.SECOND - (diff + $.SECOND / 2) % $.SECOND @@ -94,11 +98,17 @@ RelativeDates = setTimeout markStale, delay update = (now) -> - {date} = post.info + date = if post + post.info.date + else + new Date +el.dataset.utc diff = now - date relative = RelativeDates.relative diff, now, date - for singlePost in [post].concat post.clones - singlePost.nodes.date.firstChild.textContent = relative + if post + for singlePost in [post].concat post.clones + singlePost.nodes.date.firstChild.textContent = relative + else + el.firstChild.textContent = RelativeDates.relative diff, now, date setOwnTimeout diff markStale = -> RelativeDates.stale.push update From 86a46f35fb10daec3dc8f23855317857d586dc5a Mon Sep 17 00:00:00 2001 From: Mayhem Date: Mon, 11 Nov 2013 21:05:35 +0100 Subject: [PATCH 05/20] Move the last refresh timer, give the "field" class to the search input. --- css/style.css | 3 +++ html/General/Index-navlinks.html | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/css/style.css b/css/style.css index 07d983a9d..6ee0d31b1 100644 --- a/css/style.css +++ b/css/style.css @@ -32,6 +32,9 @@ background-color: #F2F2F2; color: #888; } +.field::-webkit-search-decoration { + display: none; +} .move { cursor: move; } diff --git a/html/General/Index-navlinks.html b/html/General/Index-navlinks.html index dc185f087..7d3b04da7 100644 --- a/html/General/Index-navlinks.html +++ b/html/General/Index-navlinks.html @@ -1,3 +1,3 @@ -[]  [Catalog]  - +[]  + From 547e9db6a2488dfacd57b2b081f178d8c2c59a30 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Mon, 11 Nov 2013 22:32:47 +0100 Subject: [PATCH 06/20] Smaller search input by default. Hidamarize on hover/focus. --- css/style.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/css/style.css b/css/style.css index 6ee0d31b1..89639943b 100644 --- a/css/style.css +++ b/css/style.css @@ -371,6 +371,14 @@ a[href="javascript:;"] { :root.index-loading .pagelist { display: none; } +#index-search { + width: 100px; + transition: color .25s, border-color .25s, width .25s; +} +#index-search:hover, +#index-search:focus { + width: 200px; +} .summary { text-decoration: none; } From 46e3414ec9cf83a5818f18f5e3af5c9f86127605 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Wed, 13 Nov 2013 12:35:45 +0100 Subject: [PATCH 07/20] Fix spacing issue for the top right link of the settings. --- html/General/Settings.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/html/General/Settings.html b/html/General/Settings.html index 8ee5f006b..9a94ccc59 100644 --- a/html/General/Settings.html +++ b/html/General/Settings.html @@ -2,9 +2,12 @@ From e9a128da704726397f2c15853c6494cbc1128528 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 01:31:01 +0100 Subject: [PATCH 08/20] Add search-clearing button. --- css/style.css | 12 ++++++++++-- html/General/Index-navlinks.html | 1 + src/General/Index.coffee | 11 ++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/css/style.css b/css/style.css index 89639943b..56a6a5d31 100644 --- a/css/style.css +++ b/css/style.css @@ -372,13 +372,21 @@ a[href="javascript:;"] { display: none; } #index-search { + padding-right: 1.5em; width: 100px; transition: color .25s, border-color .25s, width .25s; } -#index-search:hover, -#index-search:focus { +#index-search[data-searching] { width: 200px; } +#index-search-clear { + color: gray; + margin-left: -1.25em; +} +#index-search::-webkit-search-cancel-button, +#index-search:not([data-searching]) + #index-search-clear { + display: none; +} .summary { text-decoration: none; } diff --git a/html/General/Index-navlinks.html b/html/General/Index-navlinks.html index 7d3b04da7..cb69adae9 100644 --- a/html/General/Index-navlinks.html +++ b/html/General/Index-navlinks.html @@ -1,3 +1,4 @@ [Catalog]  [ + diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 77b10aa5f..5a492f7fe 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -58,6 +58,7 @@ Index = $.on window, 'popstate', @cb.popstate $.on @pagelist, 'click', @cb.pageNav $.on @searchInput, 'input', @onSearchInput + $.on $('#index-search-clear', @navLinks), 'click', @clearSearch $.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), -> $.replace $('.board'), Index.root $.replace $('.pagelist'), Index.pagelist @@ -297,7 +298,7 @@ Index = offset = 0 for threadRoot, i in Index.sortedNodes by 2 when Get.threadFromRoot(threadRoot).isOnTop Index.sortedNodes.splice offset++ * 2, 0, Index.sortedNodes.splice(i, 2)... - if Index.searchInput.value + if Index.isSearching Index.sortedNodes = Index.querySearch(Index.searchInput.value) or Index.sortedNodes buildIndex: -> if Conf['Index Mode'] is 'paged' @@ -311,7 +312,15 @@ Index = $.event 'IndexBuild', nodes $.add Index.root, nodes + isSearching: false + clearSearch: -> + Index.searchInput.value = null + Index.onSearchInput() onSearchInput: -> + if Index.isSearching = !!Index.searchInput.value.trim() + Index.searchInput.dataset.searching = 1 + else + delete Index.searchInput.dataset.searching Index.sort() Index.buildIndex() querySearch: (query) -> From 91dd12213e360cbc9bad4fe6f30a23bc7dbc3dad Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 02:34:13 +0100 Subject: [PATCH 09/20] Focus the index search input after clearing it. --- src/General/Index.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 5a492f7fe..eb19cd87b 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -316,6 +316,7 @@ Index = clearSearch: -> Index.searchInput.value = null Index.onSearchInput() + Index.searchInput.focus() onSearchInput: -> if Index.isSearching = !!Index.searchInput.value.trim() Index.searchInput.dataset.searching = 1 From 67e75bd2fb78eeb8819bba0d24916852b67bcb29 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 17:18:36 +0100 Subject: [PATCH 10/20] Prevent content inside of .board from being downloaded on intial page load. See comments in the code. --- src/General/Index.coffee | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index eb19cd87b..070671247 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -59,13 +59,24 @@ Index = $.on @pagelist, 'click', @cb.pageNav $.on @searchInput, 'input', @onSearchInput $.on $('#index-search-clear', @navLinks), 'click', @clearSearch - $.asap (-> $('.pagelist', doc) or d.readyState isnt 'loading'), -> - $.replace $('.board'), Index.root - $.replace $('.pagelist'), Index.pagelist - $.rmClass doc, 'index-loading' + $.asap (-> $('.board', doc) or d.readyState isnt 'loading'), -> + board = $ '.board' + $.replace board, Index.root + # Hacks: + # - When removing an element from the document during page load, + # its ancestors will still be correctly created inside of it. + # - Creating loadable elements inside of an origin-less document + # will not download them. + # - Combine the two and you get a download canceller! + # Does not work on Firefox unfortunately. + d.implementation.createDocument(null, null, null).appendChild board + for navLink in $$ '.navLinks' $.rm navLink $.after $.x('child::form/preceding-sibling::hr[1]'), Index.navLinks + $.rmClass doc, 'index-loading' + $.asap (-> $('.pagelist') or d.readyState isnt 'loading'), -> + $.replace $('.pagelist'), Index.pagelist cb: mode: -> From 2248e4de165e5cb43ca7b518c813d39e83d399e6 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 18:07:38 +0100 Subject: [PATCH 11/20] Fix the index search clear button appearance on Firefox. --- css/style.css | 3 +++ src/General/Index.coffee | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/css/style.css b/css/style.css index 56a6a5d31..0718196fd 100644 --- a/css/style.css +++ b/css/style.css @@ -383,7 +383,10 @@ a[href="javascript:;"] { color: gray; margin-left: -1.25em; } +<% if (type === 'crx') { %> +/* ``::-webkit-*'' selectors break selector lists on Firefox. */ #index-search::-webkit-search-cancel-button, +<% } %> #index-search:not([data-searching]) + #index-search-clear { display: none; } diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 070671247..866067d0d 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -332,7 +332,12 @@ Index = if Index.isSearching = !!Index.searchInput.value.trim() Index.searchInput.dataset.searching = 1 else + <% if (type === 'userscript') { %> + # XXX https://github.com/greasemonkey/greasemonkey/issues/1571 + Index.searchInput.removeAttribute 'data-searching' + <% } else { %> delete Index.searchInput.dataset.searching + <% } %> Index.sort() Index.buildIndex() querySearch: (query) -> From ac7b7661ca459e5e3b2a76b48037a9bb38421e3f Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 18:47:46 +0100 Subject: [PATCH 12/20] Jump to page zero when starting to search. Jump back to the previous page when clearing the search. --- src/General/Index.coffee | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 866067d0d..2545b9ad3 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -330,8 +330,13 @@ Index = Index.searchInput.focus() onSearchInput: -> if Index.isSearching = !!Index.searchInput.value.trim() - Index.searchInput.dataset.searching = 1 + unless Index.searchInput.dataset.searching + Index.searchInput.dataset.searching = 1 + Index.pageBeforeSearch = Index.getCurrentPage() + pageNum = 0 else + pageNum = Index.pageBeforeSearch + delete Index.pageBeforeSearch <% if (type === 'userscript') { %> # XXX https://github.com/greasemonkey/greasemonkey/issues/1571 Index.searchInput.removeAttribute 'data-searching' @@ -339,7 +344,10 @@ Index = delete Index.searchInput.dataset.searching <% } %> Index.sort() - Index.buildIndex() + if Index.currentPage is pageNum + Index.buildIndex() + else + Index.pageNav pageNum querySearch: (query) -> return unless keywords = query.toLowerCase().match /\S+/g Index.search keywords From 07bca42d637de58c0434e810445250c81b65e7cf Mon Sep 17 00:00:00 2001 From: Mayhem Date: Fri, 15 Nov 2013 21:04:49 +0100 Subject: [PATCH 13/20] Rebuild the pagelist when searching. --- src/General/Index.coffee | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 2545b9ad3..437103501 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -117,31 +117,39 @@ Index = Index.setPage() Index.scrollToIndex() + getPagesNum: -> + if Index.isSearching + Math.ceil (Index.sortedNodes.length / 2) / Index.threadsNumPerPage + else + Index.pagesNum + getMaxPageNum: -> + Math.max 0, Index.getPagesNum() - 1 togglePagelist: -> Index.pagelist.hidden = Conf['Index Mode'] isnt 'paged' buildPagelist: -> pagesRoot = $ '.pages', Index.pagelist - if pagesRoot.childElementCount isnt Index.pagesNum + maxPageNum = Index.getMaxPageNum() + if pagesRoot.childElementCount isnt maxPageNum + 1 nodes = [] - for i in [0..Index.pagesNum - 1] + for i in [0..maxPageNum] by 1 a = $.el 'a', textContent: i href: if i then i else './' nodes.push $.tn('['), a, $.tn '] ' $.rmAll pagesRoot $.add pagesRoot, nodes - Index.setPage() Index.togglePagelist() setPage: -> - pageNum = Index.getCurrentPage() - pagesRoot = $ '.pages', Index.pagelist + pageNum = Index.getCurrentPage() + maxPageNum = Index.getMaxPageNum() + pagesRoot = $ '.pages', Index.pagelist # Previous/Next buttons prev = pagesRoot.previousSibling.firstChild next = pagesRoot.nextSibling.firstChild href = Math.max pageNum - 1, 0 prev.href = if href is 0 then './' else href prev.firstChild.disabled = href is pageNum - href = Math.min pageNum + 1, Index.pagesNum - 1 + href = Math.min pageNum + 1, maxPageNum next.href = if href is 0 then './' else href next.firstChild.disabled = href is pageNum # current page @@ -218,6 +226,7 @@ Index = Index.sort() Index.buildIndex() Index.buildPagelist() + Index.setPage() parseThreadList: (pages) -> Index.pagesNum = pages.length Index.threadsNumPerPage = pages[0].threads.length @@ -334,6 +343,8 @@ Index = Index.searchInput.dataset.searching = 1 Index.pageBeforeSearch = Index.getCurrentPage() pageNum = 0 + else + pageNum = Index.getCurrentPage() else pageNum = Index.pageBeforeSearch delete Index.pageBeforeSearch @@ -344,8 +355,12 @@ Index = delete Index.searchInput.dataset.searching <% } %> Index.sort() + # Go to the last available page if we were past the limit. + pageNum = Math.min pageNum, Index.getMaxPageNum() if Conf['Index Mode'] is 'paged' + Index.buildPagelist() if Index.currentPage is pageNum Index.buildIndex() + Index.setPage() else Index.pageNav pageNum querySearch: (query) -> From 8afcac8d6fb0b04027901678c89afc0a565915c6 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 00:09:08 +0100 Subject: [PATCH 14/20] Add the `Show replies` index setting. --- CHANGELOG.md | 20 ++++++++++++-------- src/General/Build.coffee | 9 +++++++-- src/General/Config.coffee | 1 + src/General/Index.coffee | 15 +++++++++++++-- src/Miscellaneous/ExpandThread.coffee | 19 +++++++++++-------- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c64ceeaa..f5e83939d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,15 @@ -- Searching in the index is now possible and will show matched OPs by: - - comment - - subject - - filename - - name - - tripcode - - e-mail -- The elapsed time since the last index refresh is now indicated at the top of the index. +- More index navigation improvements: + - Searching in the index is now possible and will show matched OPs by: +
    +
  • comment +
  • subject +
  • filename +
  • name +
  • tripcode +
  • e-mail +
+ - The elapsed time since the last index refresh is now indicated at the top of the index. + - New setting: `Show replies`, enabled by default. Disable it to only show OPs in the index. ### 3.12.1 - *2013-11-04* diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 6fe60021b..31fbea6a9 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -279,8 +279,13 @@ Build = id: "t#{data.no}" nodes = [if OP then OP.nodes.root else Build.postFromObject data, board.ID] - if data.omitted_posts - nodes.push Build.summary board.ID, data.no, data.omitted_posts, data.omitted_images + if data.omitted_posts or !Conf['Show Replies'] and data.replies + [posts, files] = if Conf['Show Replies'] + [data.omitted_posts, data.omitted_images] + else + # XXX data.images is not accurate. + [data.replies, data.omitted_images + data.last_replies.filter((data) -> !!data.ext).length] + nodes.push Build.summary board.ID, data.no, posts, files $.add root, nodes root diff --git a/src/General/Config.coffee b/src/General/Config.coffee index e1818ec89..de55119ff 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -142,6 +142,7 @@ Config = Index: 'Index Mode': 'paged' 'Index Sort': 'bump' + 'Show Replies': true Header: 'Header auto-hide': false 'Bottom header': false diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 437103501..251d6efe8 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -36,12 +36,19 @@ Index = $.on input, 'change', $.cb.value $.on input, 'change', @cb.sort + repliesEntry = + el: $.el 'label', innerHTML: ' Show replies' + input = repliesEntry.el.firstChild + input.checked = Conf['Show Replies'] + $.on input, 'change', $.cb.checked + $.on input, 'change', @cb.replies + $.event 'AddMenuEntry', type: 'header' el: $.el 'span', textContent: 'Index Navigation' order: 90 - subEntries: [modeEntry, sortEntry] + subEntries: [modeEntry, sortEntry, repliesEntry] $.addClass doc, 'index-loading' @update() @@ -85,6 +92,10 @@ Index = sort: -> Index.sort() Index.buildIndex() + replies: -> + Index.buildThreads() + Index.sort() + Index.buildIndex() popstate: (e) -> pageNum = Index.getCurrentPage() Index.pageLoad pageNum if Index.currentPage isnt pageNum @@ -328,7 +339,7 @@ Index = else nodes = Index.sortedNodes $.rmAll Index.root - Index.buildReplies nodes + Index.buildReplies nodes if Conf['Show Replies'] $.event 'IndexBuild', nodes $.add Index.root, nodes diff --git a/src/Miscellaneous/ExpandThread.coffee b/src/Miscellaneous/ExpandThread.coffee index 608572cf7..086f76d8d 100644 --- a/src/Miscellaneous/ExpandThread.coffee +++ b/src/Miscellaneous/ExpandThread.coffee @@ -50,16 +50,19 @@ ExpandThread = a.textContent = ExpandThread.text '+', a.textContent.match(/\d+/g)... if a return - num = if thread.isSticky - 1 - else switch g.BOARD.ID - # XXX boards config - when 'b', 'vg' then 3 - when 't' then 1 - else 5 + replies = $$ '.thread > .replyContainer', threadRoot + if Conf['Show Replies'] + num = if thread.isSticky + 1 + else switch g.BOARD.ID + # XXX boards config + when 'b', 'vg' then 3 + when 't' then 1 + else 5 + replies = replies[...-num] postsCount = 0 filesCount = 0 - for reply in $$('.thread > .replyContainer', threadRoot)[...-num] + for reply in replies # rm clones inlined.click() while inlined = $ '.inlined', reply if Conf['Quote Inlining'] postsCount++ From e7dfbf776baa28072b1edd5ed12119e3b0bcf70d Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 01:10:24 +0100 Subject: [PATCH 15/20] Add a page indicator on OPs in the index. --- CHANGELOG.md | 6 ++++++ src/General/Build.coffee | 9 ++++++--- src/General/Index.coffee | 3 ++- src/General/Thread.coffee | 5 +++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5e83939d..39c35a577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@
  • tripcode
  • e-mail + - The page number on which threads are will now be displayed in OPs, to easily identify where threads are located when: +
      +
    • searching through the index. +
    • using different index sorting types. +
    • threads highlighted by the filter are moved to the top and move other threads down. +
        - The elapsed time since the last index refresh is now indicated at the top of the index. - New setting: `Show replies`, enabled by default. Disable it to only show OPs in the index. diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 31fbea6a9..9fbcf6315 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -190,10 +190,12 @@ Build = else '' - replyLink = if isOP and g.VIEW is 'index' - "   [Reply]" + if isOP and g.VIEW is 'index' + pageNum = Math.floor Index.liveThreadIDs.indexOf(postID) / Index.threadsNumPerPage + pageIcon = " #{pageNum} " + replyLink = "   [Reply]" else - '' + pageIcon = replyLink = '' container = $.el 'div', id: "pc#{postID}" @@ -226,6 +228,7 @@ Build = (if isOP then fileHTML else '') + "
        diff --git a/html/Posting/QR.html b/html/Posting/QR.html index 9b9786933..c172cb848 100644 --- a/html/Posting/QR.html +++ b/html/Posting/QR.html @@ -4,7 +4,7 @@ - × +
        @@ -29,7 +29,7 @@ No selected file - × +
        diff --git a/src/General/Notice.coffee b/src/General/Notice.coffee index 90c2e504b..ea5f6f360 100644 --- a/src/General/Notice.coffee +++ b/src/General/Notice.coffee @@ -1,7 +1,7 @@ class Notice constructor: (type, content, @timeout) -> @el = $.el 'div', - innerHTML: '×
        ' + innerHTML: '
        ' @el.style.opacity = 0 @setType type $.on @el.firstElementChild, 'click', @close diff --git a/src/Monitoring/ThreadWatcher.coffee b/src/Monitoring/ThreadWatcher.coffee index 680d61c6a..ad9e710ee 100644 --- a/src/Monitoring/ThreadWatcher.coffee +++ b/src/Monitoring/ThreadWatcher.coffee @@ -131,7 +131,7 @@ ThreadWatcher = makeLine: (boardID, threadID, data) -> x = $.el 'a', - textContent: '×' + className: 'fa fa-times' href: 'javascript:;' $.on x, 'click', ThreadWatcher.cb.rm diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index 6f71abb2f..b3e41a838 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -438,7 +438,7 @@ QR = className: 'qr-preview' draggable: true href: 'javascript:;' - innerHTML: '×' + innerHTML: '' @nodes = el: el From 20b4087f1d0be4de7750e744bba44de1a46d9d08 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 03:45:51 +0100 Subject: [PATCH 17/20] Use fa-plus for the #add-post in the QR. #1338 --- css/style.css | 8 +++----- html/Posting/QR.html | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/css/style.css b/css/style.css index 63b807874..354677865 100644 --- a/css/style.css +++ b/css/style.css @@ -764,11 +764,9 @@ a.remove { vertical-align: bottom; } #add-post { - display: inline-block; - font-size: 30px; - height: 30px; - width: 30px; - line-height: 1; + font-size: 20px; + height: 20px; + width: 20px; text-align: center; position: absolute; right: 0; diff --git a/html/Posting/QR.html b/html/Posting/QR.html index c172cb848..1458303cf 100644 --- a/html/Posting/QR.html +++ b/html/Posting/QR.html @@ -15,7 +15,7 @@
        - + +
        From b72b69d9a3fcfd5611c456ced4dddb00f0503dab Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 03:51:54 +0100 Subject: [PATCH 18/20] Hidamarize the index search input on focus. --- css/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/css/style.css b/css/style.css index 354677865..cbb57f87a 100644 --- a/css/style.css +++ b/css/style.css @@ -376,6 +376,7 @@ a[href="javascript:;"] { width: 100px; transition: color .25s, border-color .25s, width .25s; } +#index-search:focus, #index-search[data-searching] { width: 200px; } From 752e6a87478445252217ae44349d9cc15df5b8cb Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 15:27:39 +0100 Subject: [PATCH 19/20] Fix font-family of the page num indicators. --- css/style.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/css/style.css b/css/style.css index cbb57f87a..6f6f596cf 100644 --- a/css/style.css +++ b/css/style.css @@ -391,6 +391,12 @@ a[href="javascript:;"] { #index-search:not([data-searching]) + #index-search-clear { display: none; } +.page-num { + font-family: inherit; +} +.page-num::before { + font-family: FontAwesome; +} .summary { text-decoration: none; } From 06e83cc5f6bb64fcf74aa8eb975c43c95cb9baa4 Mon Sep 17 00:00:00 2001 From: Mayhem Date: Sat, 16 Nov 2013 15:42:11 +0100 Subject: [PATCH 20/20] Fix relative index refresh date on Firefox. --- src/General/Index.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 0df36998e..ca4ec0c0b 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -224,10 +224,15 @@ Index = setTimeout notice.close, $.SECOND timeEl = $ '#index-last-refresh', Index.navLinks - timeEl.dataset.utc = e.timeStamp + timeEl.dataset.utc = e.timeStamp <% if (type === 'userscript') { %>/ 1000<% } %> if timeEl.dataset.init RelativeDates.setUpdate el: timeEl + <% if (type === 'userscript') { %> + # XXX https://github.com/greasemonkey/greasemonkey/issues/1571 + timeEl.removeAttribute 'data-init' + <% } else { %> delete timeEl.dataset.init + <% } %> else RelativeDates.flush() Index.scrollToIndex()