nanosplash 2.5.3 → 3.0.1
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 +48 -0
- package/.prettierrc +10 -9
- package/LICENSE +1 -1
- package/README.md +139 -72
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +555 -0
- package/coverage/core/Dom.ts.html +565 -0
- package/coverage/core/Service.ts.html +790 -0
- package/coverage/core/Splash.ts.html +457 -0
- package/coverage/core/index.html +146 -0
- package/coverage/coverage-final.json +9043 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +131 -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/coverage/types/Types.ts.html +121 -0
- package/coverage/types/index.html +116 -0
- package/dist/latest/cjs/ns.cjs +1 -0
- package/dist/latest/cjs/style.css +1 -0
- package/dist/latest/es/ns.js +306 -0
- package/dist/latest/es/style.css +1 -0
- package/dist/latest/iife/ns.iife.js +4 -0
- package/dist/versioned/3.0.1/cjs/ns.cjs +1 -0
- package/dist/versioned/3.0.1/cjs/style.css +1 -0
- package/dist/versioned/3.0.1/es/ns.js +306 -0
- package/dist/versioned/3.0.1/es/style.css +1 -0
- package/dist/versioned/3.0.1/iife/ns.iife.js +2 -0
- package/docs/index.6d66a821.js +1 -0
- package/docs/index.74dbd99e.css +1 -0
- package/docs/index.f34144dc.js +1 -0
- package/docs/index.html +90 -114
- package/index.html +87 -115
- package/package.json +50 -36
- package/src/sass/ns.sass +95 -0
- package/src/ts/core/Dom.ts +160 -0
- package/src/ts/core/Service.ts +235 -0
- package/src/ts/core/ServiceInterface.ts +60 -0
- package/src/ts/core/Splash.ts +124 -0
- package/src/ts/core/SplashInterface.ts +54 -0
- package/src/ts/main.ts +9 -0
- package/src/ts/types/Types.ts +12 -0
- package/src/ts/types/global.d.ts +14 -0
- package/tests/Dom.spec.ts +127 -0
- package/tests/Guid.spec.ts +21 -0
- package/tests/Service.spec.ts +119 -0
- package/tests/Splash.spec.ts +64 -0
- package/tsconfig.json +20 -16
- package/vite.config.ts +27 -13
- package/vite.demo.config.ts +16 -0
- package/.github/workflows/production.yml +0 -60
- package/.github/workflows/release.yml +0 -61
- package/_config.yml +0 -1
- package/dist/iife/manifest.json +0 -7
- package/dist/iife/nanosplash.iife.js +0 -1
- package/dist/module/manifest.json +0 -7
- package/dist/module/nanosplash.cjs.js +0 -1
- package/dist/module/nanosplash.es.js +0 -371
- package/dist/module/style.css +0 -1
- package/docs/nanosplash.iife.js +0 -6
- package/docs/style.css +0 -1
- package/docs/typedoc/.nojekyll +0 -1
- package/docs/typedoc/assets/highlight.css +0 -22
- package/docs/typedoc/assets/icons.css +0 -1043
- package/docs/typedoc/assets/icons.png +0 -0
- package/docs/typedoc/assets/icons@2x.png +0 -0
- package/docs/typedoc/assets/main.js +0 -52
- package/docs/typedoc/assets/search.js +0 -1
- package/docs/typedoc/assets/style.css +0 -1414
- package/docs/typedoc/assets/widgets.png +0 -0
- package/docs/typedoc/assets/widgets@2x.png +0 -0
- package/docs/typedoc/classes/Core_Nanosplash.default.html +0 -133
- package/docs/typedoc/index.html +0 -1
- package/docs/typedoc/modules/Core_Nanosplash.html +0 -1
- package/docs/typedoc/modules/types.html +0 -1
- package/favicon.svg +0 -15
- package/postcss.config.js +0 -8
- package/src/Core/Nanosplash.ts +0 -257
- package/src/Core/SplashInstance.ts +0 -298
- package/src/Exceptions/DestinationException.ts +0 -13
- package/src/Exceptions/Exception.ts +0 -9
- package/src/Exceptions/IllegalArgumentException.ts +0 -11
- package/src/Factory/NanosplashFactory.ts +0 -93
- package/src/Interfaces/ContextualAPIInterface.ts +0 -8
- package/src/Interfaces/IdentityInterface.ts +0 -3
- package/src/Interfaces/InsideInterface.ts +0 -5
- package/src/Interfaces/NanosplashInterface.ts +0 -8
- package/src/Interfaces/ProgressInterface.ts +0 -5
- package/src/Interfaces/ShowInterface.ts +0 -5
- package/src/Interfaces/WhileInterface.ts +0 -5
- package/src/Repositories/NanosplashRepository.ts +0 -82
- package/src/Tests/dom.spec.ts +0 -72
- package/src/Utilities/dom.ts +0 -49
- package/src/main.ts +0 -5
- package/src/style.sass +0 -88
- package/src/types.d.ts +0 -59
- package/update-all.sh +0 -3
- package/vite.iife.config.js +0 -72
- package/vite.mod.config.js +0 -71
- package/vite.site.config.js +0 -22
package/src/sass/ns.sass
ADDED
|
@@ -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,160 @@
|
|
|
1
|
+
// @ts-strict
|
|
2
|
+
|
|
3
|
+
import { Reference, GUIDString, ClassListAction } from '../types/Types'
|
|
4
|
+
import { Service } from './Service'
|
|
5
|
+
import { Splash } from './Splash'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* # DOM Utilities
|
|
9
|
+
* A collection of functions that are used by the Nanosplash classes.
|
|
10
|
+
* @see Splash
|
|
11
|
+
* @see Service
|
|
12
|
+
* @author Isak K. Hauge <isakhauge@icloud.com>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* # Create Element
|
|
17
|
+
* Return the main Nanosplash element.
|
|
18
|
+
*/
|
|
19
|
+
export function createElement(): HTMLDivElement {
|
|
20
|
+
return new DOMParser().parseFromString(
|
|
21
|
+
'<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>',
|
|
22
|
+
'text/html'
|
|
23
|
+
).body.firstChild as HTMLDivElement
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* # Inject as First Child
|
|
28
|
+
* Insert element into the target element as its first child.
|
|
29
|
+
* @param element Element to inject.
|
|
30
|
+
* @param targetElement Element in which the first element is to be injected.
|
|
31
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/children
|
|
32
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
|
|
33
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
|
|
34
|
+
* @see https://developer.mozilla.org/docs/Web/API/NodeList/item
|
|
35
|
+
*/
|
|
36
|
+
export function injectAsFirstChild(
|
|
37
|
+
element: Element,
|
|
38
|
+
targetElement: Element
|
|
39
|
+
): void {
|
|
40
|
+
const targetHasChild = targetElement.children.length > 0
|
|
41
|
+
if (targetHasChild) {
|
|
42
|
+
targetElement.insertBefore(element, targetElement.children.item(0))
|
|
43
|
+
} else {
|
|
44
|
+
targetElement.append(element)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* # Set NS Host Class
|
|
50
|
+
* Add or remove the `nsHostClassName` class to the `element`.
|
|
51
|
+
* @param element Element to which the `nsHostClassName` class will be added or removed.
|
|
52
|
+
* @param action Action to perform ('add' or 'remove').
|
|
53
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
|
|
54
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/add
|
|
55
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/remove
|
|
56
|
+
*/
|
|
57
|
+
export function setNSHostClass(
|
|
58
|
+
element: Element | null,
|
|
59
|
+
action: ClassListAction
|
|
60
|
+
): void {
|
|
61
|
+
element?.classList[action](Splash.NSHostClass)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* # Prepare Parent Of
|
|
66
|
+
* Add the `nsHostClassName` class to the parent of the `ns` element.
|
|
67
|
+
* @param ns Nanosplash instance.
|
|
68
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/parentElement
|
|
69
|
+
*/
|
|
70
|
+
export function prepareParentOf(ns: Splash): void {
|
|
71
|
+
setNSHostClass(ns.getNSElement().parentElement, ClassListAction.Add)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* # Clean NS Parent Of
|
|
76
|
+
* Remove the `nsHostClassName` class from the parent of the `ns` element.
|
|
77
|
+
* @param ns Nanosplash instance.
|
|
78
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/parentElement
|
|
79
|
+
*/
|
|
80
|
+
export function cleanNSParentOf(ns: Splash): void {
|
|
81
|
+
setNSHostClass(ns.getNSElement().parentElement, ClassListAction.Remove)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* # Show Element
|
|
86
|
+
* Set the `display` property of the `element` to `flex`.
|
|
87
|
+
* @param element Element to show.
|
|
88
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/display
|
|
89
|
+
*/
|
|
90
|
+
export function showElement(element: HTMLElement): void {
|
|
91
|
+
element.style.display = 'flex'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* # Hide Element
|
|
96
|
+
* Set the `display` property of the `element` to `none`.
|
|
97
|
+
* @param element Element to hide.
|
|
98
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/display
|
|
99
|
+
*/
|
|
100
|
+
export function hideElement(element: HTMLElement): void {
|
|
101
|
+
element.style.display = 'none'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* # Element From
|
|
106
|
+
* Convert the element reference to an element.
|
|
107
|
+
* @param ref Reference to an element.
|
|
108
|
+
* @returns { Element | null } Element or null.
|
|
109
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
|
110
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element
|
|
111
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node
|
|
112
|
+
*/
|
|
113
|
+
export function elementFrom(ref: Reference): Element | null {
|
|
114
|
+
return ref instanceof Element ? ref : document.querySelector(ref || '')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* # Element Is NS
|
|
119
|
+
* Check if the element is a Nanosplash element.
|
|
120
|
+
* This is determined by the presence of the `ns` class on the element.
|
|
121
|
+
* @param element Element to check.
|
|
122
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/contains
|
|
123
|
+
*/
|
|
124
|
+
export function elementIsNS(element: Element): boolean {
|
|
125
|
+
return element?.classList?.contains(Splash.NSClass) ?? false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* # Move
|
|
130
|
+
* Move an Element to another Element.
|
|
131
|
+
* @param element Element to move
|
|
132
|
+
* @param targetElement Target element
|
|
133
|
+
*/
|
|
134
|
+
export function move(element: Element, targetElement: Element): void {
|
|
135
|
+
// Clean the current NS host element.
|
|
136
|
+
setNSHostClass(element.parentElement, ClassListAction.Remove)
|
|
137
|
+
// Assign new NS host element.
|
|
138
|
+
setNSHostClass(targetElement, ClassListAction.Add)
|
|
139
|
+
injectAsFirstChild(element, targetElement)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* # Get Recycled NS
|
|
144
|
+
* Return the Nanosplash instance inside the target element if it exists.
|
|
145
|
+
* @param targetElement Element wherein the Nanosplash instance is to reside.
|
|
146
|
+
* @returns { Nanosplash | null } Nanosplash instance or null.
|
|
147
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/firstElementChild
|
|
148
|
+
*/
|
|
149
|
+
export function getRecycledNS(targetElement: Element): Splash | null {
|
|
150
|
+
const firstChild = targetElement.firstElementChild
|
|
151
|
+
const hasChild = firstChild !== null
|
|
152
|
+
const targetAlreadyHasNS = hasChild && elementIsNS(firstChild)
|
|
153
|
+
if (targetAlreadyHasNS) {
|
|
154
|
+
const id: GUIDString = firstChild.id
|
|
155
|
+
const nss = Service.getInstance()
|
|
156
|
+
return nss.nsStack.find((ns: Splash) => ns.getId() === id) ?? null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return null
|
|
160
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// @ts-strict
|
|
2
|
+
|
|
3
|
+
import { version } from '../../../package.json'
|
|
4
|
+
import '../../sass/ns.sass'
|
|
5
|
+
|
|
6
|
+
import { NSFinder, GUIDString, Reference } from '../types/Types'
|
|
7
|
+
import { cleanNSParentOf, getRecycledNS, move, elementFrom } from './Dom'
|
|
8
|
+
import { ServiceInterface } from './ServiceInterface'
|
|
9
|
+
import { Splash } from './Splash'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* # Service
|
|
13
|
+
* A service class that handles Nanosplash instances.
|
|
14
|
+
* It's a singleton class and its instance resides in the Window object and
|
|
15
|
+
* serves the public API of the Nanosplash library.
|
|
16
|
+
* @see Splash
|
|
17
|
+
* @author Isak K. Hauge <isakhauge@icloud.com>
|
|
18
|
+
*/
|
|
19
|
+
export class Service implements ServiceInterface {
|
|
20
|
+
/**
|
|
21
|
+
* # Window Accessor Key
|
|
22
|
+
* Key to access NanosplashService instance in the Window object.
|
|
23
|
+
*/
|
|
24
|
+
public static readonly WindowAccessorKey = 'ns'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* # Instance
|
|
28
|
+
* Singleton instance of NanosplashService.
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
private static instance: Service
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* # Version
|
|
35
|
+
*/
|
|
36
|
+
public readonly version: string
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @inheritdoc
|
|
40
|
+
*/
|
|
41
|
+
public readonly nsStack: Splash[]
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* # Constructor
|
|
45
|
+
* Private constructor to prevent multiple instances.
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
private constructor() {
|
|
49
|
+
this.version = version
|
|
50
|
+
this.nsStack = []
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* # Find Index
|
|
55
|
+
* Find Nanosplash stack index by callback.
|
|
56
|
+
* @param callback Callback function that returns a boolean.
|
|
57
|
+
* @returns {number} Index of Nanosplash instance in the stack or -1.
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
private findIndex(callback: NSFinder): number | -1 {
|
|
61
|
+
return this.nsStack.findIndex(callback)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* # Find
|
|
66
|
+
* Find Nanosplash in the stack by callback.
|
|
67
|
+
* @param callback Callback function that returns a boolean.
|
|
68
|
+
* @returns {Splash | undefined} Nanosplash instance or undefined
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
private find(callback: NSFinder): Splash | undefined {
|
|
72
|
+
return this.nsStack.find(callback)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* # Get Instance
|
|
77
|
+
* Singleton instance accessor
|
|
78
|
+
* @returns {Service} NanosplashService instance
|
|
79
|
+
*/
|
|
80
|
+
public static getInstance(): Service {
|
|
81
|
+
if (!Service.instance) {
|
|
82
|
+
Service.instance = new Service()
|
|
83
|
+
}
|
|
84
|
+
return Service.instance
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* # Assign To Window
|
|
89
|
+
* Assign a NanosplashService instance to the Window object.
|
|
90
|
+
* The NanosplashService instance can be accessed in the window object
|
|
91
|
+
* using the key window accessor key.
|
|
92
|
+
* @see WindowAccessorKey
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
private static assignToWindow(): void {
|
|
96
|
+
Object.defineProperty(window, Service.WindowAccessorKey, {
|
|
97
|
+
value: Service.getInstance(),
|
|
98
|
+
writable: false,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* # Start
|
|
104
|
+
* Initialize and attach a Nanosplash Service instance to the Window object.
|
|
105
|
+
*/
|
|
106
|
+
public static start(): void {
|
|
107
|
+
Service.assignToWindow()
|
|
108
|
+
window.addEventListener('load', () => {
|
|
109
|
+
const nss = window[Service.WindowAccessorKey]
|
|
110
|
+
const nssAssigned = nss instanceof Service
|
|
111
|
+
if (!nssAssigned) {
|
|
112
|
+
Service.assignToWindow()
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* # Create Nanosplash
|
|
119
|
+
* Return new Nanosplash instance and push it to the stack.
|
|
120
|
+
* @param text Text to display.
|
|
121
|
+
* @returns {Splash} Nanosplash instance.
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
private createNS(text?: string): Splash {
|
|
125
|
+
const ns = new Splash()
|
|
126
|
+
ns.setText(text || '')
|
|
127
|
+
this.nsStack.push(ns)
|
|
128
|
+
return ns
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* # Clean And Remove
|
|
133
|
+
* Remove Nanosplash from DOM and clean its parent.
|
|
134
|
+
* @param ns Nanosplash instance.
|
|
135
|
+
* @returns {GUIDString} Nanosplash ID.
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
private cleanAndRemove(ns: Splash): GUIDString {
|
|
139
|
+
cleanNSParentOf(ns)
|
|
140
|
+
return ns.remove().getId()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* # Stack Delete
|
|
145
|
+
* Remove Nanosplash instance from the stack.
|
|
146
|
+
* @param ns Nanosplash instance.
|
|
147
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
private stackDelete(ns: Splash): GUIDString | null {
|
|
151
|
+
let index = this.findIndex((o: Splash) => o.getId() === ns.getId())
|
|
152
|
+
if (index < 0) return null
|
|
153
|
+
this.nsStack.splice(index, 1)
|
|
154
|
+
return ns.getId()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* # Delete NS
|
|
159
|
+
* Remove Nanosplash instance from both the stack and the
|
|
160
|
+
* @param callback Callback function.
|
|
161
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
162
|
+
* @private
|
|
163
|
+
*/
|
|
164
|
+
private deleteNS(callback: NSFinder): GUIDString | null {
|
|
165
|
+
const ns = this.find(callback)
|
|
166
|
+
if (ns) {
|
|
167
|
+
this.cleanAndRemove(ns)
|
|
168
|
+
return this.stackDelete(ns)
|
|
169
|
+
}
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @inheritdoc
|
|
175
|
+
*/
|
|
176
|
+
public show(text?: string): GUIDString {
|
|
177
|
+
let ns = getRecycledNS(document.body)
|
|
178
|
+
if (!ns) {
|
|
179
|
+
ns = this.createNS()
|
|
180
|
+
move(ns.getNSElement(), document.body)
|
|
181
|
+
}
|
|
182
|
+
return ns.setText(text || '').getId()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* @inheritdoc
|
|
187
|
+
*/
|
|
188
|
+
public showInside(ref: Reference, text?: string): GUIDString | null {
|
|
189
|
+
const destinationNode: Element | null = elementFrom(ref)
|
|
190
|
+
if (destinationNode) {
|
|
191
|
+
let ns = getRecycledNS(destinationNode)
|
|
192
|
+
if (!ns) {
|
|
193
|
+
ns = this.createNS()
|
|
194
|
+
}
|
|
195
|
+
move(ns.getNSElement(), <Element>destinationNode)
|
|
196
|
+
return ns.setText(text || '').getId()
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return null
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @inheritdoc
|
|
204
|
+
*/
|
|
205
|
+
public hide(): GUIDString | null {
|
|
206
|
+
const ns = this.nsStack.pop()
|
|
207
|
+
return ns ? this.cleanAndRemove(ns) : null
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @inheritdoc
|
|
212
|
+
*/
|
|
213
|
+
public hideAll(): void {
|
|
214
|
+
this.nsStack.forEach(this.cleanAndRemove)
|
|
215
|
+
this.nsStack.splice(0, this.nsStack.length)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @inheritdoc
|
|
220
|
+
*/
|
|
221
|
+
public hideId(id: GUIDString): GUIDString | null {
|
|
222
|
+
return this.deleteNS((ns: Splash) => ns.getId() === id)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @inheritdoc
|
|
227
|
+
*/
|
|
228
|
+
public hideInside(ref: Reference): GUIDString | null {
|
|
229
|
+
const node = elementFrom(ref)
|
|
230
|
+
const cb = (ns: Splash) => ns.getNSElement().parentElement === node
|
|
231
|
+
return node ? this.deleteNS(cb) : null
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export default { Service }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// @ts-strict
|
|
2
|
+
|
|
3
|
+
import { GUIDString, Reference } from '../types/Types'
|
|
4
|
+
import { Splash } from './Splash'
|
|
5
|
+
|
|
6
|
+
export interface ServiceInterface {
|
|
7
|
+
/**
|
|
8
|
+
* # Nanosplash Stack
|
|
9
|
+
* For each Nanosplash instance created, it's pushed to the stack.
|
|
10
|
+
* When a Nanosplash instance is removed, it's removed from the stack.
|
|
11
|
+
* @see Splash
|
|
12
|
+
*/
|
|
13
|
+
readonly nsStack: Splash[]
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* # Show
|
|
17
|
+
* Present a Nanosplash in the browser window displaying the given text.
|
|
18
|
+
* @param text Text to display.
|
|
19
|
+
* @returns {GUIDString} Nanosplash ID.
|
|
20
|
+
*/
|
|
21
|
+
show(text?: string): GUIDString
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* # Show Inside
|
|
25
|
+
* Present a Nanosplash over the given element displaying the given text.
|
|
26
|
+
* @param ref Reference an element.
|
|
27
|
+
* @param text Text to display.
|
|
28
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
29
|
+
*/
|
|
30
|
+
showInside(ref: Reference, text?: string): GUIDString | null
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* # Hide
|
|
34
|
+
* Hide the last created Nanosplash.
|
|
35
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
36
|
+
*/
|
|
37
|
+
hide(): GUIDString | null
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* # Hide All
|
|
41
|
+
* Hide all Nanosplashes.
|
|
42
|
+
*/
|
|
43
|
+
hideAll(): void
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* # Hide ID
|
|
47
|
+
* Hide Nanosplash by its ID.
|
|
48
|
+
* @param id Nanosplash ID.
|
|
49
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
50
|
+
*/
|
|
51
|
+
hideId(id: GUIDString): GUIDString | null
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* # Hide Inside
|
|
55
|
+
* Hide Nanosplash inside the given element if it exists.
|
|
56
|
+
* @param ref Reference an element.
|
|
57
|
+
* @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
|
|
58
|
+
*/
|
|
59
|
+
hideInside(ref: Reference): GUIDString | null
|
|
60
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// @ts-strict
|
|
2
|
+
|
|
3
|
+
import { GUIDString } from '../types/Types'
|
|
4
|
+
import { createElement, showElement, hideElement } from './Dom'
|
|
5
|
+
import { SplashInterface } from './SplashInterface'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* # Splash
|
|
9
|
+
* Small splash screen that can be used to indicate that a process
|
|
10
|
+
* is running.
|
|
11
|
+
* @author Isak K. Hauge <isakhauge@icloud.com>
|
|
12
|
+
*/
|
|
13
|
+
export class Splash implements SplashInterface {
|
|
14
|
+
/**
|
|
15
|
+
* # CSS Class Name
|
|
16
|
+
* The main CSS class name of the root element of a Nanosplash component.
|
|
17
|
+
*/
|
|
18
|
+
public static readonly NSClass = 'ns'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* # Host CSS Class Name
|
|
22
|
+
* The CSS class name of the host element of a Nanosplash component.
|
|
23
|
+
* The host element is the element that the Nanosplash is attached to.
|
|
24
|
+
*/
|
|
25
|
+
public static readonly NSHostClass = 'nsh'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* # ID
|
|
29
|
+
* Each Nanosplash instance is given a unique GUID.
|
|
30
|
+
*/
|
|
31
|
+
private readonly id: GUIDString
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* # Element
|
|
35
|
+
* The root element of the Nanosplash component.
|
|
36
|
+
*/
|
|
37
|
+
private element?: HTMLDivElement
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* # Generate GUID
|
|
41
|
+
* @returns {GUIDString} A GUID string.
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
private static generateGUID(): GUIDString {
|
|
45
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
46
|
+
const r = (Math.random() * 16) | 0
|
|
47
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8
|
|
48
|
+
return v.toString(16)
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* # Constructor
|
|
54
|
+
* Creates a new Nanosplash instance.
|
|
55
|
+
*/
|
|
56
|
+
public constructor() {
|
|
57
|
+
this.element = createElement()
|
|
58
|
+
this.element.id = this.id = Splash.generateGUID()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @inheritdoc
|
|
63
|
+
*/
|
|
64
|
+
public getNSContentElement(): HTMLDivElement {
|
|
65
|
+
return <HTMLDivElement>this.getNSElement().firstElementChild
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @inheritdoc
|
|
70
|
+
*/
|
|
71
|
+
public getNSTextElement(): HTMLDivElement {
|
|
72
|
+
return <HTMLDivElement>this.getNSContentElement().firstElementChild
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @inheritdoc
|
|
77
|
+
*/
|
|
78
|
+
public getId(): GUIDString {
|
|
79
|
+
return this.id
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @inheritdoc
|
|
84
|
+
*/
|
|
85
|
+
public getNSElement(): HTMLDivElement {
|
|
86
|
+
return <HTMLDivElement>this.element
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @inheritdoc
|
|
91
|
+
*/
|
|
92
|
+
public setText(text: string): Splash {
|
|
93
|
+
this.getNSTextElement().innerText = text
|
|
94
|
+
text.length > 0 ? this.showText() : this.hideText()
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @inheritdoc
|
|
100
|
+
*/
|
|
101
|
+
public showText(): Splash {
|
|
102
|
+
showElement(this.getNSTextElement())
|
|
103
|
+
return this
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @inheritdoc
|
|
108
|
+
*/
|
|
109
|
+
public hideText(): Splash {
|
|
110
|
+
hideElement(this.getNSTextElement())
|
|
111
|
+
return this
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @inheritdoc
|
|
116
|
+
*/
|
|
117
|
+
public remove(): Splash {
|
|
118
|
+
if (this.element) {
|
|
119
|
+
this.element.parentElement?.removeChild(this.element)
|
|
120
|
+
delete this.element
|
|
121
|
+
}
|
|
122
|
+
return this
|
|
123
|
+
}
|
|
124
|
+
}
|