FIX: Consistency with HTML anchors
This commit is contained in:
parent
e09a304122
commit
078f6c3fb5
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue