FIX: Consistency with HTML anchors

This commit is contained in:
Robin Ward 2016-07-20 15:13:56 -04:00
parent e09a304122
commit 078f6c3fb5
4 changed files with 33 additions and 51 deletions

View File

@ -42,6 +42,9 @@ export default class LockOn {
clearLock(interval) { clearLock(interval) {
$('body,html').off(SCROLL_EVENTS); $('body,html').off(SCROLL_EVENTS);
clearInterval(interval); clearInterval(interval);
if (this.options.finished) {
this.options.finished();
}
} }
lock() { lock() {

View File

@ -19,6 +19,8 @@ export default function offsetCalculator(y) {
const ideal = headerHeight + ((expectedOffset < 0) ? 0 : expectedOffset); const ideal = headerHeight + ((expectedOffset < 0) ? 0 : expectedOffset);
const $container = $('.posts-wrapper'); const $container = $('.posts-wrapper');
if ($container.length === 0) { return expectedOffset; }
const topPos = $container.offset().top; const topPos = $container.offset().top;
const scrollTop = y || $(window).scrollTop(); const scrollTop = y || $(window).scrollTop();

View File

@ -1,5 +1,5 @@
import DiscourseURL from 'discourse/lib/url';
import StaticPage from 'discourse/models/static-page'; import StaticPage from 'discourse/models/static-page';
import { default as DiscourseURL, jumpToElement } from 'discourse/lib/url';
const configs = { const configs = {
"faq": "faq_url", "faq": "faq_url",
@ -23,8 +23,7 @@ export default function(page) {
activate() { activate() {
this._super(); this._super();
// Scroll to an element if exists jumpToElement(document.location.hash.substr(1));
DiscourseURL.scrollToId(document.location.hash);
}, },
model() { model() {

View File

@ -2,16 +2,28 @@ import offsetCalculator from 'discourse/lib/offset-calculator';
import LockOn from 'discourse/lib/lock-on'; import LockOn from 'discourse/lib/lock-on';
import { defaultHomepage } from 'discourse/lib/utilities'; import { defaultHomepage } from 'discourse/lib/utilities';
let _jumpScheduled = false;
const rewrites = []; const rewrites = [];
const TOPIC_REGEXP = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/; const TOPIC_REGEXP = /\/t\/([^\/]+)\/(\d+)\/?(\d+)?/;
let _jumpScheduled = false;
export function jumpToElement(elementId) {
if (_jumpScheduled || Ember.isEmpty(elementId)) { return; }
const selector = `#${elementId}, a[name=${elementId}]`;
_jumpScheduled = true;
Ember.run.schedule('afterRender', function() {
const lockon = new LockOn(selector, {
finished() {
_jumpScheduled = false;
}
});
lockon.lock();
});
}
const DiscourseURL = Ember.Object.extend({ const DiscourseURL = Ember.Object.extend({
// Used for matching a topic isJumpScheduled() {
isJumpScheduled: function() {
return _jumpScheduled; return _jumpScheduled;
}, },
@ -56,13 +68,8 @@ const DiscourseURL = Ember.Object.extend({
}); });
}, },
/** // Browser aware replaceState. Will only be invoked if the browser supports it.
Browser aware replaceState. Will only be invoked if the browser supports it. replaceState(path) {
@method replaceState
@param {String} path The path we are replacing our history state with.
**/
replaceState: function(path) {
if (window.history && if (window.history &&
window.history.pushState && window.history.pushState &&
window.history.replaceState && window.history.replaceState &&
@ -81,23 +88,6 @@ const DiscourseURL = Ember.Object.extend({
} }
}, },
// Scroll to the same page, different anchor
scrollToId(id) {
if (Em.isEmpty(id)) { return; }
_jumpScheduled = true;
Em.run.schedule('afterRender', function() {
let $elem = $(id);
if ($elem.length === 0) {
$elem = $("[name='" + id.replace('#', '') + "']");
}
if ($elem.length > 0) {
$('html,body').scrollTop($elem.offset().top - $('header').height() - 15);
_jumpScheduled = false;
}
});
},
routeToTag(a) { routeToTag(a) {
if (a && a.host !== document.location.host) { if (a && a.host !== document.location.host) {
document.location = a.href; document.location = a.href;
@ -131,10 +121,10 @@ const DiscourseURL = Ember.Object.extend({
} }
// Scroll to the same page, different anchor // Scroll to the same page, different anchor
if (path.indexOf('#') === 0) { const m = /#(.+)$/.exec(path);
this.scrollToId(path); if (m) {
this.replaceState(path); jumpToElement(m[1]);
return; return this.replaceState(path);
} }
const oldPath = window.location.pathname; const oldPath = window.location.pathname;
@ -299,7 +289,7 @@ const DiscourseURL = Ember.Object.extend({
// Get a controller. Note that currently it uses `__container__` which is not // Get a controller. Note that currently it uses `__container__` which is not
// advised but there is no other way to access the router. // advised but there is no other way to access the router.
controllerFor: function(name) { controllerFor(name) {
return Discourse.__container__.lookup('controller:' + name); return Discourse.__container__.lookup('controller:' + name);
}, },
@ -307,7 +297,7 @@ const DiscourseURL = Ember.Object.extend({
Be wary of looking up the router. In this case, we have links in our Be wary of looking up the router. In this case, we have links in our
HTML, say form compiled markdown posts, that need to be routed. HTML, say form compiled markdown posts, that need to be routed.
**/ **/
handleURL: function(path, opts) { handleURL(path, opts) {
opts = opts || {}; opts = opts || {};
const router = this.get('router'); const router = this.get('router');
@ -328,19 +318,7 @@ const DiscourseURL = Ember.Object.extend({
const transition = router.handleURL(path); const transition = router.handleURL(path);
transition._discourse_intercepted = true; transition._discourse_intercepted = true;
transition.promise.then(function() { transition.promise.then(() => jumpToElement(elementId));
if (elementId) {
_jumpScheduled = true;
Em.run.next('afterRender', function() {
const offset = $('#' + elementId).offset();
if (offset && offset.top) {
$('html, body').scrollTop(offset.top - $('header').height() - 10);
_jumpScheduled = false;
}
});
}
});
} }
}).create(); }).create();