@hyperframes/core 0.8.207 → 0.8.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/hyperframe.runtime.iife.js +67 -67
- package/dist/runtime/clock.js +1 -1
- package/dist/runtime/mediaSteer.d.ts +1 -0
- package/dist/runtime/mediaSteer.js +1 -0
- package/dist/runtime/state.d.ts +1 -2
- package/dist/runtime/timeline.js +4 -4
- package/dist/runtime/types.d.ts +21 -0
- package/package.json +4 -4
- package/dist/runtime/adapters/seek-dispatch.d.ts +0 -37
- package/dist/runtime/adapters/seek-dispatch.js +0 -143
- package/dist/runtime/media.d.ts +0 -131
- package/dist/runtime/media.js +0 -586
- package/dist/runtime/preloadMedia.d.ts +0 -12
- package/dist/runtime/preloadMedia.js +0 -108
- package/dist/runtime/timedClipHide.d.ts +0 -12
- package/dist/runtime/timedClipHide.js +0 -93
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { parseStrictFiniteTimingNumber, readMediaStart } from "./playbackRate.js";
|
|
2
|
-
import { createRuntimeStartTimeResolver } from "./startResolver.js";
|
|
3
|
-
import { readMediaRenderId } from "./renderFrameSibling.js";
|
|
4
|
-
import { defersMedia } from "./timedClipHide.js";
|
|
5
|
-
import { swallow } from "./diagnostics.js";
|
|
6
|
-
import { mediaElementTime } from "./mediaClock.js";
|
|
7
|
-
export function isRenderFrameVideo(media) {
|
|
8
|
-
const ids = window
|
|
9
|
-
.__HF_RENDER_FRAME_VIDEO_IDS;
|
|
10
|
-
return media.tagName === "VIDEO" && ids?.includes(readMediaRenderId(media) ?? "") === true;
|
|
11
|
-
}
|
|
12
|
-
export function preloadMedia(media) {
|
|
13
|
-
if (isRenderFrameVideo(media))
|
|
14
|
-
return;
|
|
15
|
-
if (media.preload !== "auto")
|
|
16
|
-
media.preload = "auto";
|
|
17
|
-
// load() resets an in-flight video fetch, discarding its selected resource and buffered data.
|
|
18
|
-
const videoAlreadyLoading = media.tagName === "VIDEO" && media.networkState === 2;
|
|
19
|
-
if (media.readyState < 3 && !videoAlreadyLoading)
|
|
20
|
-
media.load();
|
|
21
|
-
}
|
|
22
|
-
const pendingPlaybackStart = new WeakMap();
|
|
23
|
-
function cancelPlaybackStart(media) {
|
|
24
|
-
pendingPlaybackStart.get(media)?.();
|
|
25
|
-
}
|
|
26
|
-
export function prepareUpcomingMedia(media, isUpcoming) {
|
|
27
|
-
cancelPlaybackStart(media);
|
|
28
|
-
if (media.tagName !== "VIDEO" || isRenderFrameVideo(media))
|
|
29
|
-
return;
|
|
30
|
-
const prepare = () => {
|
|
31
|
-
if (!media.isConnected || !media.paused || media.seeking || !isUpcoming())
|
|
32
|
-
return;
|
|
33
|
-
const start = readMediaStart(media);
|
|
34
|
-
if (Math.abs(media.currentTime - start) <= 0.02)
|
|
35
|
-
return;
|
|
36
|
-
try {
|
|
37
|
-
media.currentTime = mediaElementTime(start);
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
swallow("runtime.preload.playbackStart", error);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
if (media.readyState > 0) {
|
|
44
|
-
prepare();
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const cancel = () => {
|
|
48
|
-
media.removeEventListener("loadedmetadata", loaded);
|
|
49
|
-
media.removeEventListener("error", cancel);
|
|
50
|
-
media.removeEventListener("abort", cancel);
|
|
51
|
-
pendingPlaybackStart.delete(media);
|
|
52
|
-
};
|
|
53
|
-
const loaded = () => {
|
|
54
|
-
cancel();
|
|
55
|
-
prepare();
|
|
56
|
-
};
|
|
57
|
-
pendingPlaybackStart.set(media, cancel);
|
|
58
|
-
media.addEventListener("loadedmetadata", loaded);
|
|
59
|
-
media.addEventListener("error", cancel);
|
|
60
|
-
media.addEventListener("abort", cancel);
|
|
61
|
-
}
|
|
62
|
-
/** Ends a fetch in flight for good, which preload none alone does not. */
|
|
63
|
-
export function stopMediaDownload(media) {
|
|
64
|
-
cancelPlaybackStart(media);
|
|
65
|
-
for (const source of media.querySelectorAll("source"))
|
|
66
|
-
source.remove();
|
|
67
|
-
media.removeAttribute("src");
|
|
68
|
-
media.load();
|
|
69
|
-
}
|
|
70
|
-
export function releaseMedia(media) {
|
|
71
|
-
if (media.querySelector("source"))
|
|
72
|
-
return;
|
|
73
|
-
const src = media.getAttribute("src");
|
|
74
|
-
stopMediaDownload(media);
|
|
75
|
-
if (src !== null)
|
|
76
|
-
media.setAttribute("src", src);
|
|
77
|
-
}
|
|
78
|
-
export function lengthIsAuthored(media) {
|
|
79
|
-
return parseStrictFiniteTimingNumber(media.getAttribute("data-duration")) != null;
|
|
80
|
-
}
|
|
81
|
-
/** Preview only: later clips parse at preload none, as Chromium ignores a none set mid-fetch.
|
|
82
|
-
* One watcher per page: a runtime evaluated again replaces the last one's. */
|
|
83
|
-
export function deferMediaUntilDue() {
|
|
84
|
-
const win = window;
|
|
85
|
-
win.__hfMediaDeferral?.disconnect();
|
|
86
|
-
win.__hfMediaDeferral = undefined;
|
|
87
|
-
if (!defersMedia())
|
|
88
|
-
return;
|
|
89
|
-
const defer = (el, startInFilm) => {
|
|
90
|
-
const start = parseStrictFiniteTimingNumber(el.getAttribute("data-start"));
|
|
91
|
-
if (start != null && lengthIsAuthored(el) && startInFilm(el) > 0)
|
|
92
|
-
el.preload = "none";
|
|
93
|
-
};
|
|
94
|
-
win.__hfMediaDeferral = new MutationObserver((records) => {
|
|
95
|
-
const startInFilm = createRuntimeStartTimeResolver({}).resolveMediaStartForElement;
|
|
96
|
-
for (const record of records)
|
|
97
|
-
for (const node of record.addedNodes) {
|
|
98
|
-
if (node.nodeType !== 1)
|
|
99
|
-
continue;
|
|
100
|
-
const el = node;
|
|
101
|
-
if (el.matches("video, audio"))
|
|
102
|
-
defer(el, startInFilm);
|
|
103
|
-
for (const media of el.querySelectorAll("video, audio"))
|
|
104
|
-
defer(media, startInFilm);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
win.__hfMediaDeferral.observe(document.documentElement, { childList: true, subtree: true });
|
|
108
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { CLIP_HIDDEN_ATTR } from "./clipReveal.js";
|
|
2
|
-
export { CLIP_HIDDEN_ATTR };
|
|
3
|
-
export declare const SKIPPED_CLIP = "[data-start]:not(video, audio, img, [data-hf-upcoming], [data-hf-autostamped])[data-hf-clip-hidden]";
|
|
4
|
-
export declare function showHiddenClips(only?: (el: HTMLElement) => boolean): () => void;
|
|
5
|
-
export declare function showClips(hidden: Array<Element & ElementCSSInlineStyle>): () => void;
|
|
6
|
-
export declare function defersMedia(): boolean;
|
|
7
|
-
/** True in Studio's preview, where hidden clips' images are neither fetched nor decoded until due. */
|
|
8
|
-
export declare function skipsHiddenImages(): boolean;
|
|
9
|
-
export declare function hideTimedClipsUntilFirstPass(): void;
|
|
10
|
-
/** True when this call lifted the rule; callers then re-register what skipped hidden elements (grading). */
|
|
11
|
-
export declare function revealTimedClipsAfterFirstPass(): boolean;
|
|
12
|
-
export declare function keepInlineHideRulesForOlderShaders(): void;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { CLIP_HIDDEN_ATTR, olderShaderBuildOnPage, revealClip } from "./clipReveal.js";
|
|
2
|
-
import { RUNTIME_STAMPED_ATTR, STUDIO_PREVIEW_CAPTURE_MODE, STUDIO_PREVIEW_MARK_META, STUDIO_PREVIEW_UPCOMING_ATTR, } from "../studioPreviewMark.js";
|
|
3
|
-
// Hides timed non-media clips from script evaluation until the first visibility pass decides them;
|
|
4
|
-
// before it, a paused page painted every clip at once. Media is left to init's media pass.
|
|
5
|
-
// The rule and its flag live on the page, so every runtime copy shares them.
|
|
6
|
-
const HIDE_ATTR = "data-hf-first-pass-hide";
|
|
7
|
-
const HIDE_UNTIL_FIRST_PASS = "[data-start]:not(video, audio, img) { visibility: hidden !important; }";
|
|
8
|
-
const PREVIEW_HIDE_UNTIL_FIRST_PASS = 'img[loading="lazy"] { display: none !important; }';
|
|
9
|
-
const SKIP_ATTR = "data-hf-skip-hidden-images";
|
|
10
|
-
export { CLIP_HIDDEN_ATTR };
|
|
11
|
-
const SKIPPABLE_CLIP = `[data-start]:not(video, audio, img, [${STUDIO_PREVIEW_UPCOMING_ATTR}], [${RUNTIME_STAMPED_ATTR}])`;
|
|
12
|
-
export const SKIPPED_CLIP = `${SKIPPABLE_CLIP}[${CLIP_HIDDEN_ATTR}]`;
|
|
13
|
-
const STUDIO_PREVIEW_MARK = `meta[name="${STUDIO_PREVIEW_MARK_META}"]`;
|
|
14
|
-
const CONTENTS_ATTR = "data-hf-hidden-clip-contents";
|
|
15
|
-
const HIDDEN_CLIP_DOUBLED_FOR_WEIGHT = `[${CLIP_HIDDEN_ATTR}][${CLIP_HIDDEN_ATTR}]`;
|
|
16
|
-
const HIDDEN_CLIP_BY_INLINE_STYLE = `[${CLIP_HIDDEN_ATTR}][style*="visibility: hidden"]`;
|
|
17
|
-
const skipHiddenImages = (clip) => `${SKIPPABLE_CLIP}${clip} img { display: none !important; }`;
|
|
18
|
-
const hideHiddenClipContents = (clip) => {
|
|
19
|
-
const filterOutputLayers = [clip, `${clip} *`]
|
|
20
|
-
.flatMap((layer) => [layer, `${layer}::before`, `${layer}::after`])
|
|
21
|
-
.join(", ");
|
|
22
|
-
return `${clip} * { visibility: hidden !important; } ${filterOutputLayers} { filter: none !important; }`;
|
|
23
|
-
};
|
|
24
|
-
export function showHiddenClips(only = () => true) {
|
|
25
|
-
return showClips(Array.from(document.querySelectorAll(`[${CLIP_HIDDEN_ATTR}]`)).filter(only));
|
|
26
|
-
}
|
|
27
|
-
export function showClips(hidden) {
|
|
28
|
-
const putMarksBack = hidden.map((el) => revealClip(el));
|
|
29
|
-
return () => {
|
|
30
|
-
for (const el of hidden) {
|
|
31
|
-
if (el.style.getPropertyValue("visibility") !== "hidden")
|
|
32
|
-
el.style.setProperty("visibility", "hidden", "important");
|
|
33
|
-
}
|
|
34
|
-
for (const putMarkBack of putMarksBack)
|
|
35
|
-
putMarkBack();
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function appendStyle(parent, attr, css) {
|
|
39
|
-
const style = document.createElement("style");
|
|
40
|
-
style.setAttribute(attr, "");
|
|
41
|
-
style.textContent = css;
|
|
42
|
-
parent.appendChild(style);
|
|
43
|
-
}
|
|
44
|
-
export function defersMedia() {
|
|
45
|
-
return document.querySelector(STUDIO_PREVIEW_MARK) !== null;
|
|
46
|
-
}
|
|
47
|
-
/** True in Studio's preview, where hidden clips' images are neither fetched nor decoded until due. */
|
|
48
|
-
export function skipsHiddenImages() {
|
|
49
|
-
return document.querySelector(`style[${SKIP_ATTR}]`) !== null;
|
|
50
|
-
}
|
|
51
|
-
export function hideTimedClipsUntilFirstPass() {
|
|
52
|
-
if (typeof document === "undefined")
|
|
53
|
-
return;
|
|
54
|
-
const parent = document.head ?? document.documentElement;
|
|
55
|
-
if (!parent)
|
|
56
|
-
return;
|
|
57
|
-
const mark = document.querySelector(STUDIO_PREVIEW_MARK);
|
|
58
|
-
const preview = mark !== null;
|
|
59
|
-
const capture = mark?.getAttribute("content") === STUDIO_PREVIEW_CAPTURE_MODE;
|
|
60
|
-
if (preview && !capture && !skipsHiddenImages())
|
|
61
|
-
appendStyle(parent, SKIP_ATTR, skipHiddenImages(HIDDEN_CLIP_DOUBLED_FOR_WEIGHT));
|
|
62
|
-
if (!document.querySelector(`style[${CONTENTS_ATTR}]`))
|
|
63
|
-
appendStyle(parent, CONTENTS_ATTR, hideHiddenClipContents(HIDDEN_CLIP_DOUBLED_FOR_WEIGHT));
|
|
64
|
-
const win = window;
|
|
65
|
-
// A runtime that already initialised may never run another pass to lift a new rule.
|
|
66
|
-
if (win.__hfFirstPassHidden || win.__hyperframeRuntimeBootstrapped)
|
|
67
|
-
return;
|
|
68
|
-
const css = preview
|
|
69
|
-
? `${HIDE_UNTIL_FIRST_PASS} ${PREVIEW_HIDE_UNTIL_FIRST_PASS}`
|
|
70
|
-
: HIDE_UNTIL_FIRST_PASS;
|
|
71
|
-
appendStyle(parent, HIDE_ATTR, css);
|
|
72
|
-
win.__hfFirstPassHidden = true;
|
|
73
|
-
}
|
|
74
|
-
/** True when this call lifted the rule; callers then re-register what skipped hidden elements (grading). */
|
|
75
|
-
export function revealTimedClipsAfterFirstPass() {
|
|
76
|
-
const win = window;
|
|
77
|
-
if (!win.__hfFirstPassHidden)
|
|
78
|
-
return false;
|
|
79
|
-
win.__hfFirstPassHidden = false;
|
|
80
|
-
for (const style of document.querySelectorAll(`style[${HIDE_ATTR}]`))
|
|
81
|
-
style.remove();
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
export function keepInlineHideRulesForOlderShaders() {
|
|
85
|
-
if (!olderShaderBuildOnPage())
|
|
86
|
-
return;
|
|
87
|
-
const skip = document.querySelector(`style[${SKIP_ATTR}]`);
|
|
88
|
-
if (skip)
|
|
89
|
-
skip.textContent = skipHiddenImages(HIDDEN_CLIP_BY_INLINE_STYLE);
|
|
90
|
-
const contents = document.querySelector(`style[${CONTENTS_ATTR}]`);
|
|
91
|
-
if (contents)
|
|
92
|
-
contents.textContent = hideHiddenClipContents(HIDDEN_CLIP_BY_INLINE_STYLE);
|
|
93
|
-
}
|