Moved source integration into patches

This commit is contained in:
squidfunk 2020-02-19 11:42:51 +01:00
parent ae05805124
commit a6bc272778
12 changed files with 69 additions and 97 deletions

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,6 +1,6 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4120b2e2.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4120b2e2.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4a3df536.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4a3df536.min.js.map",
"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/search.js": "assets/javascripts/worker/search.0a5433f7.min.js",

View File

@ -190,7 +190,7 @@
{% endblock %}
</div>
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.4120b2e2.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.4a3df536.min.js' | url }}"></script>
<script id="__lang" type="application/json">
{%- set translations = {} -%}
{%- for key in [

View File

@ -20,8 +20,13 @@
* IN THE SOFTWARE.
*/
import { Observable, OperatorFunction, pipe } from "rxjs"
import { map, switchMap } from "rxjs/operators"
import { NEVER, Observable, OperatorFunction, pipe } from "rxjs"
import {
catchError,
map,
shareReplay,
switchMap
} from "rxjs/operators"
import {
Header,
@ -68,7 +73,9 @@ export function mountHeaderTitle(
map(({ offset: { y } }) => y >= headline.offsetHeight),
paintHeaderTitle(el)
)
)
),
shareReplay(1),
catchError(() => NEVER)
)
)
)

View File

@ -73,9 +73,13 @@ import {
mountHeaderTitle
} from "components"
import { setupClipboard } from "./integrations/clipboard"
import { patchTables, patchDetails, patchScrollfix } from "patches"
import {
patchTables,
patchDetails,
patchScrollfix,
patchSource
} from "patches"
import { takeIf, not, isConfig } from "utilities"
import { setupSourceFacts } from "integrations/source"
import { renderDialog } from "templates/dialog"
/* ------------------------------------------------------------------------- */
@ -207,13 +211,12 @@ export function initialize(config: unknown) {
patchTables({ document$ })
patchDetails({ document$, hash$ })
patchSource({ document$ })
/* Force 1px scroll offset to trigger overflow scrolling */
if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g))
patchScrollfix({ document$ })
// TODO: general keyboard handler...
// put into main!?
@ -301,10 +304,6 @@ export function initialize(config: unknown) {
// build a notification component! feed txt into it...
// TODO: WIP repo rendering
setupSourceFacts({ document$ })
.subscribe()
/* ----------------------------------------------------------------------- */
const state = {

View File

@ -22,7 +22,7 @@
import * as ClipboardJS from "clipboard"
import { NEVER, Observable, fromEventPattern } from "rxjs"
import { shareReplay, switchMap, tap } from "rxjs/operators"
import { shareReplay } from "rxjs/operators"
import { getElements } from "observables"
import { renderClipboard } from "templates"
@ -55,30 +55,26 @@ interface SetupOptions {
export function setupClipboard(
{ document$ }: SetupOptions
): Observable<ClipboardJS.Event> {
if (ClipboardJS.isSupported()) {
return document$
.pipe(
/* Inject 'copy-to-clipboard' buttons */
tap(() => {
const blocks = getElements("pre > code")
for (const [index, block] of blocks.entries()) {
const parent = block.parentElement!
parent.id = `__code_${index}`
parent.insertBefore(renderClipboard(parent.id), block)
}
}),
/* Initialize and setup clipboard */
switchMap(() => {
return fromEventPattern<ClipboardJS.Event>(next => {
const clipboard = new ClipboardJS(".md-clipboard")
clipboard.on("success", next)
})
}),
shareReplay(1)
)
} else {
if (!ClipboardJS.isSupported())
return NEVER
}
/* Inject 'copy-to-clipboard' buttons */
document$
.subscribe(() => {
const blocks = getElements("pre > code")
for (const [index, block] of blocks.entries()) {
const parent = block.parentElement!
parent.id = `__code_${index}`
parent.insertBefore(renderClipboard(parent.id), block)
}
})
/* Initialize and setup clipboard */
return fromEventPattern<ClipboardJS.Event>(next => {
const clipboard = new ClipboardJS(".md-clipboard")
clipboard.on("success", next)
})
.pipe(
shareReplay(1)
)
}

View File

@ -22,4 +22,5 @@
export * from "./details"
export * from "./scrollfix"
export * from "./source"
export * from "./table"

View File

@ -20,13 +20,13 @@
* IN THE SOFTWARE.
*/
import { NEVER, Observable, of } from "rxjs"
import { switchMap, tap } from "rxjs/operators"
import { NEVER, Observable } from "rxjs"
import { catchError, filter, switchMap } from "rxjs/operators"
import { getElement, getElements } from "observables"
import { getElementOrThrow, getElements } from "observables"
import { renderSource } from "templates"
import { cache, hash } from "utilities"
import { cache } from "utilities"
import { fetchSourceFactsFromGitHub } from "./github"
import { fetchSourceFactsFromGitLab } from "./gitlab"
@ -79,69 +79,38 @@ function fetchSourceFacts(
/* Everything else */
default:
return of([])
return NEVER
}
}
// provide a function to set a unique key?
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
// TODO: this doesnt belong here...
// cache type.. session or local storage...
// subscribe to observable and cache automatically
// withCache or useCache
/**
* Setup source facts
* Patch elements containing repository information
*
* This function will retrieve the URL from the repository link and try to
* query data from integrated source code platforms like GitHub or GitLab.
*
* @param options - Options
*
* @return Source facts observable
*/
export function setupSourceFacts(
export function patchSource(
{ document$ }: SetupOptions
): Observable<any> {
return document$
): void {
document$
.pipe(
switchMap(() => cache("repository", () => {
tap(console.log)
const el = getElement<HTMLAnchorElement>(".md-source[href]") // TODO: useElement( document$ ) ? doesnt emit if no result
if (!el) {
return NEVER
} else {
// TODO: hash should be calculated from el.href
return fetchSourceFacts(el.href)
}
})),
tap(facts => {
console.log(facts)
if (facts.length) {
const sources = getElements(".md-source__repository")
sources.forEach(repo => {
repo.dataset.mdState = "done"
repo.appendChild(renderSource(facts))
})
switchMap(() => {
const el = getElementOrThrow<HTMLAnchorElement>(".md-source[href]")
return cache(`${hash(el.href)}`, () => fetchSourceFacts(el.href))
}),
filter(facts => !!facts.length),
catchError(() => NEVER)
)
.subscribe(facts => {
for (const el of getElements(".md-source__repository")) {
el.setAttribute("data-md-state", "done")
el.appendChild(renderSource(facts))
}
})
// TODO: use URL? to dinstinguish
)
}
// /**
// * Only emit a value if it is non-empty
// *
// * @template T - Value type
// *
// * @return Operator function
// */
// export function exists<T>(): OperatorFunction<T, NonNullable<T>> {
// return pipe(
// switchMap(value => !!value ? NEVER : of(value as NonNullable<T>))
// )
// }