diff --git a/CHANGELOG.md b/CHANGELOG.md index 463426d76..234582144 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### 3.0.2 - *2013-04-09* + +- Added a 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. ### 3.0.1 - *2013-04-08* diff --git a/css/style.css b/css/style.css index f807975bc..fa3749eae 100644 --- a/css/style.css +++ b/css/style.css @@ -6,6 +6,7 @@ padding: 0; } .field { + background-color: #FFF; border: 1px solid #CCC; -moz-box-sizing: border-box; box-sizing: border-box; @@ -97,18 +98,34 @@ a[href="javascript:;"] { box-sizing: border-box; } #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; @@ -116,26 +133,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; @@ -163,6 +203,12 @@ a[href="javascript:;"] { right: 0; left: 0; } +#header.bottom #notifications { + position: fixed; + top: 0; + left: 0; + width: 100%; +} .notification { color: #FFF; font-weight: 700; @@ -427,7 +473,7 @@ a[href="javascript:;"] { max-height: 300px; max-width: 500px; } -.qphl > .post { +.qphl { outline: 2px solid rgba(216, 94, 49, .7); } diff --git a/package.json b/package.json index 6fcb5961b..1877b74e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "3.0.1", + "version": "3.0.2", "description": "Cross-browser extension for productive lurking on 4chan.", "meta": { "name": "4chan X", diff --git a/src/config.coffee b/src/config.coffee index 94833ddf1..52ab127ae 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -229,6 +229,10 @@ Config = true 'Hide the normal post form.' ] + 'Cooldown': [ + true + 'Prevent "flood detected" errors.' + ] 'Quote Links': 'Quote Backlinks': [ diff --git a/src/features.coffee b/src/features.coffee index fdbbab82d..ad7f20643 100644 --- a/src/features.coffee +++ b/src/features.coffee @@ -6,6 +6,9 @@ Header = id: 'shortcuts' @hover = $.el 'div', id: 'hoverUI' + + $.on window, 'load hashchange', Header.hashScroll + $.asap (-> d.body), -> return unless Main.isThisPageLegit() # Wait for #boardNavMobile instead of #boardNavDesktop, @@ -88,6 +91,17 @@ Header = custom.hidden = !showBoardList full.hidden = showBoardList + hashScroll: -> + return unless post = $.id @location.hash[1..] + Header.scrollToPost post + + scrollToPost: (post) -> + {top} = post.getBoundingClientRect() + unless Conf['Bottom header'] + headRect = Header.bar.getBoundingClientRect() + top += - headRect.top - headRect.height + (if $.engine is 'webkit' then d.body else doc).scrollTop += top + addShortcut: (el) -> shortcut = $.el 'span', className: 'shortcut' @@ -1871,8 +1885,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() @@ -1936,8 +1953,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() @@ -2717,7 +2737,7 @@ QuotePreview = # Remove the clone that's in the qp from the array. posts.pop() for post in posts - $.addClass post.nodes.root, 'qphl' + $.addClass post.nodes.post, 'qphl' quoterID = $.x('ancestor::*[@id][1]', @).id.match(/\d+$/)[0] clone = Get.postFromRoot qp.firstChild @@ -2736,7 +2756,7 @@ QuotePreview = return unless Conf['Quote Highlighting'] for post in [post].concat post.clones - $.rmClass post.nodes.root, 'qphl' + $.rmClass post.nodes.post, 'qphl' return QuoteBacklink = @@ -3205,8 +3225,15 @@ ImageExpand = name: 'Image Expansion' cb: @node node: -> - return unless @file and @file.isImage - $.on @file.thumb.parentNode, 'click', ImageExpand.cb.toggle + return unless @file?.isImage + {thumb} = @file + $.on thumb.parentNode, 'click', ImageExpand.cb.toggle + if @isClone and $.hasClass thumb, 'expanding' + # If we clone a post where the image is still loading, + # make it loading in the clone too. + ImageExpand.contract @ + ImageExpand.expand @ + return if ImageExpand.on and !@isHidden ImageExpand.expand @ cb: @@ -3256,8 +3283,15 @@ 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. +<<<<<<< HEAD headRect = Header.bar.getBoundingClientRect() top = rect.top - headRect.top - headRect.height +======= + {top} = rect + unless Conf['Bottom header'] + headRect = Header.toggle.getBoundingClientRect() + top += - headRect.top - headRect.height +>>>>>>> 354f566672b2dc8a556c33d6a24c0ec33ee995c8 root = if $.engine is 'webkit' then d.body else doc root.scrollTop += top if rect.top < 0 root.scrollLeft = 0 if rect.left < 0 @@ -3480,7 +3514,7 @@ ExpandComment = post = Get.postFromNode @ ExpandComment.expand post expand: (post) -> - if post.nodes.longComment + if post.nodes.longComment and !post.nodes.longComment.parentNode $.replace post.nodes.shortComment, post.nodes.longComment post.nodes.comment = post.nodes.longComment return @@ -3666,13 +3700,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'] @@ -4174,7 +4208,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. diff --git a/src/qr.coffee b/src/qr.coffee index 9b8f4df99..5ad345388 100644 --- a/src/qr.coffee +++ b/src/qr.coffee @@ -133,6 +133,7 @@ QR = cooldown: init: -> + return unless Conf['Cooldown'] board = g.BOARD.ID QR.cooldown.types = thread: switch board @@ -149,6 +150,7 @@ QR = QR.cooldown.start() $.sync "cooldown.#{board}", QR.cooldown.sync start: -> + return unless Conf['Cooldown'] return if QR.cooldown.isCounting QR.cooldown.isCounting = true QR.cooldown.count() @@ -159,6 +161,7 @@ QR = QR.cooldown.cooldowns[id] = cooldowns[id] QR.cooldown.start() set: (data) -> + return unless Conf['Cooldown'] {req, post, isReply, delay} = data start = if req then req.uploadEndTime else Date.now() if delay