diff --git a/CHANGELOG.md b/CHANGELOG.md
index 482ad9b78..9623e5eb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+- Added an setting in the Header's menu to move it at the bottom of the screen.
- Added Cooldown setting back in.
- Fixed the Header going above posts when following quotelinks for example.
- Fixed a bug where dead quotelinks would disappear.
diff --git a/css/style.css b/css/style.css
index e33e11f5c..a729961c2 100644
--- a/css/style.css
+++ b/css/style.css
@@ -104,18 +104,34 @@ a[href="javascript:;"] {
display: none !important;
}
#header {
- top: 0;
right: 0;
left: 0;
}
+#header.top {
+ top: 0;
+}
+#header.bottom {
+ bottom: 0;
+}
#header-bar {
- border-width: 0 0 1px;
+ border-width: 0;
display: -webkit-flex;
display: flex;
padding: 3px 4px 4px;
position: relative;
transition: all .1s .05s ease-in-out;
}
+#header.top #header-bar {
+ border-bottom-width: 1px;
+}
+#header.bottom #header-bar {
+ box-shadow: 0 -1px 2px rgba(0, 0, 0, .15);
+ border-top-width: 1px;
+}
+#header.bottom .menu-button i {
+ border-top: none;
+ border-bottom: 6px solid;
+}
#board-list {
-webkit-flex: 1;
flex: 1;
@@ -123,26 +139,49 @@ a[href="javascript:;"] {
}
#header-bar.autohide:not(:hover) {
box-shadow: none;
+ transition: all .8s .6s cubic-bezier(.55, .055, .675, .19);
+}
+#header.top #header-bar.autohide:not(:hover) {
margin-bottom: -1em;
-webkit-transform: translateY(-100%);
transform: translateY(-100%);
- transition: all .8s .6s cubic-bezier(.55, .055, .675, .19);
+}
+#header.bottom #header-bar.autohide:not(:hover) {
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
}
#toggle-header-bar {
- cursor: n-resize;
left: 0;
right: 0;
- bottom: -8px;
height: 10px;
position: absolute;
}
-#header-bar.autohide:not(:hover) #toggle-header-bar, #toggle-header-bar:hover {
- bottom: -16px;
+#header.top #toggle-header-bar {
+ cursor: n-resize;
+ bottom: -8px;
+}
+#header.bottom #toggle-header-bar {
+ cursor: s-resize;
+ top: -8px;
+}
+#header-bar.autohide:not(:hover) #toggle-header-bar,
+#toggle-header-bar:hover {
height: 18px;
}
-#header-bar.autohide #toggle-header-bar {
+#header.top #header-bar.autohide:not(:hover) #toggle-header-bar,
+#header.top #toggle-header-bar:hover {
+ bottom: -16px;
+}
+#header.bottom #header-bar.autohide:not(:hover) #toggle-header-bar,
+#header.bottom #toggle-header-bar:hover {
+ top: -16px;
+}
+#header.top #header-bar.autohide #toggle-header-bar {
cursor: s-resize;
}
+#header.bottom #header-bar.autohide #toggle-header-bar {
+ cursor: n-resize;
+}
#header-bar a:not(.entry) {
text-decoration: none;
padding: 1px;
@@ -168,6 +207,12 @@ a[href="javascript:;"] {
height: 0;
text-align: center;
}
+#header.bottom #notifications {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+}
.notification {
color: #FFF;
font-weight: 700;
diff --git a/src/config.coffee b/src/config.coffee
index 402fed7be..f5b799b59 100644
--- a/src/config.coffee
+++ b/src/config.coffee
@@ -132,6 +132,7 @@ Config =
'#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/'
].join '\n'
'Custom CSS': false
+ 'Bottom header': false
'Header auto-hide': false
'Header catalog links': false
boardnav: '[current-title / toggle-all]'
diff --git a/src/features.coffee b/src/features.coffee
index e3cd4dbd4..d0dbb2805 100644
--- a/src/features.coffee
+++ b/src/features.coffee
@@ -21,7 +21,7 @@ Header =
@menu = new UI.Menu 'header'
$.on $('.menu-button', @bar), 'click', @menuToggle
$.on @toggle, 'mousedown', @toggleBarVisibility
- $.on window, 'hashchange', Header.hashScroll
+ $.on window, 'load hashchange', Header.hashScroll
catalogToggler = $.el 'label',
innerHTML: " Use catalog board links"
@@ -32,6 +32,17 @@ Header =
el: catalogToggler
order: 50
+ @positionToggler = $.el 'label',
+ innerHTML: " Bottom header"
+ $.on @positionToggler.firstElementChild, 'change', @toggleBarPosition
+ $.event 'AddMenuEntry',
+ type: 'header'
+ el: @positionToggler
+ order: 108
+
+ @setBarPosition Conf['Bottom header']
+ $.sync 'Bottom header', @setBarPosition
+
@headerToggler = $.el 'label',
innerHTML: " Auto-hide header"
$.on @headerToggler.firstElementChild, 'change', @toggleBarVisibility
@@ -129,15 +140,31 @@ Header =
Header.setCatalogLinks @checked
$.set 'Header catalog links', @checked
+ setBarPosition: (bottom) ->
+ $.event 'CloseMenu'
+ Header.positionToggler.firstElementChild.checked = bottom
+ Header.bar.parentNode.className = if bottom
+ 'bottom'
+ else
+ 'top'
+ toggleBarPosition: ->
+ bottom = @checked
+ Header.setBarPosition bottom
+ Conf['Bottom header'] = bottom
+ $.set 'Bottom header', bottom
+
setBarVisibility: (hide) ->
Header.headerToggler.firstElementChild.checked = hide
(if hide then $.addClass else $.rmClass) Header.bar, 'autohide'
hashScroll: ->
return unless post = $.id @location.hash[1..]
- postRect = post.getBoundingClientRect()
- headRect = Header.toggle.getBoundingClientRect()
- root = if $.engine is 'webkit' then d.body else doc
- root.scrollTop += postRect.top - headRect.top - headRect.height
+ Header.scrollToPost post
+ scrollToPost: (post) ->
+ {top} = post.getBoundingClientRect()
+ unless Conf['Bottom header']
+ headRect = Header.toggle.getBoundingClientRect()
+ top += - headRect.top - headRect.height
+ (if $.engine is 'webkit' then d.body else doc).scrollTop += top
toggleBarVisibility: (e) ->
return if e.type is 'mousedown' and e.button isnt 0 # not LMB
hide = if @nodeName is 'INPUT'
@@ -1900,8 +1927,11 @@ Keybinds =
location.href = url
hl: (delta, thread) ->
- headRect = Header.bar.getBoundingClientRect()
- topMargin = headRect.top + headRect.height
+ if Conf['Bottom header']
+ topMargin = 0
+ else
+ headRect = Header.toggle.getBoundingClientRect()
+ topMargin = headRect.top + headRect.height
if postEl = $ '.reply.highlight', thread
$.rmClass postEl, 'highlight'
rect = postEl.getBoundingClientRect()
@@ -1965,8 +1995,11 @@ Nav =
Nav.scroll +1
getThread: (full) ->
- headRect = Header.bar.getBoundingClientRect()
- topMargin = headRect.top + headRect.height
+ if Conf['Bottom header']
+ topMargin = 0
+ else
+ headRect = Header.toggle.getBoundingClientRect()
+ topMargin = headRect.top + headRect.height
threads = $$ '.thread:not([hidden])'
for thread, i in threads
rect = thread.getBoundingClientRect()
@@ -3242,8 +3275,10 @@ ImageExpand =
return unless rect.top <= 0 or rect.left <= 0
# Scroll back to the thumbnail when contracting the image
# to avoid being left miles away from the relevant post.
- headRect = Header.toggle.getBoundingClientRect()
- top = rect.top - headRect.top - headRect.height
+ {top} = rect
+ unless Conf['Bottom header']
+ headRect = Header.toggle.getBoundingClientRect()
+ top += - headRect.top - headRect.height
root = if $.engine is 'webkit' then d.body else doc
root.scrollTop += top if rect.top < 0
root.scrollLeft = 0 if rect.left < 0
@@ -3653,13 +3688,13 @@ Unread =
defaultValue: 0
Unread.addPosts posts
if (hash = location.hash.match /\d+/) and post = @posts[hash[0]]
- post.nodes.root.scrollIntoView()
+ Header.scrollToPost post.nodes.root
else if Unread.posts.length
# Scroll to before the first unread post.
$.x('preceding-sibling::div[contains(@class,"postContainer")][1]', Unread.posts[0].nodes.root).scrollIntoView false
else if posts.length
# Scroll to the last read post.
- posts[posts.length - 1].nodes.root.scrollIntoView()
+ Header.scrollToPost posts[posts.length - 1].nodes.root
$.on d, 'ThreadUpdate', Unread.onUpdate
$.on d, 'scroll visibilitychange', Unread.read
$.on d, 'visibilitychange', Unread.setLine if Conf['Unread Line']
@@ -4143,7 +4178,7 @@ ThreadUpdater =
if Conf['Bottom Scroll']
(if $.engine is 'webkit' then d.body else doc).scrollTop = d.body.clientHeight
else
- nodes[0].scrollIntoView()
+ Header.scrollToPost nodes[0]
$.queueTask ->
# Enable 4chan features.