nanosplash 3.0.0 → 3.0.2
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/.github/workflows/ci.yml +50 -44
- package/.github/workflows/vitepress.yml +69 -0
- package/.prettierignore +1 -0
- package/.prettierrc +10 -10
- package/LICENSE +21 -0
- package/README.md +14 -41
- package/bun.lockb +0 -0
- package/coverage/DomUtilities.ts.html +568 -0
- package/coverage/Service.ts.html +718 -0
- package/coverage/Splash.ts.html +448 -0
- package/coverage/SplashQueue.ts.html +232 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +560 -0
- package/coverage/coverage-final.json +5 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +161 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/dist/cjs/ns.cjs +2 -0
- package/dist/es/ns.js +342 -0
- package/dist/iife/ns.iife.js +2 -0
- package/docs/.vitepress/config.ts +75 -0
- package/docs/.vitepress/theme/css/style.css +157 -0
- package/docs/.vitepress/theme/index.ts +16 -0
- package/docs/.vitepress/theme/vue/Card.vue +31 -0
- package/docs/.vitepress/theme/vue/CardGrid.vue +17 -0
- package/docs/.vitepress/theme/vue/Exe.vue +86 -0
- package/docs/.vitepress/theme/vue/PlayGround.vue +50 -0
- package/docs/api/doc/hide.md +69 -0
- package/docs/api/doc/show.md +47 -0
- package/docs/api/start/features.md +17 -0
- package/docs/api/start/install.md +53 -0
- package/docs/api/start/playground.md +11 -0
- package/docs/api/start/usage.md +25 -0
- package/docs/index.md +30 -0
- package/package.json +86 -66
- package/src/style/ns.sass +95 -0
- package/src/ts/core/DomUtilities.ts +161 -0
- package/src/ts/core/Service.ts +211 -0
- package/src/ts/core/{Nanosplash/interfaces/NanosplashAPI.ts → ServiceInterface.ts} +18 -10
- package/src/ts/core/Splash.ts +121 -0
- package/src/ts/core/SplashInterface.ts +46 -0
- package/src/ts/core/SplashQueue.ts +49 -0
- package/src/ts/main.ts +9 -0
- package/src/ts/types/Types.ts +3 -0
- package/src/ts/types/global.d.ts +14 -0
- package/src/vite-env.d.ts +0 -8
- package/tests/DomUtilities.spec.ts +117 -0
- package/tests/Guid.spec.ts +5 -5
- package/tests/Service.spec.ts +198 -0
- package/tests/Splash.spec.ts +64 -0
- package/tests/TestUtilities.ts +48 -0
- package/tsconfig.json +21 -20
- package/vite.config.ts +14 -22
- package/dist/main.css +0 -1
- package/dist/ns.cjs.js +0 -1
- package/dist/ns.es.js +0 -330
- package/dist/ns.iife.js +0 -2
- package/index.html +0 -52
- package/src/main.ts +0 -8
- package/src/sass/ns.sass +0 -86
- package/src/ts/core/Nanosplash/Nanosplash.ts +0 -97
- package/src/ts/core/Nanosplash/interfaces/NanosplashInterface.ts +0 -42
- package/src/ts/core/Nanosplash/repositories/NanosplashRepository.ts +0 -178
- package/src/ts/core/Nanosplash/services/NanosplashService.ts +0 -222
- package/src/ts/types/Alias.d.ts +0 -1
- package/src/ts/types/Nanosplash.d.ts +0 -18
- package/src/ts/types/NanosplashService.d.ts +0 -1
- package/src/ts/util/Guid.ts +0 -13
- package/src/ts/util/Stack.ts +0 -73
- package/tests/Nanosplash.spec.ts +0 -64
- package/tests/NanosplashRepository.spec.ts +0 -91
- package/tests/NanosplashService.spec.ts +0 -119
- package/tests/Stack.spec.ts +0 -56
package/package.json
CHANGED
|
@@ -1,67 +1,87 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
2
|
+
"name": "nanosplash",
|
|
3
|
+
"description": "The tiny loading screen for web artisans",
|
|
4
|
+
"private": false,
|
|
5
|
+
"version": "3.0.2",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Isak K. Hauge",
|
|
9
|
+
"email": "isakhauge@icloud.com",
|
|
10
|
+
"url": "https://no.linkedin.com/in/isakhauge"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"loading",
|
|
14
|
+
"loader",
|
|
15
|
+
"screen",
|
|
16
|
+
"splash",
|
|
17
|
+
"nano",
|
|
18
|
+
"nanosplash",
|
|
19
|
+
"small",
|
|
20
|
+
"tiny",
|
|
21
|
+
"es",
|
|
22
|
+
"esm",
|
|
23
|
+
"ts",
|
|
24
|
+
"typescript",
|
|
25
|
+
"iife",
|
|
26
|
+
"cdn",
|
|
27
|
+
"vite"
|
|
28
|
+
],
|
|
29
|
+
"homepage": "https://isakhauge.github.io/nanosplash",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/isakhauge/nanosplash.git"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"main": "./dist/latest/es/ns.js",
|
|
36
|
+
"module": "./dist/latest/es/ns.js",
|
|
37
|
+
"source": "./src/main.ts",
|
|
38
|
+
"unpkg": "./dist/latest/iife/ns.iife.js",
|
|
39
|
+
"style": "./dist/latest/es/style.css",
|
|
40
|
+
"exports": {
|
|
41
|
+
".": {
|
|
42
|
+
"types": {
|
|
43
|
+
"require": "./src/ts/types/global.d.ts",
|
|
44
|
+
"default": "./src/ts/types/global.d.ts"
|
|
45
|
+
},
|
|
46
|
+
"browser": {
|
|
47
|
+
"require": "./dist/latest/cjs/ns.cjs",
|
|
48
|
+
"default": "./dist/latest/es/ns.js"
|
|
49
|
+
},
|
|
50
|
+
"default": {
|
|
51
|
+
"require": "./dist/latest/cjs/ns.cjs",
|
|
52
|
+
"default": "./dist/latest/es/ns.js"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"types": "./src/ts/types/global.d.ts",
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "bun build:all && bun build:docs",
|
|
59
|
+
"build:es": "tsc && cross-env entry=./src/ts/core/Service.ts format=es bun vite build -m production --c vite.config.ts",
|
|
60
|
+
"build:cjs": "tsc && cross-env entry=./src/ts/core/Service.ts format=cjs bun vite build -m production --c vite.config.ts",
|
|
61
|
+
"build:iife": "tsc && cross-env entry=./src/ts/main.ts format=iife bun vite build -m production --c vite.config.ts",
|
|
62
|
+
"build:all": "bun build:es && bun build:cjs && bun build:iife",
|
|
63
|
+
"build:docs": "bun docs:build",
|
|
64
|
+
"preview": "vite preview",
|
|
65
|
+
"test": "vitest",
|
|
66
|
+
"test:ui": "vitest --ui",
|
|
67
|
+
"coverage": "vitest --coverage",
|
|
68
|
+
"docs:dev": "vitepress dev docs",
|
|
69
|
+
"docs:build": "vitepress build docs",
|
|
70
|
+
"docs:preview": "vitepress preview docs"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@types/jsdom": "^21.1.3",
|
|
74
|
+
"@types/node": "^20.8.6",
|
|
75
|
+
"@types/rollup": "^0.54.0",
|
|
76
|
+
"@vitest/coverage-v8": "^0.34.6",
|
|
77
|
+
"@vitest/ui": "^0.34.6",
|
|
78
|
+
"cross-env": "^7.0.3",
|
|
79
|
+
"jsdom": "^22.1.0",
|
|
80
|
+
"sass": "^1.69.3",
|
|
81
|
+
"terser": "^5.22.0",
|
|
82
|
+
"typescript": "^5.2.2",
|
|
83
|
+
"vite": "^4.4.11",
|
|
84
|
+
"vitepress": "1.0.0-rc.22",
|
|
85
|
+
"vitest": "^0.34.6"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
%maximize
|
|
2
|
+
width: 100%
|
|
3
|
+
height: 100%
|
|
4
|
+
|
|
5
|
+
%upper-left
|
|
6
|
+
top: 0
|
|
7
|
+
left: 0
|
|
8
|
+
|
|
9
|
+
%flex-center-xy
|
|
10
|
+
display: flex
|
|
11
|
+
justify-content: center
|
|
12
|
+
align-items: center
|
|
13
|
+
|
|
14
|
+
// Nanosplash host scoped varibles
|
|
15
|
+
.nsh
|
|
16
|
+
--color: DarkSlateGray
|
|
17
|
+
--size: 20px
|
|
18
|
+
--relSize: calc(var(--size) * 0.9)
|
|
19
|
+
--font: 'Helvetica', 'Arial', sans-serif
|
|
20
|
+
--weight: 400
|
|
21
|
+
--bg: #{ rgba(White, 0.8) }
|
|
22
|
+
--zIdx: 999999999
|
|
23
|
+
--blur: blur(10px)
|
|
24
|
+
|
|
25
|
+
// Nanosplash host
|
|
26
|
+
.nsh
|
|
27
|
+
position: relative
|
|
28
|
+
z-index: var(--zIdx)
|
|
29
|
+
&::before
|
|
30
|
+
@extend %maximize
|
|
31
|
+
@extend %upper-left
|
|
32
|
+
position: absolute
|
|
33
|
+
background-color: var(--bg)
|
|
34
|
+
content: ''
|
|
35
|
+
backdrop-filter: var(--blur)
|
|
36
|
+
-webkit-backdrop-filter: var(--blur)
|
|
37
|
+
z-index: calc(var(--zIdx) + 1)
|
|
38
|
+
border-radius: inherit
|
|
39
|
+
|
|
40
|
+
// When Nanosplash host is the document body
|
|
41
|
+
body.nsh
|
|
42
|
+
height: 100vh
|
|
43
|
+
|
|
44
|
+
// Nanosplash (main element)
|
|
45
|
+
.ns
|
|
46
|
+
@extend %maximize
|
|
47
|
+
@extend %upper-left
|
|
48
|
+
@extend %flex-center-xy
|
|
49
|
+
position: absolute
|
|
50
|
+
z-index: calc(var(--zIdx) + 2)
|
|
51
|
+
|
|
52
|
+
// Nanosplash container
|
|
53
|
+
.nsc
|
|
54
|
+
@extend %flex-center-xy
|
|
55
|
+
filter: drop-shadow(0 0 0.1rem #{ rgba(LightGray, 0.5) })
|
|
56
|
+
|
|
57
|
+
// Nanosplash text
|
|
58
|
+
.nst
|
|
59
|
+
color: var(--color)
|
|
60
|
+
font-size: var(--size)
|
|
61
|
+
font-family: var(--font)
|
|
62
|
+
font-weight: var(--weight)
|
|
63
|
+
margin-right: var(--relSize)
|
|
64
|
+
text-shadow: 0 0 0.06rem #{ rgba(DarkSlateGray, .25) }
|
|
65
|
+
|
|
66
|
+
// Nanosplash spinner
|
|
67
|
+
.nss
|
|
68
|
+
display: block
|
|
69
|
+
width: var(--relSize)
|
|
70
|
+
height: var(--relSize)
|
|
71
|
+
& > svg
|
|
72
|
+
animation: Rotate 2s linear infinite
|
|
73
|
+
position: relative
|
|
74
|
+
width: inherit
|
|
75
|
+
height: inherit
|
|
76
|
+
stroke-width: 8
|
|
77
|
+
& .path
|
|
78
|
+
stroke: var(--color)
|
|
79
|
+
stroke-linecap: round
|
|
80
|
+
animation: Dash 1.5s ease-in-out infinite
|
|
81
|
+
|
|
82
|
+
// Spinner animations:
|
|
83
|
+
@keyframes Rotate
|
|
84
|
+
100%
|
|
85
|
+
transform: rotate(360deg)
|
|
86
|
+
@keyframes Dash
|
|
87
|
+
0%
|
|
88
|
+
stroke-dasharray: 1, 150
|
|
89
|
+
stroke-dashoffset: 0
|
|
90
|
+
50%
|
|
91
|
+
stroke-dasharray: 90, 150
|
|
92
|
+
stroke-dashoffset: -35
|
|
93
|
+
100%
|
|
94
|
+
stroke-dasharray: 90, 150
|
|
95
|
+
stroke-dashoffset: -124
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Reference } from '../types/Types'
|
|
2
|
+
import { Service } from './Service'
|
|
3
|
+
import { Splash } from './Splash'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* # DOM Utilities
|
|
7
|
+
* A collection of functions that are used by the Nanosplash classes.
|
|
8
|
+
* @see Splash
|
|
9
|
+
* @see Service
|
|
10
|
+
* @author Isak K. Hauge <isakhauge@icloud.com>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* # Render
|
|
15
|
+
* @param html HTML string to render.
|
|
16
|
+
* @returns Rendered HTML element.
|
|
17
|
+
*/
|
|
18
|
+
export function render(html: string): HTMLElement {
|
|
19
|
+
return (div =>
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
(() => div.firstChild as HTMLElement)((div.innerHTML = html)))(
|
|
22
|
+
document.createElement('div')
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* # Create Element
|
|
28
|
+
* Return the main Nanosplash element.
|
|
29
|
+
*/
|
|
30
|
+
export function createElement(): HTMLDivElement {
|
|
31
|
+
return render(
|
|
32
|
+
'<div class=ns><div class=nsc><div class=nst></div><div class=nss><svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none></circle></svg></div></div></div>'
|
|
33
|
+
) as HTMLDivElement
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* # Inject as First Child
|
|
38
|
+
* Insert element into the target element as its first child.
|
|
39
|
+
* @param element Element to inject.
|
|
40
|
+
* @param targetElement Element in which the first element is to be injected.
|
|
41
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/children
|
|
42
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
|
|
43
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
|
|
44
|
+
* @see https://developer.mozilla.org/docs/Web/API/NodeList/item
|
|
45
|
+
*/
|
|
46
|
+
export function injectAsFirstChild(
|
|
47
|
+
element: Element,
|
|
48
|
+
targetElement: Element
|
|
49
|
+
): void {
|
|
50
|
+
const targetHasChild = targetElement.children.length > 0
|
|
51
|
+
if (targetHasChild) {
|
|
52
|
+
targetElement.insertBefore(element, targetElement.children.item(0))
|
|
53
|
+
} else {
|
|
54
|
+
targetElement.append(element)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* # Add NS Host Class
|
|
60
|
+
* Add the `nsHostClassName` class to the `element`.
|
|
61
|
+
* @param element Element to which the `nsHostClassName` class will be added.
|
|
62
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
|
|
63
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/add
|
|
64
|
+
*/
|
|
65
|
+
export function addNSHostClass(element: Element | null): void {
|
|
66
|
+
element?.classList.add(Splash.NSHostClass)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* # Remove NS Host Class
|
|
71
|
+
* Remove the `nsHostClassName` class from the `element`.
|
|
72
|
+
* @param element Element from which the `nsHostClassName` class will be removed.
|
|
73
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
|
|
74
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/remove
|
|
75
|
+
*/
|
|
76
|
+
export function removeNSHostClass(element: Element | null): void {
|
|
77
|
+
element?.classList.remove(Splash.NSHostClass)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* # Show Element
|
|
82
|
+
* Set the `display` property of the `element` to `flex`.
|
|
83
|
+
* @param element Element to show.
|
|
84
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/display
|
|
85
|
+
*/
|
|
86
|
+
export function showElement(element: HTMLElement): void {
|
|
87
|
+
element.style.display = 'flex'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* # Hide Element
|
|
92
|
+
* Set the `display` property of the `element` to `none`.
|
|
93
|
+
* @param element Element to hide.
|
|
94
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/display
|
|
95
|
+
*/
|
|
96
|
+
export function hideElement(element: HTMLElement): void {
|
|
97
|
+
element.style.display = 'none'
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* # Element From
|
|
102
|
+
* Convert the element reference to an element.
|
|
103
|
+
* @param ref Reference to an element.
|
|
104
|
+
* @returns { Element | null } Element or null.
|
|
105
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
|
106
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element
|
|
107
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node
|
|
108
|
+
*/
|
|
109
|
+
export function elementFrom(ref: Reference): Element | null {
|
|
110
|
+
switch (typeof ref) {
|
|
111
|
+
case 'object':
|
|
112
|
+
const isBody = ref === document.body
|
|
113
|
+
const isElement = ref instanceof Element
|
|
114
|
+
if (isBody || isElement) {
|
|
115
|
+
return ref
|
|
116
|
+
}
|
|
117
|
+
throw new Error(
|
|
118
|
+
'Reference is an object but not an Element instance.'
|
|
119
|
+
)
|
|
120
|
+
case 'string':
|
|
121
|
+
return document.querySelector(ref)
|
|
122
|
+
default:
|
|
123
|
+
throw new Error('Reference is not an object or a string.')
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* # Move
|
|
129
|
+
* Move an Element to another Element.
|
|
130
|
+
* @param element Element to move
|
|
131
|
+
* @param targetElement Target element
|
|
132
|
+
*/
|
|
133
|
+
export function move(element: Element, targetElement: Element): void {
|
|
134
|
+
// Clean the current NS host element.
|
|
135
|
+
removeNSHostClass(element.parentElement)
|
|
136
|
+
// Assign new NS host element.
|
|
137
|
+
addNSHostClass(targetElement)
|
|
138
|
+
injectAsFirstChild(element, targetElement)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* # Get Recycled NS
|
|
143
|
+
* Return the Nanosplash instance inside the target element if it exists.
|
|
144
|
+
* @param targetElement Element wherein the Nanosplash instance is to reside.
|
|
145
|
+
* @returns { Nanosplash | null } Nanosplash instance or null.
|
|
146
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/firstElementChild
|
|
147
|
+
*/
|
|
148
|
+
export function getRecycledSplash(targetElement: Element): Splash | null {
|
|
149
|
+
const children = Array.from(targetElement.children || [])
|
|
150
|
+
const nss = Service.getInstance()
|
|
151
|
+
let splash: Splash | null = null
|
|
152
|
+
const n = children.length
|
|
153
|
+
for (let i = 0; i < n; i++) {
|
|
154
|
+
const child = children[i]
|
|
155
|
+
if (child.classList.contains(Splash.NSClass)) {
|
|
156
|
+
splash = nss.nsQueue.get(child.id) ?? null
|
|
157
|
+
break
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return splash
|
|
161
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { version } from '../../../package.json'
|
|
2
|
+
|
|
3
|
+
import { Reference, GUIDString } from '../types/Types'
|
|
4
|
+
import {
|
|
5
|
+
getRecycledSplash,
|
|
6
|
+
move,
|
|
7
|
+
elementFrom,
|
|
8
|
+
render,
|
|
9
|
+
removeNSHostClass,
|
|
10
|
+
} from './DomUtilities'
|
|
11
|
+
import { ServiceInterface } from './ServiceInterface'
|
|
12
|
+
import { Splash } from './Splash'
|
|
13
|
+
import css from '../../style/ns.sass?inline'
|
|
14
|
+
import { SplashQueue } from './SplashQueue'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* # Service
|
|
18
|
+
* A service class that handles Nanosplash instances.
|
|
19
|
+
* It's a singleton class and its instance resides in the Window object and
|
|
20
|
+
* serves the public API of the Nanosplash library.
|
|
21
|
+
* @see Splash
|
|
22
|
+
* @author Isak K. Hauge <isakhauge@icloud.com>
|
|
23
|
+
*/
|
|
24
|
+
export class Service implements ServiceInterface {
|
|
25
|
+
/**
|
|
26
|
+
* # Window Accessor Key
|
|
27
|
+
* Key to access NanosplashService instance in the Window object.
|
|
28
|
+
*/
|
|
29
|
+
public static readonly WindowAccessorKey = 'ns'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* # Instance
|
|
33
|
+
* Singleton instance of NanosplashService.
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
private static instance: Service
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* # Version
|
|
40
|
+
*/
|
|
41
|
+
public readonly version: string
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @inheritdoc
|
|
45
|
+
*/
|
|
46
|
+
public readonly nsQueue: SplashQueue
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* # Constructor
|
|
50
|
+
* Private constructor to prevent multiple instances.
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
private constructor() {
|
|
54
|
+
this.version = version
|
|
55
|
+
this.nsQueue = new SplashQueue()
|
|
56
|
+
Service.addStyle()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**e
|
|
60
|
+
* # Add Style
|
|
61
|
+
* Add Nanosplash CSS to the DOM.
|
|
62
|
+
*/
|
|
63
|
+
private static addStyle(): void {
|
|
64
|
+
const style = render(`<style>${css}</style>`) as HTMLStyleElement
|
|
65
|
+
document.body.append(style)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* # Get Instance
|
|
70
|
+
* Singleton instance accessor
|
|
71
|
+
* @returns {Service} NanosplashService instance
|
|
72
|
+
*/
|
|
73
|
+
public static getInstance(): Service {
|
|
74
|
+
if (!Service.instance) {
|
|
75
|
+
Service.instance = new Service()
|
|
76
|
+
}
|
|
77
|
+
return Service.instance
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* # Assign To Window
|
|
82
|
+
* Assign a NanosplashService instance to the Window object.
|
|
83
|
+
* The NanosplashService instance can be accessed in the window object
|
|
84
|
+
* using the key window accessor key.
|
|
85
|
+
* @see WindowAccessorKey
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
private static assignToWindow(): void {
|
|
89
|
+
Object.defineProperty(window, Service.WindowAccessorKey, {
|
|
90
|
+
value: Service.getInstance(),
|
|
91
|
+
writable: false,
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* # Start
|
|
97
|
+
* Initialize and attach a Nanosplash Service instance to the Window object.
|
|
98
|
+
*/
|
|
99
|
+
public static start(): void {
|
|
100
|
+
const nss = window[Service.WindowAccessorKey]
|
|
101
|
+
if (!nss) {
|
|
102
|
+
Service.assignToWindow()
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* # Create Nanosplash
|
|
108
|
+
* Return new Nanosplash instance and push it to the stack.
|
|
109
|
+
* @param text Text to display.
|
|
110
|
+
* @returns {Splash} Nanosplash instance.
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
private createNS(text?: string): Splash {
|
|
114
|
+
const ns = new Splash().setText(text || '')
|
|
115
|
+
this.nsQueue.enqueue(ns)
|
|
116
|
+
return ns
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* # Clean And Remove From DOM
|
|
121
|
+
* Remove Nanosplash from DOM and clean its parent.
|
|
122
|
+
* @param ns Nanosplash instance.
|
|
123
|
+
* @returns True if Nanosplash was removed from DOM.
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
private cleanAndRemoveFromDOM(ns: Splash | null): boolean {
|
|
127
|
+
if (ns) {
|
|
128
|
+
removeNSHostClass(ns.getElement()?.parentElement ?? null)
|
|
129
|
+
return ns.delete()
|
|
130
|
+
}
|
|
131
|
+
return false
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* # Delete NS
|
|
136
|
+
* Remove Nanosplash instance from both the stack and the
|
|
137
|
+
* @param guid Nanosplash ID.
|
|
138
|
+
* @returns True if Nanosplash was removed from DOM.
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
private deleteNS(guid: GUIDString): boolean {
|
|
142
|
+
return this.cleanAndRemoveFromDOM(this.nsQueue.delete(guid) ?? null)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @inheritdoc
|
|
147
|
+
*/
|
|
148
|
+
public show(text?: string): GUIDString | null {
|
|
149
|
+
return this.showInside(document.body, text)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @inheritdoc
|
|
154
|
+
*/
|
|
155
|
+
public showInside(ref: Reference, text?: string): GUIDString | null {
|
|
156
|
+
try {
|
|
157
|
+
const destinationNode = elementFrom(ref) as Element
|
|
158
|
+
const ns = getRecycledSplash(destinationNode) ?? this.createNS()
|
|
159
|
+
move(ns.getElement() as Element, destinationNode)
|
|
160
|
+
const parsedText = text ? String(text) : ''
|
|
161
|
+
return ns.setText(parsedText).getId()
|
|
162
|
+
} catch (e) {
|
|
163
|
+
console.error(e)
|
|
164
|
+
return null
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @inheritdoc
|
|
170
|
+
*/
|
|
171
|
+
public hide(): GUIDString | null {
|
|
172
|
+
const ns = this.nsQueue.dequeue()
|
|
173
|
+
if (!ns) return null
|
|
174
|
+
this.cleanAndRemoveFromDOM(ns)
|
|
175
|
+
return ns.getId()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @inheritdoc
|
|
180
|
+
*/
|
|
181
|
+
public hideAll(): void {
|
|
182
|
+
let ns = this.nsQueue.dequeue()
|
|
183
|
+
while (ns) {
|
|
184
|
+
this.cleanAndRemoveFromDOM(ns)
|
|
185
|
+
ns = this.nsQueue.dequeue()
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @inheritdoc
|
|
191
|
+
*/
|
|
192
|
+
public hideId(id: GUIDString): GUIDString | null {
|
|
193
|
+
return this.deleteNS(id) ? id : null
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @inheritdoc
|
|
198
|
+
*/
|
|
199
|
+
public hideInside(ref: Reference): GUIDString | null {
|
|
200
|
+
try {
|
|
201
|
+
const ns = getRecycledSplash(elementFrom(ref) as Element)
|
|
202
|
+
const guid = ns?.getId() ?? ''
|
|
203
|
+
return this.deleteNS(guid ?? '') ? guid : null
|
|
204
|
+
} catch (e) {
|
|
205
|
+
console.error(e)
|
|
206
|
+
return null
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export default { Service }
|
|
@@ -1,27 +1,35 @@
|
|
|
1
|
-
import { GUIDString } from '
|
|
2
|
-
import {
|
|
1
|
+
import { GUIDString, Reference } from '../types/Types'
|
|
2
|
+
import { SplashQueue } from './SplashQueue'
|
|
3
|
+
|
|
4
|
+
export interface ServiceInterface {
|
|
5
|
+
/**
|
|
6
|
+
* # Nanosplash Stack
|
|
7
|
+
* For each Nanosplash instance created, it's pushed to the stack.
|
|
8
|
+
* When a Nanosplash instance is removed, it's removed from the stack.
|
|
9
|
+
* @see Splash
|
|
10
|
+
*/
|
|
11
|
+
readonly nsQueue: SplashQueue
|
|
3
12
|
|
|
4
|
-
export interface NanosplashAPI {
|
|
5
13
|
/**
|
|
6
14
|
* # Show
|
|
7
15
|
* Present a Nanosplash in the browser window displaying the given text.
|
|
8
16
|
* @param text Text to display.
|
|
9
|
-
* @returns {GUIDString} Nanosplash ID.
|
|
17
|
+
* @returns {GUIDString | null} Nanosplash ID.
|
|
10
18
|
*/
|
|
11
|
-
show(text?: string): GUIDString
|
|
19
|
+
show(text?: string): GUIDString | null
|
|
12
20
|
|
|
13
21
|
/**
|
|
14
22
|
* # Show Inside
|
|
15
23
|
* Present a Nanosplash over the given element displaying the given text.
|
|
16
|
-
* @param
|
|
24
|
+
* @param ref Reference an element.
|
|
17
25
|
* @param text Text to display.
|
|
18
26
|
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
19
27
|
*/
|
|
20
|
-
showInside(
|
|
28
|
+
showInside(ref: Reference, text?: string): GUIDString | null
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
31
|
* # Hide
|
|
24
|
-
* Hide the
|
|
32
|
+
* Hide the oldest Nanosplash.
|
|
25
33
|
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
26
34
|
*/
|
|
27
35
|
hide(): GUIDString | null
|
|
@@ -43,8 +51,8 @@ export interface NanosplashAPI {
|
|
|
43
51
|
/**
|
|
44
52
|
* # Hide Inside
|
|
45
53
|
* Hide Nanosplash inside the given element if it exists.
|
|
46
|
-
* @param
|
|
54
|
+
* @param ref Reference an element.
|
|
47
55
|
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
48
56
|
*/
|
|
49
|
-
hideInside(
|
|
57
|
+
hideInside(ref: Reference): GUIDString | null
|
|
50
58
|
}
|