diff --git a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6 b/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6 index 4b547a68828..2900e5d6704 100644 --- a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6 +++ b/app/assets/javascripts/discourse-common/lib/raw-handlebars.js.es6 @@ -18,13 +18,15 @@ RawHandlebars.helpers['get'] = function(context, options) { var firstContext = options.contexts[0]; var val = firstContext[context]; - if (context.indexOf('controller') === 0) { - context = context.replace(/^controller\./, ''); + if (context.indexOf('controller.') === 0) { + context = context.slice(context.indexOf('.') + 1); } - if (val && val.isDescriptor) { return Em.get(firstContext, context); } - val = val === undefined ? Em.get(firstContext, context): val; - return val; + if (val && val.isDescriptor) { + return Em.get(firstContext, context); + } + + return val === undefined ? Em.get(firstContext, context) : val; }; // adds compatability so this works with stringParams diff --git a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 index 74d6b378b7d..420a440e15a 100644 --- a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 +++ b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 @@ -93,7 +93,7 @@ export default MountWidget.extend({ let percent = null; const offset = offsetCalculator(); - const topCheck = Math.ceil(windowTop + offset); + const topCheck = Math.ceil(windowTop + offset + 5); // uncomment to debug the eyeline /* diff --git a/app/assets/javascripts/discourse/lib/lock-on.js.es6 b/app/assets/javascripts/discourse/lib/lock-on.js.es6 index 111b713a359..d780990b30b 100644 --- a/app/assets/javascripts/discourse/lib/lock-on.js.es6 +++ b/app/assets/javascripts/discourse/lib/lock-on.js.es6 @@ -1,13 +1,13 @@ import { scrollTopFor } from 'discourse/lib/offset-calculator'; -// Dear traveller, you are entering a zone where we are at war with the browser -// the browser is insisting on positioning scrollTop per the location it was in -// the past, we are insisting on it being where we want it to be -// The hack is just to keep trying over and over to position the scrollbar (up to 1 minute) +// Dear traveller, you are entering a zone where we are at war with the browser. +// The browser is insisting on positioning scrollTop per the location it was in +// the past, we are insisting on it being where we want it to be. +// The hack is just to keep trying over and over to position the scrollbar (up to 1 second). // // The root cause is that a "refresh" on a topic page will almost never be at the // same position it was in the past, the URL points to the post at the top of the -// page, so a refresh will try to bring that post into view causing drift +// page, so a refresh will try to bring that post into view causing drift. // // Additionally if you loaded multiple batches of posts, on refresh they will not // be loaded. @@ -19,6 +19,7 @@ import { scrollTopFor } from 'discourse/lib/offset-calculator'; // 2. give up on the scrollbar and implement it ourselves (something that will happen) const SCROLL_EVENTS = "scroll.lock-on touchmove.lock-on mousedown.lock-on wheel.lock-on DOMMouseScroll.lock-on mousewheel.lock-on keyup.lock-on"; +const SCROLL_TYPES = ["mousedown", "mousewheel", "touchmove", "wheel"]; function within(threshold, x, y) { return Math.abs(x-y) < threshold; @@ -34,8 +35,7 @@ export default class LockOn { elementTop() { const selected = $(this.selector); if (selected && selected.offset && selected.offset()) { - const result = selected.offset().top; - return scrollTopFor(result); + return scrollTopFor(selected.offset().top); } } @@ -54,9 +54,7 @@ export default class LockOn { $(window).scrollTop(previousTop); const interval = setInterval(() => { - let top = this.elementTop(); - if (top < 0) { top = 0; } - + const top = Math.max(0, this.elementTop()); const scrollTop = $(window).scrollTop(); if (typeof(top) === "undefined" || isNaN(top)) { @@ -68,20 +66,14 @@ export default class LockOn { previousTop = top; } - // We commit suicide after 3s just to clean up - const nowTime = new Date().getTime(); - if (nowTime - startedAt > 1000) { + // Commit suicide after a little while + if (new Date().getTime() - startedAt > 1000) { return this.clearLock(interval); } }, 50); $('body,html').off(SCROLL_EVENTS).on(SCROLL_EVENTS, e => { - if ( e.which > 0 || - e.type === "mousedown" || - e.type === "mousewheel" || - e.type === "touchmove" || - e.type === "wheel" - ) { + if (e.which > 0 || SCROLL_TYPES.includes(e.type)) { this.clearLock(interval); } }); diff --git a/app/assets/javascripts/discourse/lib/offset-calculator.js.es6 b/app/assets/javascripts/discourse/lib/offset-calculator.js.es6 index b354e271b44..00cb7212453 100644 --- a/app/assets/javascripts/discourse/lib/offset-calculator.js.es6 +++ b/app/assets/javascripts/discourse/lib/offset-calculator.js.es6 @@ -5,34 +5,19 @@ export function scrollTopFor(y) { export default function offsetCalculator(y) { const $header = $('header'); const $container = $('.posts-wrapper'); - const containerOffset = $container.offset(); - - let titleHeight = 0; const scrollTop = y || $(window).scrollTop(); - - if (!containerOffset || scrollTop < containerOffset.top) { - titleHeight = $('#topic-title').height() || 0; - } - + const titleHeight = $('#topic-title').height() || 0; const rawWinHeight = $(window).height(); - const windowHeight = rawWinHeight - titleHeight; - - const eyeTarget = (windowHeight / 10); - const headerHeight = $header.outerHeight(true); - const expectedOffset = titleHeight - ($header.find('.contents').height() || 0) + (eyeTarget * 2); - const ideal = headerHeight + ((expectedOffset < 0) ? 0 : expectedOffset); + const expectedOffset = titleHeight - ($header.find('.contents').height() || 0); if ($container.length === 0) { return expectedOffset; } + const headerHeight = $header.outerHeight(true); + const ideal = headerHeight + Math.max(0, expectedOffset); const topPos = $container.offset().top; - const docHeight = $(document).height(); - let scrollPercent = Math.min((scrollTop / (docHeight-rawWinHeight)), 1.0); - - let inter = topPos - scrollTop + ($container.height() * scrollPercent); - if (inter < headerHeight + eyeTarget) { - inter = headerHeight + eyeTarget; - } + const scrollPercent = Math.min(scrollTop / (docHeight - rawWinHeight), 1.0); + const inter = Math.min(headerHeight, topPos - scrollTop + ($container.height() * scrollPercent)); if (inter > ideal) { const bottom = $('#topic-bottom').offset().top;