|
14 | 14 | load('#sidebar-page', sidebarPage) |
15 | 15 | } |
16 | 16 |
|
17 | | - function loadMain(search, callback) { |
| 17 | + function loadMain(search, callback, isPopState) { |
18 | 18 | mainSearch = search |
19 | | - var seg = search.slice(1).replace(/&.*$/g, '') |
| 19 | + var seg = search.slice(1).replace(/[&#].*$/g, '') |
20 | 20 | // fucking wechat again |
21 | 21 | // like /?graduation-thanks= |
22 | 22 | // or /?graduation-thanks=/ (SublimeServer) |
|
25 | 25 | // like /?from=singlemessage&isappinstalled=0 |
26 | 26 | if (/=/.test(seg)) seg = null |
27 | 27 | mainPage = resolve(seg || defaultPage) |
28 | | - load('#main-page', mainPage, true, callback) |
| 28 | + load('#main-page', mainPage, true, callback, isPopState) |
29 | 29 | } |
30 | 30 |
|
31 | | - function load(sel, stack, isMain, callback) { |
| 31 | + function load(sel, stack, isMain, callback, isPopState) { |
32 | 32 | if (typeof stack === 'string') { |
33 | 33 | if (/\/$/.test(stack)) { |
34 | 34 | stack = [stack + 'index', stack + 'README', stack.replace(/\/$/, '')] |
|
48 | 48 | if (isMain && pageId !== mainPageId) return |
49 | 49 |
|
50 | 50 | if (stack.length) { |
51 | | - return load(sel, stack, isMain, callback) |
| 51 | + return load(sel, stack, isMain, callback, isPopState) |
52 | 52 | } |
53 | 53 | if (isMain) onNotFound(err) |
54 | 54 | }, |
|
65 | 65 | $el.addClass('contents-preparing').html(html) |
66 | 66 | postProcess($el, url) |
67 | 67 |
|
68 | | - $el.removeClass('contents-preparing').attr('data-loaded', true) |
69 | | - if (isMain) onMainRendered() |
| 68 | + $el.removeClass('contents-preparing').attr('data-loaded', '') |
| 69 | + if (isMain) onMainRendered(isPopState) |
70 | 70 | if (callback) callback() |
71 | 71 | }) |
72 | 72 | } |
|
133 | 133 | }) |
134 | 134 | } |
135 | 135 |
|
136 | | - function onMainRendered() { |
| 136 | + function onMainRendered(isPopState) { |
137 | 137 | mainTitle = $('#main-page').find('h1, h2, h3, h4, h5, h6').first().text().trim() |
138 | 138 | var navTitle = autoTitleFavicon(mainTitle) |
139 | 139 | document.title = navTitle |
140 | 140 |
|
141 | 141 | // supports mermaid diagrams |
142 | 142 | mermaid.init() |
143 | 143 |
|
| 144 | + if (!isPopState) { |
| 145 | + setTimeout(scrollToAnchorIfExists, 500) |
| 146 | + } |
144 | 147 | comments() |
145 | 148 | shares() |
146 | 149 | } |
147 | 150 |
|
148 | 151 | function onNotFound() { |
149 | 152 | if ($('#main-page').attr('data-loaded') != null) { |
150 | | - // onMainRendered() |
| 153 | + // noop |
151 | 154 | } else if (location.search) { |
152 | 155 | location.href = '.' |
153 | 156 | } |
154 | 157 | } |
155 | 158 |
|
| 159 | + function scrollToAnchorIfExists() { |
| 160 | + // location.hash is either empty or leading with `#` |
| 161 | + // so the selector here is safe |
| 162 | + var $anchor = $(location.hash) |
| 163 | + if ($anchor.length) scrollIntoView($anchor[0]) |
| 164 | + } |
| 165 | + |
| 166 | + // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded |
| 167 | + function scrollIntoView(el, scrollParent) { |
| 168 | + if (el.scrollIntoView) { |
| 169 | + el.scrollIntoView(true) // alignToTop=true |
| 170 | + } else { |
| 171 | + scrollParent = scrollParent || el.parentElement |
| 172 | + var diff = el.offsetTop - scrollParent.scrollTop |
| 173 | + if (diff < 0 || diff > scrollParent.offsetHeight - el.offsetHeight) { |
| 174 | + scrollParent.scrollTop = el.offsetTop |
| 175 | + } |
| 176 | + } |
| 177 | + } |
| 178 | + |
156 | 179 | function slashes(str) { |
157 | 180 | return str.replace(/([.?*+^$!:[\]\\(){}|-])/g, '\\$1') |
158 | 181 | } |
|
208 | 231 | // TODO library extraction: title-favicon & text-favicon & emoji-detect |
209 | 232 | // How to detect emoji using javascript |
210 | 233 | // https://stackoverflow.com/questions/18862256/how-to-detect-emoji-using-javascript |
211 | | - // +modification title-favicon bugfix: recognize emoji `✋🏻` `💁♀️` `👨👩👧👦` |
| 234 | + // +modification title-favicon bugfix: recognize emoji `✋🏻` `💁♀️` `👨👩👧👦` `🏳️🌈` |
212 | 235 | var emojiCellRegex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])+/ |
213 | | - var emojiRegex = new RegExp(emojiCellRegex.toString().replace(/^\/(.+)\/$/, '(?:[\\u200d]*$1)+[\\ufe0f]*')) |
| 236 | + var emojiRegex = new RegExp(emojiCellRegex.toString().replace(/^\/(.+)\/$/, '(?:[\\u200d\\ufe0f]*$1)+[\\ufe0f]*')) |
214 | 237 | var emojiPrefixRegex = new RegExp(emojiRegex.toString().replace(/^\/(.+)\/$/, '^$1')) |
215 | 238 | var anyPrefixRegex = new RegExp(emojiPrefixRegex.toString().replace(/^\/\^(.+)\/$/, '^(?:$1|.)')) |
216 | 239 |
|
|
324 | 347 | }).appendTo('#comment-system') |
325 | 348 | $('<script>').attr({ |
326 | 349 | src: 'https://cusdis.com/js/cusdis.umd.js', |
327 | | - async: true |
| 350 | + async: '' |
328 | 351 | }).appendTo('head') |
329 | 352 | } |
330 | 353 | // opt.3 giscus |
|
346 | 369 | 'data-input-position': 'bottom', |
347 | 370 | 'data-theme': 'light', // silent doesn't support darkmode now |
348 | 371 | crossorigin: 'anonymous', |
349 | | - async: true |
| 372 | + async: '' |
350 | 373 | } |
351 | 374 | Object.keys(attrs).forEach(function (k) { dest[k] = attrs[k] }) |
352 | 375 | // notice: $('<script>') not working here |
|
386 | 409 | var savedScrollTop = savedState.scrollTop || 0 |
387 | 410 | loadMain(location.search, function () { |
388 | 411 | window.scrollTo(0, savedScrollTop) |
389 | | - }) |
| 412 | + }, true) |
390 | 413 | adaptForTripleBackBehavior() |
391 | 414 | }) |
392 | 415 | // trying to fix: continuous popstate events may not be fired properly |
|
461 | 484 | } |
462 | 485 |
|
463 | 486 | function config() { |
464 | | - // Optional: history.pushState API (PJAX) for silent internal page navigation |
| 487 | + // -- Optional: history.pushState API (PJAX) for silent internal page navigation |
465 | 488 | preferPJAX() |
466 | 489 |
|
467 | 490 | // supports mermaid diagrams |
|
0 commit comments