mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Evaluate script elements upon load when using instant loading
This commit is contained in:
parent
c201b3de5f
commit
ab3ef19498
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
material/assets/javascripts/bundle.4de2b008.min.js.map
Normal file
1
material/assets/javascripts/bundle.4de2b008.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,8 +1,8 @@
|
||||
{
|
||||
"assets/javascripts/bundle.js": "assets/javascripts/bundle.2f004b84.min.js",
|
||||
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.2f004b84.min.js.map",
|
||||
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4de2b008.min.js",
|
||||
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4de2b008.min.js.map",
|
||||
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.926ffd9e.min.js",
|
||||
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.926ffd9e.min.js.map",
|
||||
"assets/stylesheets/main.scss": "assets/stylesheets/main.1e07d700.min.css",
|
||||
"assets/stylesheets/palette.scss": "assets/stylesheets/palette.f5f04e6f.min.css"
|
||||
"assets/stylesheets/main.css": "assets/stylesheets/main.1e07d700.min.css",
|
||||
"assets/stylesheets/palette.css": "assets/stylesheets/palette.f5f04e6f.min.css"
|
||||
}
|
@ -195,7 +195,7 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block scripts %}
|
||||
<script src="{{ 'assets/javascripts/bundle.2f004b84.min.js' | url }}"></script>
|
||||
<script src="{{ 'assets/javascripts/bundle.4de2b008.min.js' | url }}"></script>
|
||||
{%- set translations = {} -%}
|
||||
{%- for key in [
|
||||
"clipboard.copy",
|
||||
|
@ -52,8 +52,7 @@ import {
|
||||
debounceTime,
|
||||
distinctUntilKeyChanged,
|
||||
distinctUntilChanged,
|
||||
bufferCount,
|
||||
startWith
|
||||
bufferCount
|
||||
} from "rxjs/operators"
|
||||
|
||||
import {
|
||||
@ -96,7 +95,8 @@ import {
|
||||
patchTables,
|
||||
patchDetails,
|
||||
patchScrollfix,
|
||||
patchSource
|
||||
patchSource,
|
||||
patchScripts
|
||||
} from "patches"
|
||||
import { isConfig } from "utilities"
|
||||
import { setupDialog } from "integrations/dialog"
|
||||
@ -245,12 +245,12 @@ export function initialize(config: unknown) {
|
||||
|
||||
const keyboard$ = setupKeyboard()
|
||||
|
||||
patchTables({ document$ })
|
||||
patchDetails({ document$, hash$ })
|
||||
patchScripts({ document$ })
|
||||
patchSource({ document$ })
|
||||
patchTables({ document$ })
|
||||
|
||||
/* Force 1px scroll offset to trigger overflow scrolling */
|
||||
if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g))
|
||||
patchScrollfix({ document$ })
|
||||
|
||||
/* Setup clipboard and dialog */
|
||||
|
@ -61,8 +61,7 @@ export function setupClipboard(
|
||||
return NEVER
|
||||
|
||||
/* Inject 'copy-to-clipboard' buttons */
|
||||
document$
|
||||
.subscribe(() => {
|
||||
document$.subscribe(() => {
|
||||
const blocks = getElements("pre > code")
|
||||
for (const [index, block] of blocks.entries()) {
|
||||
const parent = block.parentElement!
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
export * from "./details"
|
||||
export * from "./script"
|
||||
export * from "./scrollfix"
|
||||
export * from "./source"
|
||||
export * from "./table"
|
||||
|
91
src/assets/javascripts/patches/script/index.ts
Normal file
91
src/assets/javascripts/patches/script/index.ts
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020 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, fromEvent, merge } from "rxjs"
|
||||
import {
|
||||
filter,
|
||||
map,
|
||||
skip,
|
||||
switchMapTo,
|
||||
tap,
|
||||
withLatestFrom
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { useComponent } from "components"
|
||||
import {
|
||||
getElement,
|
||||
getElements,
|
||||
watchMedia
|
||||
} from "observables"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
document$: Observable<Document> /* Document observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Patch all `script` elements
|
||||
*
|
||||
* This function must be run after a document switch, which means the first
|
||||
* emission must be ignored.
|
||||
*
|
||||
* @param options - Options
|
||||
*/
|
||||
export function patchScripts(
|
||||
{ document$ }: MountOptions
|
||||
): void {
|
||||
const els$ = document$
|
||||
.pipe(
|
||||
skip(1),
|
||||
withLatestFrom(useComponent("container")),
|
||||
map(([, el]) => getElements<HTMLScriptElement>("script", el))
|
||||
)
|
||||
|
||||
/* Evaluate all scripts via replacement */
|
||||
els$.subscribe(els => {
|
||||
for (const el of els) {
|
||||
if (
|
||||
el.src || !el.type ||
|
||||
/^(application|text)\/javascript$/i.test(el.type)
|
||||
) {
|
||||
const script = document.createElement("script")
|
||||
if (el.src) {
|
||||
script.src = el.src
|
||||
} else {
|
||||
script.innerText = el.innerText
|
||||
}
|
||||
el.replaceWith(script)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, fromEvent, merge } from "rxjs"
|
||||
import { NEVER, Observable, fromEvent, iif, merge } from "rxjs"
|
||||
import { map, mapTo, shareReplay, switchMap } from "rxjs/operators"
|
||||
|
||||
import { getElements } from "observables"
|
||||
@ -36,6 +36,19 @@ interface MountOptions {
|
||||
document$: Observable<Document> /* Document observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Check whetehr the given device is an Apple device
|
||||
*
|
||||
* @return Test result
|
||||
*/
|
||||
function isAppleDevice(): boolean {
|
||||
return /(iPad|iPhone|iPod)/.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@ -67,7 +80,7 @@ export function patchScrollfix(
|
||||
})
|
||||
|
||||
/* Patch overflow scrolling on touch start */
|
||||
els$
|
||||
iif(isAppleDevice, els$, NEVER)
|
||||
.pipe(
|
||||
switchMap(els => merge(...els.map(el => (
|
||||
fromEvent(el, "touchstart")
|
||||
|
@ -52,8 +52,7 @@ export function cache<T>(
|
||||
/* Retrieve value from observable factory and write to storage */
|
||||
} else {
|
||||
const value$ = factory()
|
||||
value$
|
||||
.subscribe(value => {
|
||||
value$.subscribe(value => {
|
||||
try {
|
||||
sessionStorage.setItem(key, JSON.stringify(value))
|
||||
} catch (err) {
|
||||
|
@ -94,13 +94,13 @@
|
||||
|
||||
<!-- Theme-related stylesheets -->
|
||||
{% block styles %}
|
||||
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.scss' | url }}" />
|
||||
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.css' | url }}" />
|
||||
|
||||
<!-- Extra color palette -->
|
||||
{% if palette.primary or palette.accent %}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ 'assets/stylesheets/palette.scss' | url }}"
|
||||
href="{{ 'assets/stylesheets/palette.css' | url }}"
|
||||
/>
|
||||
{% endif %}
|
||||
|
||||
|
@ -161,7 +161,13 @@ function config(args: Configuration): Configuration {
|
||||
plugins: [
|
||||
new AssetsManifestPlugin({
|
||||
output: "assets/manifest.json",
|
||||
assets
|
||||
assets,
|
||||
customize({ key, value }) {
|
||||
return {
|
||||
key: key.replace(/\.scss$/, ".css"),
|
||||
value
|
||||
}
|
||||
}
|
||||
})
|
||||
],
|
||||
|
||||
@ -286,9 +292,12 @@ export default (_env: never, args: Configuration): Configuration[] => {
|
||||
context: "src"
|
||||
}),
|
||||
|
||||
/* Replace assets in base template */
|
||||
/* Hooks */
|
||||
new EventHooksPlugin({
|
||||
afterEmit: () => {
|
||||
|
||||
/* Replace asset URLs in base template */
|
||||
if (args.mode === "production") {
|
||||
const manifest = require("./material/assets/manifest.json")
|
||||
const template = toPairs<string>(manifest)
|
||||
.reduce((content, [from, to]) => {
|
||||
@ -298,6 +307,7 @@ export default (_env: never, args: Configuration): Configuration[] => {
|
||||
/* Save template with replaced assets */
|
||||
fs.writeFileSync("material/base.html", template, "utf8")
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user