1
0
mirror of https://github.com/squidfunk/mkdocs-material.git synced 2024-11-24 07:30:12 +01:00

Fixed anchor jump from mobile search

This commit is contained in:
squidfunk 2020-02-16 00:23:50 +01:00
parent a539eab0b5
commit a399540940
18 changed files with 112 additions and 136 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,10 @@
{ {
"assets/javascripts/bundle.js": "assets/javascripts/bundle.676c670f.min.js", "assets/javascripts/bundle.js": "assets/javascripts/bundle.a0e3393a.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.676c670f.min.js.map", "assets/javascripts/bundle.js.map": "assets/javascripts/bundle.a0e3393a.min.js.map",
"assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js", "assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js",
"assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map", "assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.3144ce89.min.js", "assets/javascripts/worker/search.js": "assets/javascripts/worker/search.3144ce89.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.3144ce89.min.js.map", "assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.3144ce89.min.js.map",
"assets/stylesheets/app-palette.scss": "assets/stylesheets/app-palette.8c25017f.min.css", "assets/stylesheets/app-palette.scss": "assets/stylesheets/app-palette.8c25017f.min.css",
"assets/stylesheets/app.scss": "assets/stylesheets/app.a4472ab8.min.css" "assets/stylesheets/app.scss": "assets/stylesheets/app.3d7b25ce.min.css"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,7 @@
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block styles %} {% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/app.a4472ab8.min.css' | url }}"> <link rel="stylesheet" href="{{ 'assets/stylesheets/app.3d7b25ce.min.css' | url }}">
{% if palette.primary or palette.accent %} {% if palette.primary or palette.accent %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/app-palette.8c25017f.min.css' | url }}"> <link rel="stylesheet" href="{{ 'assets/stylesheets/app-palette.8c25017f.min.css' | url }}">
{% endif %} {% endif %}
@ -190,7 +190,7 @@
{% endblock %} {% endblock %}
</div> </div>
{% block scripts %} {% block scripts %}
<script src="{{ 'assets/javascripts/bundle.676c670f.min.js' | url }}"></script> <script src="{{ 'assets/javascripts/bundle.a0e3393a.min.js' | url }}"></script>
<script id="__lang" type="application/json"> <script id="__lang" type="application/json">
{%- set translations = {} -%} {%- set translations = {} -%}
{%- for key in [ {%- for key in [

View File

@ -19,7 +19,7 @@
<label class="md-nav__title" for="{{ path }}"> <label class="md-nav__title" for="{{ path }}">
{{ nav_item.title }} {{ nav_item.title }}
</label> </label>
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
{% set base = path %} {% set base = path %}
{% for nav_item in nav_item.children %} {% for nav_item in nav_item.children %}
{% set path = base + "-" + loop.index | string %} {% set path = base + "-" + loop.index | string %}

View File

@ -17,7 +17,7 @@
{% include "partials/source.html" %} {% include "partials/source.html" %}
</div> </div>
{% endif %} {% endif %}
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
{% for nav_item in nav %} {% for nav_item in nav %}
{% set path = "nav-" + loop.index | string %} {% set path = "nav-" + loop.index | string %}
{% set level = 1 %} {% set level = 1 %}

View File

@ -13,7 +13,7 @@
</button> </button>
</form> </form>
<div class="md-search__output"> <div class="md-search__output">
<div class="md-search__scrollwrap"> <div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result"> <div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta"> <div class="md-search-result__meta">
{{ lang.t("search.result.placeholder") }} {{ lang.t("search.result.placeholder") }}

View File

@ -9,7 +9,7 @@
{% endif %} {% endif %}
{% if toc_ | first is defined %} {% if toc_ | first is defined %}
<label class="md-nav__title" for="__toc">{{ lang.t("toc.title") }}</label> <label class="md-nav__title" for="__toc">{{ lang.t("toc.title") }}</label>
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
{% for toc_item in toc_ %} {% for toc_item in toc_ %}
{% include "partials/toc-item.html" %} {% include "partials/toc-item.html" %}
{% endfor %} {% endfor %}

View File

@ -26,12 +26,13 @@
import "../stylesheets/app.scss" import "../stylesheets/app.scss"
import "../stylesheets/app-palette.scss" import "../stylesheets/app-palette.scss"
import { values } from "ramda" import { values, identity } from "ramda"
import { import {
EMPTY, EMPTY,
merge, merge,
of, of,
NEVER NEVER,
combineLatest
} from "rxjs" } from "rxjs"
import { import {
delay, delay,
@ -53,6 +54,7 @@ import {
getElements, getElements,
watchMedia, watchMedia,
watchDocument, watchDocument,
watchLocation,
watchLocationHash, watchLocationHash,
watchViewport, watchViewport,
watchKeyboard, watchKeyboard,
@ -98,7 +100,7 @@ if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g))
*/ */
function repository() { function repository() {
const el = getElement<HTMLAnchorElement>(".md-source[href]") // TODO: dont use classes const el = getElement<HTMLAnchorElement>(".md-source[href]") // TODO: dont use classes
console.log(el) // console.log(el)
if (!el) if (!el)
return EMPTY return EMPTY
@ -165,6 +167,7 @@ export function initialize(config: unknown) {
// pass config here!? // pass config here!?
const document$ = watchDocument() const document$ = watchDocument()
const location$ = watchLocation()
const hash$ = watchLocationHash() const hash$ = watchLocationHash()
const keyboard$ = watchKeyboard() const keyboard$ = watchKeyboard()
const viewport$ = watchViewport() const viewport$ = watchViewport()
@ -251,7 +254,9 @@ export function initialize(config: unknown) {
) )
}) })
) )
.subscribe(console.log) .subscribe()
// paintHeaderTitle <- same with shadow...
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
@ -274,23 +279,39 @@ export function initialize(config: unknown) {
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
// Close drawer and search on hash change // Close drawer and search on hash change
hash$.subscribe(() => { hash$.subscribe(x => {
useToggle("drawer").subscribe(el => { useToggle("drawer").subscribe(el => {
setToggle(el, false) setToggle(el, false)
}) })
useToggle("search").subscribe(el => { // omit nested subscribes...
setToggle(el, false)
})
}) })
// TODO:
hash$
.pipe(
switchMap(hash => {
return useToggle("search")
.pipe(
filter(x => x.checked), // only active
tap(toggle => setToggle(toggle, false)),
delay(125), // ensure that it runs after the body scroll reset...
tap(() => {
location.hash = " "
location.hash = hash
}) // encapsulate this...
)
})
)
.subscribe()
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
// watchClipboard // watchClipboard
mountClipboard({ document$ }) mountClipboard({ document$ })
.subscribe(console.log) .subscribe()
// TODO: WIP repo rendering // TODO: WIP repo rendering
repository().subscribe(facts => { repository().subscribe(facts => {
@ -306,68 +327,65 @@ export function initialize(config: unknown) {
}) })
patchTables({ document$ }) patchTables({ document$ })
.subscribe(console.log) .subscribe()
patchDetails({ document$ }) patchDetails({ document$ })
.subscribe(console.log) .subscribe()
// // TODO: must be reset when tablet/toggle is left // scroll lock
// const toggle$ = useToggle("search") let scroll = 0
// toggle$ combineLatest([
// .pipe( useToggle("search")
// switchMap(watchToggle), .pipe(
// skip(1), switchMap(watchToggle)
// switchMap(toggle => viewport$ ),
// .pipe( tablet$,
// take(1), ]).pipe(
// pluck("offset"), tap(([toggle, tablet]) => {
// delay(toggle ? 400 : 100) if (toggle && !tablet) {
// ) scroll = scrollY
// ), setTimeout(() => {
// startWith({ x: 0, y: 0 }), requestAnimationFrame(() => {
// bufferCount(2, 1), document.body.style.position = 'fixed';
// takeIf(not(tablet$)), // TODO: wrong position document.body.style.top = `-${scroll}px`;
// map(([offset]) => offset) // data.mdState = lock
// ) })
// .subscribe(offset => { }, 400)
// // TODO: this will also trigger if we started at the top. } else {
// document.body.dataset.mdState = offset.y ? "" : "lock" // TODO: refactor
// setViewportOffset(offset)
// })
// accidentally triggers on resize /* Scroll to former position, but wait for 100ms to prevent flashes on
// let lastOffset = 0 iOS. A short timeout seems to do the trick */
// tablet$.pipe( setTimeout(() => {
// switchMap(active => { requestAnimationFrame(() => {
// return !active ? watchToggle(search) : NEVER document.body.style.position = '';
// }), document.body.style.top = '';
// switchMap(toggle => { if (scroll)
// if (toggle) { window.scrollTo(0, scroll)
// console.log("ACTIVE") })
// return of(document.body) }, 100)
// .pipe( }
// tap(() => lastOffset = window.pageYOffset), })
// delay(400), )
// tap(() => { .subscribe()
// window.scrollTo(0, 0),
// console.log("scrolled... to top, locked body") /* Force 1px scroll offset to trigger overflow scrolling */
// document.body.dataset.mdState = "lock" if (true || navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) {
// }) const scrollable = document.querySelectorAll("[data-md-scrollfix]")
// ) Array.prototype.forEach.call(scrollable, item => {
// } else { item.addEventListener("touchstart", () => {
// console.log("INACTIVE") const top = item.scrollTop
// return of(document.body)
// .pipe( /* We're at the top of the container */
// tap(() => document.body.dataset.mdState = ""), if (top === 0) {
// delay(100), item.scrollTop = 1
// tap(() => {
// window.scrollTo(0, lastOffset) // setViewportOffset ! /* We're at the bottom of the container */
// }) } else if (top + item.offsetHeight === item.scrollHeight) {
// ) item.scrollTop = top - 1
// } }
// }) })
// ) })
// .subscribe(x => console.log("SEARCHLOCK", x)) }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */

View File

@ -20,55 +20,13 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
import { import { MonoTypeOperatorFunction, Observable, pipe } from "rxjs"
EMPTY, import { filter, map, withLatestFrom } from "rxjs/operators"
MonoTypeOperatorFunction,
Observable,
OperatorFunction,
combineLatest,
of,
pipe
} from "rxjs"
import {
filter,
map,
switchMap,
takeUntil,
withLatestFrom
} from "rxjs/operators"
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Functions * Functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/**
* Toggle switch map with another observable
*
* @template T - Source value type
* @template U - Target value type
*
* @param toggle$ - Toggle observable
* @param project - Projection
*
* @return Operator function
*/
export function switchMapIf<T, U>(
toggle$: Observable<boolean>, project: (value: T) => Observable<U>
): OperatorFunction<T, U> {
const begin$ = toggle$.pipe(filter(value => value))
const end$ = toggle$.pipe(filter(value => !value))
return pipe(
switchMap(value => combineLatest([of(value), begin$])),
switchMap(([value, active]) => active
? project(value)
.pipe(
takeUntil(end$)
)
: EMPTY
)
)
}
/** /**
* Toggle emission with another observable * Toggle emission with another observable
* *

View File

@ -56,7 +56,7 @@
<label class="md-nav__title" for="{{ path }}"> <label class="md-nav__title" for="{{ path }}">
{{ nav_item.title }} {{ nav_item.title }}
</label> </label>
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
<!-- Render nested item list --> <!-- Render nested item list -->
{% set base = path %} {% set base = path %}

View File

@ -52,7 +52,7 @@
{% endif %} {% endif %}
<!-- Render item list --> <!-- Render item list -->
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
{% for nav_item in nav %} {% for nav_item in nav %}
{% set path = "nav-" + loop.index | string %} {% set path = "nav-" + loop.index | string %}
{% set level = 1 %} {% set level = 1 %}

View File

@ -50,7 +50,7 @@
</button> </button>
</form> </form>
<div class="md-search__output"> <div class="md-search__output">
<div class="md-search__scrollwrap"> <div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result"> <div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta"> <div class="md-search-result__meta">
{{ lang.t("search.result.placeholder") }} {{ lang.t("search.result.placeholder") }}

View File

@ -39,7 +39,7 @@
<!-- Render item list --> <!-- Render item list -->
{% if toc_ | first is defined %} {% if toc_ | first is defined %}
<label class="md-nav__title" for="__toc">{{ lang.t("toc.title") }}</label> <label class="md-nav__title" for="__toc">{{ lang.t("toc.title") }}</label>
<ul class="md-nav__list"> <ul class="md-nav__list" data-md-scrollfix>
{% for toc_item in toc_ %} {% for toc_item in toc_ %}
{% include "partials/toc-item.html" %} {% include "partials/toc-item.html" %}
{% endfor %} {% endfor %}