nanosplash 3.0.7 → 3.0.9

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.
Files changed (40) hide show
  1. package/.prettierrc +1 -1
  2. package/README.md +6 -6
  3. package/bun.lockb +0 -0
  4. package/dist/cjs/ns.cjs +1 -2
  5. package/dist/es/ns.js +61 -340
  6. package/dist/iife/ns.iife.js +1 -2
  7. package/docs/.vitepress/{config.ts → config.mts} +42 -43
  8. package/docs/.vitepress/theme/css/style.css +107 -6
  9. package/docs/.vitepress/theme/vue/CardGrid.vue +1 -1
  10. package/docs/.vitepress/theme/vue/Exe.vue +58 -28
  11. package/docs/.vitepress/theme/vue/PlayGround.vue +5 -21
  12. package/docs/api/doc/hide.md +10 -31
  13. package/docs/api/doc/show.md +12 -13
  14. package/docs/api/start/features.md +1 -1
  15. package/docs/api/start/install.md +6 -4
  16. package/docs/api/start/playground.md +1 -1
  17. package/docs/api/start/usage.md +2 -5
  18. package/docs/index.md +25 -25
  19. package/docs/public/macos.jpg +0 -0
  20. package/eslint.config.js +9 -0
  21. package/package.json +54 -48
  22. package/src/style/ns.sass +100 -70
  23. package/src/ts/Nanosplash.ts +219 -0
  24. package/src/ts/main.ts +2 -8
  25. package/src/ts/types/NanosplashInterface.ts +7 -0
  26. package/src/ts/types/Types.ts +28 -3
  27. package/src/ts/types/global.d.ts +9 -9
  28. package/tests/Nanosplash.spec.ts +35 -0
  29. package/.prettierignore +0 -1
  30. package/src/ts/core/DomUtilities.ts +0 -161
  31. package/src/ts/core/Service.ts +0 -211
  32. package/src/ts/core/ServiceInterface.ts +0 -58
  33. package/src/ts/core/Splash.ts +0 -121
  34. package/src/ts/core/SplashInterface.ts +0 -46
  35. package/src/ts/core/SplashQueue.ts +0 -49
  36. package/tests/DomUtilities.spec.ts +0 -117
  37. package/tests/Guid.spec.ts +0 -21
  38. package/tests/Service.spec.ts +0 -198
  39. package/tests/Splash.spec.ts +0 -64
  40. package/tests/TestUtilities.ts +0 -48
@@ -1,211 +0,0 @@
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,58 +0,0 @@
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
12
-
13
- /**
14
- * # Show
15
- * Present a Nanosplash in the browser window displaying the given text.
16
- * @param text Text to display.
17
- * @returns {GUIDString | null} Nanosplash ID.
18
- */
19
- show(text?: string): GUIDString | null
20
-
21
- /**
22
- * # Show Inside
23
- * Present a Nanosplash over the given element displaying the given text.
24
- * @param ref Reference an element.
25
- * @param text Text to display.
26
- * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
27
- */
28
- showInside(ref: Reference, text?: string): GUIDString | null
29
-
30
- /**
31
- * # Hide
32
- * Hide the oldest Nanosplash.
33
- * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
34
- */
35
- hide(): GUIDString | null
36
-
37
- /**
38
- * # Hide All
39
- * Hide all Nanosplashes.
40
- */
41
- hideAll(): void
42
-
43
- /**
44
- * # Hide ID
45
- * Hide Nanosplash by its ID.
46
- * @param id Nanosplash ID.
47
- * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
48
- */
49
- hideId(id: GUIDString): GUIDString | null
50
-
51
- /**
52
- * # Hide Inside
53
- * Hide Nanosplash inside the given element if it exists.
54
- * @param ref Reference an element.
55
- * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
56
- */
57
- hideInside(ref: Reference): GUIDString | null
58
- }
@@ -1,121 +0,0 @@
1
- import { GUIDString } from '../types/Types'
2
- import { createElement, showElement, hideElement } from './DomUtilities'
3
- import { SplashInterface } from './SplashInterface'
4
-
5
- /**
6
- * # Splash
7
- * Small splash screen that can be used to indicate that a process
8
- * is running.
9
- * @author Isak K. Hauge <isakhauge@icloud.com>
10
- */
11
- export class Splash implements SplashInterface {
12
- /**
13
- * # CSS Class Name
14
- * The main CSS class name of the root element of a Nanosplash component.
15
- */
16
- public static readonly NSClass = 'ns'
17
-
18
- /**
19
- * # Host CSS Class Name
20
- * The CSS class name of the host element of a Nanosplash component.
21
- * The host element is the element that the Nanosplash is attached to.
22
- */
23
- public static readonly NSHostClass = 'nsh'
24
-
25
- /**
26
- * # ID
27
- * Each Nanosplash instance is given a unique GUID.
28
- */
29
- private id: GUIDString | null
30
-
31
- /**
32
- * # Element
33
- * The root element of the Nanosplash component.
34
- */
35
- private element: HTMLDivElement | null
36
-
37
- /**
38
- * # Generate GUID
39
- * @returns {GUIDString} A GUID string.
40
- * @private
41
- */
42
- private static generateGUID(): GUIDString {
43
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
44
- const r = (Math.random() * 16) | 0
45
- const v = c === 'x' ? r : (r & 0x3) | 0x8
46
- return v.toString(16)
47
- })
48
- }
49
-
50
- /**
51
- * # Constructor
52
- * Creates a new Nanosplash instance.
53
- */
54
- public constructor() {
55
- this.element = createElement()
56
- this.element.id = this.id = Splash.generateGUID()
57
- }
58
-
59
- /**
60
- * @inheritdoc
61
- */
62
- public getId(): GUIDString | null {
63
- return this.id
64
- }
65
-
66
- /**
67
- * @inheritdoc
68
- */
69
- public getElement(): HTMLDivElement | null {
70
- return <HTMLDivElement>this.element
71
- }
72
-
73
- /**
74
- * @inheritdoc
75
- */
76
- public getTextElement(): HTMLDivElement {
77
- return (
78
- <HTMLDivElement>(
79
- this.getElement()?.firstElementChild?.firstElementChild
80
- ) ?? null
81
- )
82
- }
83
-
84
- /**
85
- * @inheritdoc
86
- */
87
- public setText(text: string): Splash {
88
- this.getTextElement().innerText = text
89
- text.length > 0 ? this.showText() : this.hideText()
90
- return this
91
- }
92
-
93
- /**
94
- * @inheritdoc
95
- */
96
- public showText(): Splash {
97
- showElement(this.getTextElement())
98
- return this
99
- }
100
-
101
- /**
102
- * @inheritdoc
103
- */
104
- public hideText(): Splash {
105
- hideElement(this.getTextElement())
106
- return this
107
- }
108
-
109
- /**
110
- * @inheritdoc
111
- */
112
- public delete(): boolean {
113
- this.id = null
114
- if (this.element !== null) {
115
- this.element.innerHTML = ''
116
- this.element.remove()
117
- this.element = null
118
- }
119
- return this.element === null
120
- }
121
- }
@@ -1,46 +0,0 @@
1
- import { GUIDString } from '../types/Types'
2
- import { Splash } from './Splash'
3
-
4
- export interface SplashInterface {
5
- /**
6
- * # Get ID
7
- * Return Nanosplash instance GUID.
8
- */
9
- getId(): GUIDString | null
10
-
11
- /**
12
- * # Get Element
13
- * Return Nanosplash instance HTMLDivElement.
14
- */
15
- getElement(): HTMLDivElement | null
16
-
17
- /**
18
- * # Get Text Element
19
- * Returns the text element of the Nanosplash.
20
- */
21
- getTextElement(): HTMLDivElement | null
22
-
23
- /**
24
- * # Set Text
25
- * @param text The text that will be visible inside the splash.
26
- */
27
- setText(text: string): Splash
28
-
29
- /**
30
- * # Show Text
31
- * Display text element.
32
- */
33
- showText(): Splash
34
-
35
- /**
36
- * # Hide Text
37
- * Hide the text element.
38
- */
39
- hideText(): Splash
40
-
41
- /**
42
- * # Delete
43
- * Remove from DOM and delete internal data.
44
- */
45
- delete(): boolean
46
- }
@@ -1,49 +0,0 @@
1
- import { GUIDString } from '../types/Types'
2
- import { Splash } from './Splash'
3
-
4
- export class SplashQueue {
5
- public queue: Array<Splash>
6
-
7
- constructor() {
8
- this.queue = []
9
- }
10
-
11
- /**
12
- * # Enqueue
13
- * Add a new item to the queue.
14
- * @param item The item to add to the queue.
15
- */
16
- public enqueue(item: Splash): SplashQueue {
17
- this.queue.push(item)
18
- return this
19
- }
20
-
21
- /**
22
- * # Dequeue
23
- * Remove the first item from the queue.
24
- * @returns The first item from the queue.
25
- */
26
- public dequeue(): Splash | undefined {
27
- return this.queue.shift()
28
- }
29
-
30
- /**
31
- * # Get
32
- * @param id The GUID of the Nanosplash to get.
33
- * @returns The Nanosplash with the given GUID.
34
- */
35
- public get(id: GUIDString): Splash | undefined {
36
- return this.queue.find(item => item.getId() === id)
37
- }
38
-
39
- /**
40
- * # Delete
41
- * @param id The GUID of the Nanosplash to delete.
42
- * @returns The deleted Nanosplash.
43
- */
44
- public delete(id: GUIDString): Splash | undefined {
45
- const index = this.queue.findIndex(item => item.getId() === id)
46
- if (index === -1) return undefined
47
- return this.queue.splice(index, 1)[0]
48
- }
49
- }
@@ -1,117 +0,0 @@
1
- // @ts-strict
2
-
3
- import { JSDOM } from 'jsdom'
4
- import { beforeEach, describe, expect, it } from 'vitest'
5
- import {
6
- createElement,
7
- injectAsFirstChild,
8
- showElement,
9
- hideElement,
10
- move,
11
- elementFrom,
12
- getRecycledSplash,
13
- addNSHostClass,
14
- removeNSHostClass,
15
- } from '../src/ts/core/DomUtilities'
16
- import { Splash } from '../src/ts/core/Splash'
17
- import { Service } from '../src/ts/core/Service'
18
-
19
- describe('DOMUtilities', () => {
20
- // Reset the DOM before each test
21
- beforeEach(() => {
22
- const dom = new JSDOM()
23
- // @ts-ignore
24
- globalThis.window = dom.window
25
- globalThis.document = dom.window.document
26
- globalThis.DOMParser = dom.window.DOMParser
27
- globalThis.Element = dom.window.Element
28
- })
29
-
30
- it('Should be able to create a Nanosplash component', () => {
31
- const getClass = (element: Element) => element.classList[0]
32
- const element = createElement()
33
- const contentElement = <Element>element.firstElementChild
34
- const textElement = <Element>contentElement.firstElementChild
35
- const spinnerElement = <Element>textElement.nextElementSibling
36
-
37
- expect(getClass(element)).toBe('ns')
38
- expect(getClass(contentElement)).toBe('nsc')
39
- expect(getClass(textElement)).toBe('nst')
40
- expect(getClass(spinnerElement)).toBe('nss')
41
- })
42
-
43
- it('Should be able to inject a Nanosplash component', () => {
44
- const elementA = createElement()
45
- const elementB = createElement()
46
- const destinationElement = document.createElement('div')
47
- injectAsFirstChild(elementA, destinationElement)
48
- expect(destinationElement.firstElementChild).toBe(elementA)
49
- injectAsFirstChild(elementB, destinationElement)
50
- expect(destinationElement.firstElementChild).toBe(elementB)
51
- })
52
-
53
- it('Should be able to prepare the parent of a Nanosplash component', () => {
54
- const ns = new Splash()
55
- const parent = document.createElement('div')
56
- parent.appendChild(ns.getElement() as Element)
57
- addNSHostClass(parent)
58
- expect(parent.classList.contains(Splash.NSHostClass)).toBe(true)
59
- })
60
-
61
- it('Should be able to clean the parent of a Nanosplash component', () => {
62
- const ns = new Splash()
63
- const parent = document.createElement('div')
64
- parent.appendChild(ns.getElement() as Element)
65
- parent.classList.add(Splash.NSClass)
66
- removeNSHostClass(parent)
67
- expect(parent.classList.contains(Splash.NSHostClass)).toBe(false)
68
- })
69
-
70
- it('Should be able to convert an element reference to an element', () => {
71
- const element = document.createElement('div')
72
- document.body.appendChild(element)
73
- element.id = 'test-id'
74
- element.classList.add('test-class')
75
- element.setAttribute('data-test', 'test')
76
- expect(elementFrom('#test-id')).toBe(element)
77
- expect(elementFrom('.test-class')).toBe(element)
78
- expect(elementFrom('div[data-test="test"]')).toBe(element)
79
- expect(elementFrom(element)).toBe(element)
80
- })
81
-
82
- it('Should be able to recycle a Nanosplash component', () => {
83
- const destination = document.createElement('div')
84
- document.body.appendChild(destination)
85
- const nss = Service.getInstance()
86
- const id = nss.showInside(destination, 'Hello World!')
87
- const recycled = getRecycledSplash(destination)
88
- expect(recycled?.getId()).toBe(id)
89
- })
90
-
91
- it('Should be able to show an element', () => {
92
- const element = document.createElement('div')
93
- showElement(element)
94
- expect(element.style.display).toBe('flex')
95
- })
96
-
97
- it('Should be able to hide an element', () => {
98
- const element = document.createElement('div')
99
- hideElement(element)
100
- expect(element.style.display).toBe('none')
101
- })
102
-
103
- it('Should be able to alter the class of a Nanosplash host', () => {
104
- const div = document.createElement('div')
105
- addNSHostClass(div)
106
- expect(div.classList.contains(Splash.NSHostClass)).toBe(true)
107
- removeNSHostClass(div)
108
- expect(div.classList.contains(Splash.NSHostClass)).toBe(false)
109
- })
110
-
111
- it('Should be able to move a Nanosplash component', () => {
112
- const ns = new Splash()
113
- const destination = document.createElement('div')
114
- move(ns.getElement() as Element, destination)
115
- expect(destination.firstElementChild).toBe(ns.getElement())
116
- })
117
- })
@@ -1,21 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest'
2
- import { JSDOM } from 'jsdom'
3
- import { Splash } from '../src/ts/core/Splash'
4
-
5
- const rgx = /^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$/
6
-
7
- describe('Guid', () => {
8
- // Reset the DOM before each test
9
- beforeEach(() => {
10
- const dom = new JSDOM()
11
- // @ts-ignore
12
- globalThis.window = dom.window
13
- globalThis.document = dom.window.document
14
- globalThis.DOMParser = dom.window.DOMParser
15
- })
16
-
17
- it('Should generate a valid GUID', () => {
18
- const value = new Splash().getId()
19
- expect(value).toMatch(rgx)
20
- })
21
- })