-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
99 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@vtbag/utensil-drawer': patch | ||
--- | ||
|
||
Still not officially supported. Code refactorings and renames. Breaking: vtn -> declarative-names. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { setSelectedViewTransitionNames } from '../set-view-transition-names'; | ||
|
||
/* This scripts must be loaded inside the `<head>` of a page. | ||
The function sets up eventListeners that look for script elements with a `data-vtbag-decl` attribute and uses its value to set view transition names. The value is interpreted as a semicolon separated list of `<selector> '=' <prefix>` pairs. Those pairs are then used to set view transition names. | ||
See setSelectedViewTransitionNames() for additional information. | ||
Do not use '=' or ';' in <selector> or <prefix> values | ||
While the `data-vtbag-decl` attribute is interpreted for the old and for the new page, the `data-vtbag-decl-new` and `data-vtbag-decl-old` attributes are only interpreted when the page is entered and left, respectively. This allows for different view transition names to be set for defining different enter and exit animations when the page is the source or the target page of a navigation. | ||
The elements are also labeled after the DOM is initially loaded but will be updated (extended) on pageswap. | ||
This behavior enables you to access the view transition names before the swap event, e.g. in a click handler, even after a full page reload. | ||
*/ | ||
export function setViewTransitionNamesFromScripts() { | ||
addEventListener('DOMContentLoaded', set('old')); | ||
addEventListener('pagereveal', set('new')); | ||
addEventListener('pageswap', set('old')); | ||
} | ||
function set(what: 'new' | 'old') { | ||
return () => { | ||
document.querySelectorAll('script').forEach((script) => { | ||
const spec = | ||
(script.getAttribute('data-vtbag-decl') ?? '') + | ||
';' + | ||
(script.getAttribute(`data-vtbag-decl-${what}`) ?? ''); | ||
spec.split(/\s*;\s*/).forEach((cmd) => { | ||
let [selector, prefix] = cmd.split(/=/, 2); | ||
if (prefix !== undefined) { | ||
const weak = selector.endsWith('~'); | ||
weak && (selector = selector.slice(0, -1)); | ||
setSelectedViewTransitionNames(selector.trim(), prefix.trim(), !weak); | ||
}}); | ||
}); | ||
}; | ||
} | ||
setViewTransitionNamesFromScripts(); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,40 @@ | ||
export function setViewTransitionNames(selector: string, prefix: any) { | ||
const elements = document.querySelectorAll<HTMLElement>(selector); | ||
/* Sets the view transition name in the style attribute of selected elements, see setGivenViewTransitionNames. | ||
`selector´is an arbitrary CSS selector for the current document | ||
*/ | ||
export function setSelectedViewTransitionNames(selector: string, prefix: any, force = false) { | ||
setGivenViewTransitionNames([...document.querySelectorAll<HTMLElement>(selector)], prefix, force); | ||
} | ||
|
||
/* Sets the view transition name in the style attribute of the given elements. | ||
If `elements` has exactly one entry, `prefix` is used as a name. | ||
Otherwise the `elements` are named with the `prefix` with an appended index starting from 0. | ||
If `force` is true, the names are always set, otherwise only if they are not already set. | ||
If the prefix string ends with a '~', the character is replaced by a '-' and the names are assigned in random order. | ||
*/ | ||
export function setGivenViewTransitionNames(elements: HTMLElement[], prefix: string, force = false) { | ||
if (prefix[prefix.length - 1] === '~') { | ||
prefix = prefix.slice(0, -1) + '-'; | ||
shuffle(elements); | ||
} | ||
elements.forEach((element, idx, array) => { | ||
element.style.viewTransitionName = `${prefix}${array.length > 1 ? idx : ''}`; | ||
force && (element.style.viewTransitionName = `${prefix}${array.length > 1 ? idx : ''}`) | ||
|| (element.style.viewTransitionName ||= `${prefix}${array.length > 1 ? idx : ''}`); | ||
}); | ||
} | ||
|
||
export function setOldPageViewTransitionNames(selector: string, prefix: any) { | ||
addEventListener('pageswap', () => setViewTransitionNames(selector, prefix)); | ||
addEventListener('pageswap', () => setSelectedViewTransitionNames(selector, prefix)); | ||
} | ||
|
||
// The pagereveal event fires very early. Thus scripts using this code should load inside the <head> | ||
export function setNewPageViewTransitionNames(selector: string, prefix: any) { | ||
addEventListener('pagereveal', () => setViewTransitionNames(selector, prefix)); | ||
addEventListener('pagereveal', () => setSelectedViewTransitionNames(selector, prefix)); | ||
} | ||
|
||
function shuffle<T>(array: T[]): T[] { | ||
for (let i = array.length - 1; i > 0; --i) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[array[i], array[j]] = [array[j], array[i]]; | ||
} | ||
return array; | ||
} |