mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-07-23 22:33:42 -04:00
Finished search and moved components to setup functions
This commit is contained in:
@@ -70,7 +70,7 @@ interface Options {
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Watch component map
|
||||
* Watch component mapping
|
||||
*
|
||||
* This function returns an observable that will maintain bindings to the given
|
||||
* components in-between document switches and update the document in-place.
|
||||
@@ -78,7 +78,7 @@ interface Options {
|
||||
* @param names - Component names
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Component map observable
|
||||
* @return Component mapping observable
|
||||
*/
|
||||
export function watchComponentMap(
|
||||
names: Component[], { document$ }: Options
|
||||
|
||||
@@ -28,7 +28,8 @@ import {
|
||||
switchMapTo
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { ViewportOffset, ViewportSize } from "../../../utilities"
|
||||
import { Agent, ViewportOffset } from "utilities"
|
||||
|
||||
import { Header } from "../_"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -39,8 +40,6 @@ import { Header } from "../_"
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
size$: Observable<ViewportSize> /* Viewport size observable */
|
||||
offset$: Observable<ViewportOffset> /* Viewport offset observable */
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
@@ -55,16 +54,17 @@ interface Options {
|
||||
* top of the given element based on the current viewport offset.
|
||||
*
|
||||
* @param el - HTML element
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Viewport offset observable
|
||||
*/
|
||||
export function watchHeaderOffsetToTopOf(
|
||||
el: HTMLElement, { size$, offset$, header$ }: Options
|
||||
el: HTMLElement, { viewport }: Agent, { header$ }: Options
|
||||
): Observable<ViewportOffset> {
|
||||
|
||||
/* Compute necessary adjustment for offset */
|
||||
const adjust$ = size$
|
||||
const adjust$ = viewport.size$
|
||||
.pipe(
|
||||
switchMapTo(header$),
|
||||
map(({ height }) => el.offsetTop - height),
|
||||
@@ -72,7 +72,7 @@ export function watchHeaderOffsetToTopOf(
|
||||
)
|
||||
|
||||
/* Compute relative offset and return as hot observable */
|
||||
return combineLatest([offset$, adjust$])
|
||||
return combineLatest([viewport.offset$, adjust$])
|
||||
.pipe(
|
||||
map(([{ x, y }, adjust]) => ({ x, y: y - adjust })),
|
||||
shareReplay(1)
|
||||
@@ -86,16 +86,17 @@ export function watchHeaderOffsetToTopOf(
|
||||
* bottom of the given element based on the current viewport offset.
|
||||
*
|
||||
* @param el - HTML element
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Viewport offset observable
|
||||
*/
|
||||
export function watchHeaderOffsetToBottomOf(
|
||||
el: HTMLElement, { size$, offset$, header$ }: Options
|
||||
el: HTMLElement, { viewport }: Agent, { header$ }: Options
|
||||
): Observable<ViewportOffset> {
|
||||
|
||||
/* Compute necessary adjustment for offset */
|
||||
const adjust$ = size$
|
||||
const adjust$ = viewport.size$
|
||||
.pipe(
|
||||
switchMapTo(header$),
|
||||
map(({ height }) => el.offsetTop + el.offsetHeight - height),
|
||||
@@ -103,7 +104,7 @@ export function watchHeaderOffsetToBottomOf(
|
||||
)
|
||||
|
||||
/* Compute relative offset and return as hot observable */
|
||||
return combineLatest([offset$, adjust$])
|
||||
return combineLatest([viewport.offset$, adjust$])
|
||||
.pipe(
|
||||
map(([{ x, y }, adjust]) => ({ x, y: y - adjust })),
|
||||
shareReplay(1)
|
||||
|
||||
@@ -32,7 +32,8 @@ import {
|
||||
tap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { resetHeaderShadow, setHeaderShadow } from "../../../actions"
|
||||
import { resetHeaderShadow, setHeaderShadow } from "actions"
|
||||
|
||||
import { Main } from "../../main"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
86
src/assets/javascripts/components/hero/index.ts
Normal file
86
src/assets/javascripts/components/hero/index.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, OperatorFunction, pipe } from "rxjs"
|
||||
import { map, shareReplay } from "rxjs/operators"
|
||||
|
||||
import { switchMapIf } from "extensions"
|
||||
import { Agent, paintHidden } from "utilities"
|
||||
|
||||
import { Header, watchHeaderOffsetToTopOf } from "../header"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Hero
|
||||
*/
|
||||
export interface Hero {
|
||||
hidden: boolean /* Whether the hero is hidden */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup hero from source observable
|
||||
*
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupHero(
|
||||
agent: Agent, { header$ }: Options
|
||||
): OperatorFunction<HTMLElement, Hero> {
|
||||
const { media } = agent
|
||||
return pipe(
|
||||
switchMapIf(media.screen$, el => {
|
||||
|
||||
/* Watch and paint visibility */
|
||||
const hidden$ = watchHeaderOffsetToTopOf(el, agent, { header$ })
|
||||
.pipe(
|
||||
paintHidden(el, 20)
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return hidden$
|
||||
.pipe(
|
||||
map(hidden => ({ hidden }))
|
||||
)
|
||||
}),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
@@ -21,9 +21,10 @@
|
||||
*/
|
||||
|
||||
export * from "./_"
|
||||
export * from "./anchor"
|
||||
export * from "./header"
|
||||
export * from "./hidden"
|
||||
export * from "./hero"
|
||||
export * from "./navigation"
|
||||
export * from "./main"
|
||||
export * from "./search"
|
||||
export * from "./sidebar"
|
||||
export * from "./tabs"
|
||||
export * from "./toc"
|
||||
|
||||
125
src/assets/javascripts/components/main/_/index.ts
Normal file
125
src/assets/javascripts/components/main/_/index.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, OperatorFunction, combineLatest, pipe } from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
pluck,
|
||||
shareReplay,
|
||||
switchMap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { Agent } from "utilities"
|
||||
|
||||
import { Header } from "../../header"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Main area
|
||||
*/
|
||||
export interface Main {
|
||||
offset: number /* Main area top offset */
|
||||
height: number /* Main area visible height */
|
||||
active: boolean /* Scrolled past top offset */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup main area from source observable
|
||||
*
|
||||
* This function returns an observable that computes the visual parameters of
|
||||
* the main area from the viewport height and vertical offset, as well as the
|
||||
* height of the header element. The height of the main area is corrected by
|
||||
* the height of the header (if fixed) and footer element.
|
||||
*
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupMain(
|
||||
{ viewport }: Agent, { header$ }: Options
|
||||
): OperatorFunction<HTMLElement, Main> {
|
||||
return pipe(
|
||||
switchMap(el => {
|
||||
|
||||
/* Compute necessary adjustment for header */
|
||||
const adjust$ = header$
|
||||
.pipe(
|
||||
pluck("height")
|
||||
)
|
||||
|
||||
/* Compute the main area's visible height */
|
||||
const height$ = combineLatest([
|
||||
viewport.offset$,
|
||||
viewport.size$,
|
||||
adjust$
|
||||
])
|
||||
.pipe(
|
||||
map(([{ y }, { height }, adjust]) => {
|
||||
const top = el.offsetTop
|
||||
const bottom = el.offsetHeight + top
|
||||
return height
|
||||
- Math.max(0, top - y, adjust)
|
||||
- Math.max(0, height + y - bottom)
|
||||
}),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
/* Compute whether the viewport offset is past the main area's top */
|
||||
const active$ = combineLatest([viewport.offset$, adjust$])
|
||||
.pipe(
|
||||
map(([{ y }, adjust]) => y >= el.offsetTop - adjust),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return combineLatest([height$, adjust$, active$])
|
||||
.pipe(
|
||||
map(([height, adjust, active]) => ({
|
||||
offset: el.offsetTop - adjust,
|
||||
height,
|
||||
active
|
||||
}))
|
||||
)
|
||||
}),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
@@ -20,99 +20,5 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, combineLatest } from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
pluck,
|
||||
shareReplay
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { ViewportOffset, ViewportSize } from "utilities"
|
||||
|
||||
import { Header } from "../header"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Main area
|
||||
*/
|
||||
export interface Main {
|
||||
offset: number /* Main area top offset */
|
||||
height: number /* Main area visible height */
|
||||
active: boolean /* Scrolled past top offset */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
size$: Observable<ViewportSize> /* Viewport size observable */
|
||||
offset$: Observable<ViewportOffset> /* Viewport offset observable */
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Watch main area
|
||||
*
|
||||
* This function returns an observable that computes the visual parameters of
|
||||
* the main area from the viewport height and vertical offset, as well as the
|
||||
* height of the header element. The height of the main area is corrected by
|
||||
* the height of the header (if fixed) and footer element.
|
||||
*
|
||||
* @param el - Main area element
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Main area observable
|
||||
*/
|
||||
export function watchMain(
|
||||
el: HTMLElement, { size$, offset$, header$ }: Options
|
||||
): Observable<Main> {
|
||||
|
||||
/* Compute necessary adjustment for header */
|
||||
const adjust$ = header$
|
||||
.pipe(
|
||||
pluck("height")
|
||||
)
|
||||
|
||||
/* Compute the main area's visible height */
|
||||
const height$ = combineLatest([offset$, size$, adjust$])
|
||||
.pipe(
|
||||
map(([{ y }, { height }, adjust]) => {
|
||||
const top = el.offsetTop
|
||||
const bottom = el.offsetHeight + top
|
||||
return height
|
||||
- Math.max(0, top - y, adjust)
|
||||
- Math.max(0, height + y - bottom)
|
||||
}),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
/* Compute whether the viewport offset is past the main area's top */
|
||||
const active$ = combineLatest([offset$, adjust$])
|
||||
.pipe(
|
||||
map(([{ y }, adjust]) => y >= el.offsetTop - adjust),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return combineLatest([height$, adjust$, active$])
|
||||
.pipe(
|
||||
map(([height, adjust, active]) => ({
|
||||
offset: el.offsetTop - adjust,
|
||||
height,
|
||||
active
|
||||
})),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
export * from "./_"
|
||||
export * from "./sidebar"
|
||||
|
||||
@@ -43,7 +43,7 @@ import {
|
||||
setSidebarHeight,
|
||||
setSidebarLock
|
||||
} from "actions"
|
||||
import { ViewportOffset } from "utilities"
|
||||
import { Agent } from "utilities"
|
||||
|
||||
import { Main } from "../main"
|
||||
|
||||
@@ -67,7 +67,6 @@ export interface Sidebar {
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
offset$: Observable<ViewportOffset> /* Viewport offset observable */
|
||||
main$: Observable<Main> /* Main area observable */
|
||||
}
|
||||
|
||||
@@ -84,12 +83,13 @@ interface Options {
|
||||
* the sidebar is locked and fills the remaining space.
|
||||
*
|
||||
* @param el - Sidebar element
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Sidebar observable
|
||||
*/
|
||||
export function watchSidebar(
|
||||
el: HTMLElement, { offset$, main$ }: Options
|
||||
el: HTMLElement, { viewport }: Agent, { main$ }: Options
|
||||
): Observable<Sidebar> {
|
||||
|
||||
/* Adjust for internal main area offset */
|
||||
@@ -99,7 +99,7 @@ export function watchSidebar(
|
||||
)
|
||||
|
||||
/* Compute the sidebar's available height */
|
||||
const height$ = combineLatest([offset$, main$])
|
||||
const height$ = combineLatest([viewport.offset$, main$])
|
||||
.pipe(
|
||||
map(([{ y }, { offset, height }]) => {
|
||||
return height - adjust + Math.min(adjust, Math.max(0, y - offset))
|
||||
@@ -107,7 +107,7 @@ export function watchSidebar(
|
||||
)
|
||||
|
||||
/* Compute whether the sidebar should be locked */
|
||||
const lock$ = combineLatest([offset$, main$])
|
||||
const lock$ = combineLatest([viewport.offset$, main$])
|
||||
.pipe(
|
||||
map(([{ y }, { offset }]) => y >= offset + adjust)
|
||||
)
|
||||
91
src/assets/javascripts/components/navigation/_/index.ts
Normal file
91
src/assets/javascripts/components/navigation/_/index.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, OperatorFunction, pipe } from "rxjs"
|
||||
import { map, shareReplay } from "rxjs/operators"
|
||||
|
||||
import { switchMapIf } from "extensions"
|
||||
import { Agent } from "utilities"
|
||||
|
||||
import {
|
||||
Main,
|
||||
Sidebar,
|
||||
paintSidebar,
|
||||
watchSidebar
|
||||
} from "../../main"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Navigation
|
||||
*/
|
||||
export interface Navigation {
|
||||
sidebar: Sidebar /* Sidebar */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
main$: Observable<Main> /* Main observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup navigation from source observable
|
||||
*
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupNavigation(
|
||||
agent: Agent, { main$ }: Options
|
||||
): OperatorFunction<HTMLElement, Navigation> {
|
||||
const { media } = agent
|
||||
return pipe(
|
||||
switchMapIf(media.screen$, el => {
|
||||
|
||||
/* Watch and paint sidebar */
|
||||
const sidebar$ = watchSidebar(el, agent, { main$ })
|
||||
.pipe(
|
||||
paintSidebar(el)
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return sidebar$
|
||||
.pipe(
|
||||
map(sidebar => ({ sidebar }))
|
||||
)
|
||||
}),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
23
src/assets/javascripts/components/navigation/index.ts
Normal file
23
src/assets/javascripts/components/navigation/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export * from "./_"
|
||||
85
src/assets/javascripts/components/search/result/_/index.ts
Normal file
85
src/assets/javascripts/components/search/result/_/index.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { identity } from "ramda"
|
||||
import { Observable, OperatorFunction, pipe } from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
map,
|
||||
switchMap,
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { SearchResult } from "modules"
|
||||
import { Agent, watchElementOffset } from "utilities"
|
||||
|
||||
import { paintSearchResultList } from "../list"
|
||||
import { paintSearchResultMeta } from "../meta"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
result$: Observable<SearchResult[]> /* Search result observable */
|
||||
query$: Observable<string> /* Search query observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup search result from source observable
|
||||
*
|
||||
* @param el - Search result element
|
||||
* @param agent - Agent
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupSearchResult(
|
||||
agent: Agent, { result$, query$ }: Options
|
||||
): OperatorFunction<HTMLElement, SearchResult[]> {
|
||||
return pipe(
|
||||
switchMap(el => {
|
||||
const parent = el.parentElement!
|
||||
|
||||
/* Compute whether more elements need to be rendered */
|
||||
const render$ = watchElementOffset(parent, agent)
|
||||
.pipe(
|
||||
map(({ y }) => y >= parent.scrollHeight - parent.offsetHeight - 16),
|
||||
distinctUntilChanged(),
|
||||
filter(identity)
|
||||
)
|
||||
|
||||
/* Paint search results */
|
||||
return result$
|
||||
.pipe(
|
||||
paintSearchResultMeta(el, { query$ }),
|
||||
paintSearchResultList(el, { render$ })
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -20,99 +20,6 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { identity } from "ramda"
|
||||
import {
|
||||
MonoTypeOperatorFunction,
|
||||
Observable,
|
||||
animationFrameScheduler,
|
||||
pipe
|
||||
} from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
mapTo,
|
||||
observeOn,
|
||||
scan,
|
||||
switchMap,
|
||||
tap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import {
|
||||
addToSearchResultList,
|
||||
resetSearchResultList,
|
||||
setSearchResultMeta
|
||||
} from "actions"
|
||||
import { SearchResult } from "modules"
|
||||
import { renderSearchResult } from "templates"
|
||||
import { ViewportSize, watchElementOffset } from "utilities"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
size$: Observable<ViewportSize> /* Viewport size observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Paint search result from source observable
|
||||
*
|
||||
* @param el - Search result element
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function paintSearchResult(
|
||||
el: HTMLElement, { size$ }: Options
|
||||
): MonoTypeOperatorFunction<SearchResult[]> {
|
||||
const container = el.parentElement!
|
||||
|
||||
/* Compute whether the container is near the bottom offset */
|
||||
const render$ = watchElementOffset(container, { size$ })
|
||||
.pipe(
|
||||
map(({ y }) => y >= container.scrollHeight - container.offsetHeight - 16),
|
||||
distinctUntilChanged(),
|
||||
filter(identity)
|
||||
)
|
||||
|
||||
/* Paint search results lazily */
|
||||
const [meta, list] = Array.from(el.children) as HTMLElement[]
|
||||
return pipe(
|
||||
|
||||
/* Paint search result metadata */
|
||||
tap(result => {
|
||||
setSearchResultMeta(meta, result.length)
|
||||
}),
|
||||
|
||||
/* Paint search result list */
|
||||
switchMap(result => render$
|
||||
.pipe(
|
||||
|
||||
/* Defer repaint to next animation frame */
|
||||
observeOn(animationFrameScheduler),
|
||||
scan(index => {
|
||||
while (index < result.length) {
|
||||
addToSearchResultList(list, renderSearchResult(result[index++]))
|
||||
if (container.scrollHeight - container.offsetHeight > 16)
|
||||
break
|
||||
}
|
||||
return index
|
||||
}, 0),
|
||||
mapTo(result),
|
||||
|
||||
/* Reset on complete or error */
|
||||
finalize(() => {
|
||||
resetSearchResultList(list)
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
export * from "./_"
|
||||
export * from "./list"
|
||||
export * from "./meta"
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import {
|
||||
MonoTypeOperatorFunction,
|
||||
Observable,
|
||||
animationFrameScheduler,
|
||||
pipe
|
||||
} from "rxjs"
|
||||
import {
|
||||
finalize,
|
||||
mapTo,
|
||||
observeOn,
|
||||
scan,
|
||||
switchMap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import {
|
||||
addToSearchResultList,
|
||||
resetSearchResultList
|
||||
} from "actions"
|
||||
import { SearchResult } from "modules"
|
||||
import { renderSearchResult } from "templates"
|
||||
import { getElement } from "utilities"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
render$: Observable<boolean> /* Render trigger observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Paint search result list from source observable
|
||||
*
|
||||
* @param el - Search result element
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function paintSearchResultList(
|
||||
el: HTMLElement, { render$ }: Options
|
||||
): MonoTypeOperatorFunction<SearchResult[]> {
|
||||
const parent = el.parentElement!
|
||||
const list = getElement(".md-search-result__list", el)!
|
||||
return pipe(
|
||||
switchMap(result => render$
|
||||
.pipe(
|
||||
|
||||
/* Defer repaint to next animation frame */
|
||||
observeOn(animationFrameScheduler),
|
||||
scan(index => {
|
||||
while (index < result.length) {
|
||||
addToSearchResultList(list, renderSearchResult(result[index++]))
|
||||
if (parent.scrollHeight - parent.offsetHeight > 16)
|
||||
break
|
||||
}
|
||||
return index
|
||||
}, 0),
|
||||
|
||||
/* Re-map to search result */
|
||||
mapTo(result),
|
||||
|
||||
/* Reset on complete or error */
|
||||
finalize(() => {
|
||||
resetSearchResultList(list)
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -20,46 +20,52 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { OperatorFunction, animationFrameScheduler, pipe } from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
tap
|
||||
} from "rxjs/operators"
|
||||
import { MonoTypeOperatorFunction, Observable, pipe } from "rxjs"
|
||||
import { map, withLatestFrom } from "rxjs/operators"
|
||||
|
||||
import { resetHidden, setHidden } from "actions"
|
||||
import { ViewportOffset } from "utilities"
|
||||
import {
|
||||
resetSearchResultMeta,
|
||||
setSearchResultMeta
|
||||
} from "actions"
|
||||
import { SearchResult } from "modules"
|
||||
import { getElement } from "utilities"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
query$: Observable<string> /* Search query observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Paint hideable from source observable
|
||||
* Paint search result metadata from source observable
|
||||
*
|
||||
* @param el - Hideable element
|
||||
* @param offset - Additional offset
|
||||
* @param el - Search result metadata element
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function paintHidden(
|
||||
el: HTMLElement, offset: number = 0
|
||||
): OperatorFunction<ViewportOffset, boolean> {
|
||||
export function paintSearchResultMeta(
|
||||
el: HTMLElement, { query$ }: Options
|
||||
): MonoTypeOperatorFunction<SearchResult[]> {
|
||||
const meta = getElement(".md-search-result__meta", el)!
|
||||
return pipe(
|
||||
map(({ y }) => y >= offset),
|
||||
distinctUntilChanged(),
|
||||
|
||||
/* Defer repaint to next animation frame */
|
||||
observeOn(animationFrameScheduler),
|
||||
tap(value => {
|
||||
setHidden(el, value)
|
||||
}),
|
||||
|
||||
/* Reset on complete or error */
|
||||
finalize(() => {
|
||||
resetHidden(el)
|
||||
withLatestFrom(query$),
|
||||
map(([result, query]) => {
|
||||
if (query) {
|
||||
setSearchResultMeta(meta, result.length)
|
||||
} else {
|
||||
resetSearchResultMeta(meta)
|
||||
}
|
||||
return result
|
||||
})
|
||||
)
|
||||
}
|
||||
86
src/assets/javascripts/components/tabs/index.ts
Normal file
86
src/assets/javascripts/components/tabs/index.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, OperatorFunction, pipe } from "rxjs"
|
||||
import { map, shareReplay } from "rxjs/operators"
|
||||
|
||||
import { switchMapIf } from "extensions"
|
||||
import { Agent, paintHidden } from "utilities"
|
||||
|
||||
import { Header, watchHeaderOffsetToTopOf } from "../header"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Tabs
|
||||
*/
|
||||
export interface Tabs {
|
||||
hidden: boolean /* Whether the tabs are hidden */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup tabs from source observable
|
||||
*
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupTabs(
|
||||
agent: Agent, { header$ }: Options
|
||||
): OperatorFunction<HTMLElement, Tabs> {
|
||||
const { media } = agent
|
||||
return pipe(
|
||||
switchMapIf(media.screen$, el => {
|
||||
|
||||
/* Watch and paint visibility */
|
||||
const hidden$ = watchHeaderOffsetToTopOf(el, agent, { header$ })
|
||||
.pipe(
|
||||
paintHidden(el, 8)
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return hidden$
|
||||
.pipe(
|
||||
map(hidden => ({ hidden }))
|
||||
)
|
||||
}),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
106
src/assets/javascripts/components/toc/_/index.ts
Normal file
106
src/assets/javascripts/components/toc/_/index.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, OperatorFunction, combineLatest, pipe } from "rxjs"
|
||||
import { map, shareReplay } from "rxjs/operators"
|
||||
|
||||
import { switchMapIf } from "extensions"
|
||||
import { Agent, getElements } from "utilities"
|
||||
|
||||
import { Header } from "../../header"
|
||||
import {
|
||||
Main,
|
||||
Sidebar,
|
||||
paintSidebar,
|
||||
watchSidebar
|
||||
} from "../../main"
|
||||
import {
|
||||
AnchorList,
|
||||
paintAnchorList,
|
||||
watchAnchorList
|
||||
} from "../anchor"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Table of contents
|
||||
*/
|
||||
export interface TableOfContents {
|
||||
sidebar: Sidebar /* Sidebar */
|
||||
anchors: AnchorList /* Anchor list */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
header$: Observable<Header> /* Header observable */
|
||||
main$: Observable<Main> /* Main observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Setup table of contents from source observable
|
||||
*
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Operator function
|
||||
*/
|
||||
export function setupTableOfContents(
|
||||
agent: Agent, { header$, main$ }: Options
|
||||
): OperatorFunction<HTMLElement, TableOfContents> {
|
||||
const { media } = agent
|
||||
return pipe(
|
||||
switchMapIf(media.tablet$, el => {
|
||||
|
||||
/* Watch and paint sidebar */
|
||||
const sidebar$ = watchSidebar(el, agent, { main$ })
|
||||
.pipe(
|
||||
paintSidebar(el)
|
||||
)
|
||||
|
||||
/* Watch and paint anchor list (scroll spy) */
|
||||
const els = getElements<HTMLAnchorElement>(".md-nav__link", el)
|
||||
const anchors$ = watchAnchorList(els, agent, { header$ })
|
||||
.pipe(
|
||||
paintAnchorList(els)
|
||||
)
|
||||
|
||||
/* Combine into a single hot observable */
|
||||
return combineLatest([sidebar$, anchors$])
|
||||
.pipe(
|
||||
map(([sidebar, anchors]) => ({ sidebar, anchors }))
|
||||
)
|
||||
}),
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
@@ -45,13 +45,9 @@ import {
|
||||
setAnchorActive,
|
||||
setAnchorBlur
|
||||
} from "actions"
|
||||
import {
|
||||
ViewportOffset,
|
||||
ViewportSize,
|
||||
getElement
|
||||
} from "utilities"
|
||||
import { Agent, getElement } from "utilities"
|
||||
|
||||
import { Header } from "../header"
|
||||
import { Header } from "../../header"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
@@ -73,8 +69,6 @@ export interface AnchorList {
|
||||
* Options
|
||||
*/
|
||||
interface Options {
|
||||
size$: Observable<ViewportSize> /* Viewport size observable */
|
||||
offset$: Observable<ViewportOffset> /* Viewport offset observable */
|
||||
header$: Observable<Header> /* Header observable */
|
||||
}
|
||||
|
||||
@@ -98,12 +92,13 @@ interface Options {
|
||||
* Note that the current anchor is the last item of the `prev` anchor list.
|
||||
*
|
||||
* @param els - Anchor elements
|
||||
* @param agent - Agent
|
||||
* @param options - Options
|
||||
*
|
||||
* @return Anchor list observable
|
||||
*/
|
||||
export function watchAnchorList(
|
||||
els: HTMLAnchorElement[], { size$, offset$, header$ }: Options
|
||||
els: HTMLAnchorElement[], { viewport }: Agent, { header$ }: Options
|
||||
): Observable<AnchorList> {
|
||||
const table = new Map<HTMLAnchorElement, HTMLElement>()
|
||||
for (const el of els) {
|
||||
@@ -120,7 +115,7 @@ export function watchAnchorList(
|
||||
)
|
||||
|
||||
/* Compute partition of previous and next anchors */
|
||||
const partition$ = size$
|
||||
const partition$ = viewport.size$
|
||||
.pipe(
|
||||
|
||||
/* Build index to map anchor paths to vertical offsets */
|
||||
@@ -143,7 +138,7 @@ export function watchAnchorList(
|
||||
}),
|
||||
|
||||
/* Re-compute partition when viewport offset changes */
|
||||
switchMap(index => combineLatest(offset$, adjust$)
|
||||
switchMap(index => combineLatest(viewport.offset$, adjust$)
|
||||
.pipe(
|
||||
scan(([prev, next], [{ y }, adjust]) => {
|
||||
|
||||
24
src/assets/javascripts/components/toc/index.ts
Normal file
24
src/assets/javascripts/components/toc/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export * from "./_"
|
||||
export * from "./anchor"
|
||||
Reference in New Issue
Block a user