nanosplash 2.5.2 → 3.0.0

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 (80) hide show
  1. package/.github/workflows/ci.yml +48 -0
  2. package/.prettierrc +10 -9
  3. package/README.md +22 -89
  4. package/dist/main.css +1 -0
  5. package/dist/ns.cjs.js +1 -0
  6. package/dist/ns.es.js +330 -0
  7. package/dist/ns.iife.js +2 -0
  8. package/index.html +41 -122
  9. package/package.json +27 -34
  10. package/src/main.ts +8 -5
  11. package/src/sass/ns.sass +86 -0
  12. package/src/ts/core/Nanosplash/Nanosplash.ts +97 -0
  13. package/src/ts/core/Nanosplash/interfaces/NanosplashAPI.ts +50 -0
  14. package/src/ts/core/Nanosplash/interfaces/NanosplashInterface.ts +42 -0
  15. package/src/ts/core/Nanosplash/repositories/NanosplashRepository.ts +178 -0
  16. package/src/ts/core/Nanosplash/services/NanosplashService.ts +222 -0
  17. package/src/ts/types/Alias.d.ts +1 -0
  18. package/src/ts/types/Nanosplash.d.ts +18 -0
  19. package/src/ts/types/NanosplashService.d.ts +1 -0
  20. package/src/ts/util/Guid.ts +13 -0
  21. package/src/ts/util/Stack.ts +73 -0
  22. package/src/vite-env.d.ts +8 -0
  23. package/tests/Guid.spec.ts +21 -0
  24. package/tests/Nanosplash.spec.ts +64 -0
  25. package/tests/NanosplashRepository.spec.ts +91 -0
  26. package/tests/NanosplashService.spec.ts +119 -0
  27. package/tests/Stack.spec.ts +56 -0
  28. package/tsconfig.json +9 -5
  29. package/vite.config.ts +22 -14
  30. package/.github/workflows/production.yml +0 -60
  31. package/.github/workflows/release.yml +0 -61
  32. package/LICENSE +0 -21
  33. package/_config.yml +0 -1
  34. package/dist/iife/manifest.json +0 -7
  35. package/dist/iife/nanosplash.iife.js +0 -1
  36. package/dist/module/manifest.json +0 -7
  37. package/dist/module/nanosplash.cjs.js +0 -1
  38. package/dist/module/nanosplash.es.js +0 -371
  39. package/dist/module/style.css +0 -1
  40. package/docs/index.html +0 -131
  41. package/docs/nanosplash.iife.js +0 -6
  42. package/docs/style.css +0 -1
  43. package/docs/typedoc/.nojekyll +0 -1
  44. package/docs/typedoc/assets/highlight.css +0 -22
  45. package/docs/typedoc/assets/icons.css +0 -1043
  46. package/docs/typedoc/assets/icons.png +0 -0
  47. package/docs/typedoc/assets/icons@2x.png +0 -0
  48. package/docs/typedoc/assets/main.js +0 -52
  49. package/docs/typedoc/assets/search.js +0 -1
  50. package/docs/typedoc/assets/style.css +0 -1414
  51. package/docs/typedoc/assets/widgets.png +0 -0
  52. package/docs/typedoc/assets/widgets@2x.png +0 -0
  53. package/docs/typedoc/classes/Core_Nanosplash.default.html +0 -133
  54. package/docs/typedoc/index.html +0 -1
  55. package/docs/typedoc/modules/Core_Nanosplash.html +0 -1
  56. package/docs/typedoc/modules/types.html +0 -1
  57. package/favicon.svg +0 -15
  58. package/postcss.config.js +0 -8
  59. package/src/Core/Nanosplash.ts +0 -257
  60. package/src/Core/SplashInstance.ts +0 -298
  61. package/src/Exceptions/DestinationException.ts +0 -13
  62. package/src/Exceptions/Exception.ts +0 -9
  63. package/src/Exceptions/IllegalArgumentException.ts +0 -11
  64. package/src/Factory/NanosplashFactory.ts +0 -93
  65. package/src/Interfaces/ContextualAPIInterface.ts +0 -8
  66. package/src/Interfaces/IdentityInterface.ts +0 -3
  67. package/src/Interfaces/InsideInterface.ts +0 -5
  68. package/src/Interfaces/NanosplashInterface.ts +0 -8
  69. package/src/Interfaces/ProgressInterface.ts +0 -5
  70. package/src/Interfaces/ShowInterface.ts +0 -5
  71. package/src/Interfaces/WhileInterface.ts +0 -5
  72. package/src/Repositories/NanosplashRepository.ts +0 -82
  73. package/src/Tests/dom.spec.ts +0 -72
  74. package/src/Utilities/dom.ts +0 -49
  75. package/src/style.sass +0 -88
  76. package/src/types.d.ts +0 -59
  77. package/update-all.sh +0 -3
  78. package/vite.iife.config.js +0 -72
  79. package/vite.mod.config.js +0 -71
  80. package/vite.site.config.js +0 -22
@@ -0,0 +1,178 @@
1
+ // @ts-strict
2
+
3
+ /**
4
+ * # Nanosplash Repository
5
+ * A repository of functions that are used by the Nanosplash classes.
6
+ * @see Nanosplash
7
+ * @see NanosplashService
8
+ * @author Isak K. Hauge <isakhauge@icloud.com>
9
+ */
10
+
11
+ import { GUIDString } from '../../../types/Alias'
12
+ import type { Destination, DestinationNode } from '../../../types/Nanosplash'
13
+ import Nanosplash from '../Nanosplash'
14
+ import NanosplashService from '../services/NanosplashService'
15
+
16
+ /**
17
+ * # Create
18
+ * Return the main Nanosplash element.
19
+ */
20
+ export function createElement(): HTMLDivElement {
21
+ return new DOMParser().parseFromString(
22
+ '<div class=ns><div class=ns-content><div class=ns-text></div><div class=ns-spinner><svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none></circle></svg></div></div></div>',
23
+ 'text/html'
24
+ ).body.firstChild as HTMLDivElement
25
+ }
26
+
27
+ /**
28
+ * # Inject as First Child
29
+ * Insert the `node` into the `destinationNode` as its first child.
30
+ * @param node Node to inject.
31
+ * @param destinationNode Node in which the first node is to be injected.
32
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes
33
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
34
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
35
+ * @see https://developer.mozilla.org/docs/Web/API/NodeList/item
36
+ */
37
+ export function injectAsFirstChild(
38
+ node: Element,
39
+ destinationNode: Element
40
+ ): void {
41
+ const destinationNodeHasChildren = destinationNode.children.length > 0
42
+ if (destinationNodeHasChildren) {
43
+ destinationNode.insertBefore(node, destinationNode.children.item(0))
44
+ } else {
45
+ destinationNode.append(node)
46
+ }
47
+ }
48
+
49
+ /**
50
+ * # Set NS Host Class
51
+ * Add or remove the `nsHostClassName` class to the `element`.
52
+ * @param element Element to which the `nsHostClassName` class will be added or removed.
53
+ * @param action Action to perform ('add' or 'remove').
54
+ */
55
+ export function setNSHostClass(
56
+ element: Element | null,
57
+ action: 'add' | 'remove'
58
+ ): void {
59
+ element?.classList[action](Nanosplash.nsHostClassName)
60
+ }
61
+
62
+ /**
63
+ * # Prepare Parent
64
+ * Add the `nsHostClassName` class to the parent of the `ns` element.
65
+ * @param ns Nanosplash instance.
66
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/parentElement
67
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/add
68
+ */
69
+ export function prepareParentOf(ns: Nanosplash): void {
70
+ setNSHostClass(ns.getNSElement().parentElement, 'add')
71
+ }
72
+
73
+ /**
74
+ * # Clean Parent
75
+ * Remove the `nsHostClassName` class from the parent of the `ns` element.
76
+ * @param ns Nanosplash instance.
77
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/parentElement
78
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/remove
79
+ */
80
+ export function cleanNSParentOf(ns: Nanosplash): void {
81
+ setNSHostClass(ns.getNSElement().parentElement, '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
+ * # Node From
106
+ * Convert the `destination` to a HTMLElement, Element, Node or null.
107
+ * @param destination Destination of the node.
108
+ * @returns Node from the `destination`.
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 nodeFrom(destination: Destination): DestinationNode | null {
114
+ let elem: HTMLElement | null
115
+
116
+ if (typeof destination === 'string') {
117
+ elem = document.querySelector(destination)
118
+ } else if (destination instanceof Node) {
119
+ return destination
120
+ } else if (typeof destination === 'function') {
121
+ elem = <HTMLElement>destination()
122
+ if (!(elem instanceof Node)) {
123
+ return null
124
+ }
125
+ } else {
126
+ elem = null
127
+ }
128
+
129
+ return elem
130
+ }
131
+
132
+ /**
133
+ * # Element Is NS
134
+ * Check if the element is Nanosplash element.
135
+ * This is determined by the presence of the `ns` class on the element.
136
+ * @param element Element to check.
137
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/contains
138
+ */
139
+ export function elementIsNS(element: Element): boolean {
140
+ return element?.classList?.contains('ns')
141
+ }
142
+
143
+ /**
144
+ * # Move
145
+ * Move an Element to another Element.
146
+ * @param element Element to move
147
+ * @param destinationElement Target element
148
+ */
149
+ export function move(element: Element, destinationElement: Element): void {
150
+ // Clean the current NS host element.
151
+ setNSHostClass(element.parentElement, 'remove')
152
+ // Assign new NS host element.
153
+ setNSHostClass(destinationElement, 'add')
154
+ injectAsFirstChild(element, destinationElement)
155
+ }
156
+
157
+ /**
158
+ * # Get Recycled NS
159
+ * Return the Nanosplash instance inside the `destination` if it exists.
160
+ * @param destination Destination of the Nanosplash instance.
161
+ * @returns { Nanosplash | null } Nanosplash instance or null.
162
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild
163
+ */
164
+ export function getRecycledNS(destination: Destination): Nanosplash | null {
165
+ const destinationNode = nodeFrom(destination)
166
+ if (!destinationNode) return null
167
+ const firstChild = <Element>destinationNode.firstChild
168
+ const hasChild = firstChild !== null
169
+ const destinationAlreadyHasNS = hasChild && elementIsNS(firstChild)
170
+
171
+ if (destinationAlreadyHasNS) {
172
+ const id: GUIDString = firstChild.id
173
+ const nss = NanosplashService.getInstance()
174
+ return nss.nsStack.items.find((ns: Nanosplash) => ns.getId() === id) ?? null
175
+ }
176
+
177
+ return null
178
+ }
@@ -0,0 +1,222 @@
1
+ // @ts-strict
2
+
3
+ import Nanosplash from '../Nanosplash'
4
+ import Stack from '../../../util/Stack'
5
+ import {
6
+ cleanNSParentOf,
7
+ getRecycledNS,
8
+ move,
9
+ nodeFrom,
10
+ } from '../repositories/NanosplashRepository'
11
+ import type { Destination, DestinationNode } from '../../../types/Nanosplash'
12
+ import type { GUIDString } from '../../../types/Alias'
13
+ import { FindCallback } from '../../../types/NanosplashService'
14
+ import { NanosplashAPI } from '../interfaces/NanosplashAPI'
15
+
16
+ /**
17
+ * # Nanosplash Service
18
+ * A service class that handles Nanosplash instances.
19
+ * It's a singleton class and it's instance resides in the Window object and
20
+ * serves the public API of the Nanosplash library.
21
+ * @see Nanosplash
22
+ * @author Isak K. Hauge <isakhauge@icloud.com>
23
+ */
24
+ class NanosplashService implements NanosplashAPI {
25
+ private static readonly WindowAccessorKey = 'ns'
26
+ private static instance: NanosplashService
27
+
28
+ public readonly nsStack: Stack<Nanosplash>
29
+
30
+ /**
31
+ * # Constructor
32
+ * Private constructor to prevent multiple instances.
33
+ * @private
34
+ */
35
+ private constructor() {
36
+ this.nsStack = new Stack<Nanosplash>()
37
+ }
38
+
39
+ /**
40
+ * # Find Index
41
+ * Find Nanosplash stack index by callback.
42
+ * @param callback Callback function that returns a boolean.
43
+ * @returns {number} Index of Nanosplash instance in the stack or -1.
44
+ */
45
+ private findIndex(callback: FindCallback): number | -1 {
46
+ return this.nsStack.items.findIndex(callback)
47
+ }
48
+
49
+ /**
50
+ * # Find
51
+ * Find Nanosplash in the stack by callback.
52
+ * @param callback Callback function that returns a boolean.
53
+ * @returns {Nanosplash | undefined} Nanosplash instance or undefined
54
+ */
55
+ private find(callback: FindCallback): Nanosplash | undefined {
56
+ return this.nsStack.items.find(callback)
57
+ }
58
+
59
+ /**
60
+ * # Get Instance
61
+ * Singleton instance accessor
62
+ * @returns {NanosplashService} NanosplashService instance
63
+ */
64
+ public static getInstance(): NanosplashService {
65
+ if (!NanosplashService.instance) {
66
+ NanosplashService.instance = new NanosplashService()
67
+ }
68
+ return NanosplashService.instance
69
+ }
70
+
71
+ /**
72
+ * # Assign To Window
73
+ * Assign Nanosplash service instance to Window object.
74
+ * The NanosplashService instance can be accessed in the window object
75
+ * using the key window accessor key.
76
+ * @see WindowAccessorKey
77
+ */
78
+ private static assignToWindow(): void {
79
+ Object.defineProperty(window, NanosplashService.WindowAccessorKey, {
80
+ value: NanosplashService.getInstance(),
81
+ writable: false,
82
+ })
83
+ }
84
+
85
+ /**
86
+ * # Start
87
+ * Initialize Nanosplash Service instance in Window when it's loaded.
88
+ */
89
+ public static start(): void {
90
+ NanosplashService.assignToWindow()
91
+ window.addEventListener('load', () => {
92
+ const nss = window[NanosplashService.WindowAccessorKey]
93
+ const nssAssigned = nss instanceof NanosplashService
94
+ if (!nssAssigned) {
95
+ NanosplashService.assignToWindow()
96
+ }
97
+ })
98
+ }
99
+
100
+ /**
101
+ * # Create Nanosplash
102
+ * Return new Nanosplash instance and push it to the stack.
103
+ * @param text Text to display.
104
+ * @returns {Nanosplash} Nanosplash instance.
105
+ */
106
+ private createNS(text?: string): Nanosplash {
107
+ const ns = new Nanosplash()
108
+ ns.setText(text || '')
109
+ this.nsStack.push(ns)
110
+ return ns
111
+ }
112
+
113
+ /**
114
+ * # Clean And Remove
115
+ * Remove Nanosplash from DOM and clean its parent.
116
+ * @param ns Nanosplash instance.
117
+ * @returns {GUIDString} Nanosplash ID.
118
+ */
119
+ private cleanAndRemove(ns: Nanosplash): GUIDString {
120
+ cleanNSParentOf(ns)
121
+ ns.remove()
122
+ return ns.getId()
123
+ }
124
+
125
+ /**
126
+ * # Stack Delete At
127
+ * Remove Nanosplash instance from the stack.
128
+ * @param ns Nanosplash instance.
129
+ * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
130
+ */
131
+ private stackDelete(ns: Nanosplash): GUIDString | null {
132
+ let index = this.findIndex((o: Nanosplash) => o.getId() === ns.getId())
133
+ if (index < 0) return null
134
+ this.nsStack.items.splice(index, 1)
135
+ return ns.getId()
136
+ }
137
+
138
+ /**
139
+ * # Delete NS
140
+ * Remove Nanosplash instance from both the stack and the DOM.
141
+ * @param callback Callback function.
142
+ * @returns {GUIDString | null} Nanosplash ID or null if it doesn't exist.
143
+ */
144
+ private deleteNS(callback: FindCallback): GUIDString | null {
145
+ const ns = this.find(callback)
146
+ if (ns) {
147
+ this.cleanAndRemove(ns)
148
+ return this.stackDelete(ns)
149
+ }
150
+ return null
151
+ }
152
+
153
+ /**
154
+ * @inheritDoc
155
+ */
156
+ public show(text?: string): GUIDString {
157
+ let ns = getRecycledNS(document.body)
158
+ if (!ns) {
159
+ ns = this.createNS()
160
+ move(ns.getNSElement(), document.body)
161
+ }
162
+ ns.setText(text || '')
163
+ return ns.getId()
164
+ }
165
+
166
+ /**
167
+ * @inheritDoc
168
+ */
169
+ public showInside(
170
+ destination: Destination,
171
+ text?: string
172
+ ): GUIDString | null {
173
+ const destinationNode: DestinationNode | null = nodeFrom(destination)
174
+ if (destinationNode) {
175
+ let ns = getRecycledNS(destinationNode)
176
+ if (!ns) {
177
+ ns = this.createNS()
178
+ }
179
+ ns.setText(text || '')
180
+ move(ns.getNSElement(), <Element>destinationNode)
181
+ return ns.getId()
182
+ }
183
+
184
+ return null
185
+ }
186
+
187
+ /**
188
+ * @inheritDoc
189
+ */
190
+ public hideAll(): void {
191
+ this.nsStack.items.forEach((ns: Nanosplash) => {
192
+ this.cleanAndRemove(ns)
193
+ })
194
+ this.nsStack.clear()
195
+ }
196
+
197
+ /**
198
+ * @inheritDoc
199
+ */
200
+ public hide(): GUIDString | null {
201
+ const ns = this.nsStack.pop()
202
+ return ns ? this.cleanAndRemove(ns) : null
203
+ }
204
+
205
+ /**
206
+ * @inheritDoc
207
+ */
208
+ public hideId(id: GUIDString): GUIDString | null {
209
+ return this.deleteNS((ns: Nanosplash) => ns.getId() === id)
210
+ }
211
+
212
+ /**
213
+ * @inheritDoc
214
+ */
215
+ public hideInside(destination: Destination): GUIDString | null {
216
+ const node = nodeFrom(destination)
217
+ const cb = (ns: Nanosplash) => ns.getNSElement().parentElement === node
218
+ return node ? this.deleteNS(cb) : null
219
+ }
220
+ }
221
+
222
+ export default NanosplashService
@@ -0,0 +1 @@
1
+ export type GUIDString = string
@@ -0,0 +1,18 @@
1
+ export type DestinationSelector = string
2
+
3
+ export type DestinationNode = Node | Element | HTMLElement
4
+
5
+ export type DestinationCallback = () =>
6
+ | DestinationNode
7
+ | Promise<DestinationNode>
8
+
9
+ export type Destination =
10
+ | DestinationSelector
11
+ | DestinationNode
12
+ | DestinationCallback
13
+
14
+ declare global {
15
+ interface Window {
16
+ ns: NanosplashService
17
+ }
18
+ }
@@ -0,0 +1 @@
1
+ export type FindCallback = (ns: Nanosplash, index: number) => boolean
@@ -0,0 +1,13 @@
1
+ import { GUIDString } from '../types/Alias'
2
+
3
+ /**
4
+ * # GUID
5
+ * @returns {GUIDString} A GUID string.
6
+ */
7
+ export function guid(): GUIDString {
8
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
9
+ const r = (Math.random() * 16) | 0
10
+ const v = c === 'x' ? r : (r & 0x3) | 0x8
11
+ return v.toString(16)
12
+ })
13
+ }
@@ -0,0 +1,73 @@
1
+ // @ts-strict
2
+
3
+ /**
4
+ * A stack data structure.
5
+ * @template T The type of item stored in the stack.
6
+ * @author Isak K. Hauge <isakhauge@icloud.com>
7
+ */
8
+ class Stack<T> {
9
+ private _items: T[]
10
+
11
+ /**
12
+ * Constructs a new stack.
13
+ */
14
+ constructor() {
15
+ this._items = []
16
+ }
17
+
18
+ /**
19
+ * Returns the items in the stack.
20
+ */
21
+ public get items(): T[] {
22
+ return this._items
23
+ }
24
+
25
+ /**
26
+ * Adds an item to the top of the stack.
27
+ * @param item The item to add to the stack.
28
+ */
29
+ public push(item: T): void {
30
+ this._items.push(item)
31
+ }
32
+
33
+ /**
34
+ * Removes and returns the item at the top of the stack.
35
+ * @returns The item at the top of the stack, or undefined if the stack is empty.
36
+ */
37
+ public pop(): T | undefined {
38
+ return this._items.pop()
39
+ }
40
+
41
+ /**
42
+ * Returns the item at the top of the stack without removing it.
43
+ * @returns The item at the top of the stack, or undefined if the stack is empty.
44
+ */
45
+ public peek(): T | undefined {
46
+ return this._items[this._items.length - 1]
47
+ }
48
+
49
+ /**
50
+ * Returns true if the stack is empty, false otherwise.
51
+ * @returns True if the stack is empty, false otherwise.
52
+ */
53
+ public isEmpty(): boolean {
54
+ return this._items.length === 0
55
+ }
56
+
57
+ /**
58
+ * Returns the number of items in the stack.
59
+ * @returns The number of items in the stack.
60
+ */
61
+ public size(): number {
62
+ return this._items.length
63
+ }
64
+
65
+ /**
66
+ * Removes all items from the stack.
67
+ */
68
+ public clear(): void {
69
+ this._items = []
70
+ }
71
+ }
72
+
73
+ export default Stack
package/src/vite-env.d.ts CHANGED
@@ -1 +1,9 @@
1
1
  /// <reference types="vite/client" />
2
+
3
+ import Nanosplash from "./ts/core/Nanosplash/Nanosplash";
4
+
5
+ declare global {
6
+ interface Window {
7
+ ns2: Nanosplash
8
+ }
9
+ }
@@ -0,0 +1,21 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest'
2
+ import Nanosplash from '../src/ts/core/Nanosplash/Nanosplash'
3
+ import { JSDOM } from 'jsdom'
4
+
5
+ describe('Guid', () => {
6
+ // Reset the DOM before each test
7
+ beforeEach(() => {
8
+ const dom = new JSDOM()
9
+ // @ts-ignore
10
+ globalThis.window = dom.window
11
+ globalThis.document = dom.window.document
12
+ globalThis.DOMParser = dom.window.DOMParser
13
+ })
14
+
15
+ it('Should generate a valid GUID', () => {
16
+ const guidRegex =
17
+ /^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$/
18
+ const value = new Nanosplash().getId()
19
+ expect(value).toMatch(guidRegex)
20
+ })
21
+ })
@@ -0,0 +1,64 @@
1
+ // @ts-strict
2
+
3
+ import { describe, it, expect, beforeEach } from 'vitest'
4
+ import Nanosplash from '../src/ts/core/Nanosplash/Nanosplash'
5
+ import { JSDOM } from 'jsdom'
6
+
7
+ describe('Nanosplash', () => {
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 be a valid Nanosplash', () => {
18
+ const ns = new Nanosplash()
19
+ const element = ns.getNSElement()
20
+
21
+ expect(element).not.toBeUndefined()
22
+ expect(element.id).toBe(ns.getId())
23
+ expect(element.classList.contains(Nanosplash.nsClassName)).toBe(true)
24
+
25
+ const contentElement = ns.getNSContentElement()
26
+ expect(contentElement).not.toBeUndefined()
27
+
28
+ const textElement = ns.getNSTextElement()
29
+ expect(textElement).not.toBeUndefined()
30
+
31
+ const spinnerElement = <HTMLElement>textElement.nextElementSibling
32
+ expect(spinnerElement).not.toBeUndefined()
33
+
34
+ const spinnerSVGElement = <HTMLElement>spinnerElement.firstElementChild
35
+ expect(spinnerSVGElement).not.toBeUndefined()
36
+ })
37
+
38
+ it('Should be able to set text', () => {
39
+ const ns = new Nanosplash()
40
+ const text = 'Hello World!'
41
+ ns.setText(text)
42
+ expect(ns.getNSTextElement().innerText).toBe(text)
43
+ })
44
+
45
+ it('Should be able to hide text', () => {
46
+ const ns = new Nanosplash()
47
+ ns.hideText()
48
+ expect(ns.getNSTextElement().style.display).toBe('none')
49
+ })
50
+
51
+ it('Should be able to show text', () => {
52
+ const ns = new Nanosplash()
53
+ ns.setText('Hello World!')
54
+ ns.hideText()
55
+ ns.showText()
56
+ expect(ns.getNSTextElement().style.display).toBe('flex')
57
+ })
58
+
59
+ it('Should be able to remove itself from DOM', () => {
60
+ const ns = new Nanosplash()
61
+ ns.remove()
62
+ expect(ns.getNSElement()).toBeUndefined()
63
+ })
64
+ })
@@ -0,0 +1,91 @@
1
+ // @ts-strict
2
+
3
+ import { JSDOM } from 'jsdom'
4
+ import { beforeEach, describe, expect, it } from 'vitest'
5
+ import Nanosplash from '../src/ts/core/Nanosplash/Nanosplash'
6
+ import {
7
+ createElement,
8
+ injectAsFirstChild,
9
+ prepareParentOf,
10
+ cleanNSParentOf,
11
+ showElement,
12
+ hideElement,
13
+ setNSHostClass,
14
+ move,
15
+ } from '../src/ts/core/Nanosplash/repositories/NanosplashRepository'
16
+
17
+ describe('NanosplashRepository', () => {
18
+ // Reset the DOM before each test
19
+ beforeEach(() => {
20
+ const dom = new JSDOM()
21
+ // @ts-ignore
22
+ globalThis.window = dom.window
23
+ globalThis.document = dom.window.document
24
+ globalThis.DOMParser = dom.window.DOMParser
25
+ globalThis.Node = dom.window.Node
26
+ })
27
+
28
+ it('Should be able to create a Nanosplash component', () => {
29
+ const getClass = (element: Element) => element.classList[0]
30
+ const element = createElement()
31
+ const contentElement = <Element>element.firstElementChild
32
+ const textElement = <Element>contentElement.firstElementChild
33
+ const spinnerElement = <Element>textElement.nextElementSibling
34
+
35
+ expect(getClass(element)).toBe('ns')
36
+ expect(getClass(contentElement)).toBe('ns-content')
37
+ expect(getClass(textElement)).toBe('ns-text')
38
+ expect(getClass(spinnerElement)).toBe('ns-spinner')
39
+ })
40
+
41
+ it('Should be able to inject a Nanosplash component', () => {
42
+ const element = createElement()
43
+ const destinationElement = document.createElement('div')
44
+ injectAsFirstChild(element, destinationElement)
45
+ expect(destinationElement.firstElementChild).toBe(element)
46
+ })
47
+
48
+ it('Should be able to prepare the parent of a Nanosplash component', () => {
49
+ const ns = new Nanosplash()
50
+ const parent = document.createElement('div')
51
+ parent.appendChild(ns.getNSElement())
52
+ prepareParentOf(ns)
53
+ expect(parent.classList.contains(Nanosplash.nsHostClassName)).toBe(true)
54
+ })
55
+
56
+ it('Should be able to clean the parent of a Nanosplash component', () => {
57
+ const ns = new Nanosplash()
58
+ const parent = document.createElement('div')
59
+ parent.appendChild(ns.getNSElement())
60
+ parent.classList.add(Nanosplash.nsHostClassName)
61
+ cleanNSParentOf(ns)
62
+ expect(parent.classList.contains(Nanosplash.nsHostClassName)).toBe(false)
63
+ })
64
+
65
+ it('Should be able to show an element', () => {
66
+ const element = document.createElement('div')
67
+ showElement(element)
68
+ expect(element.style.display).toBe('flex')
69
+ })
70
+
71
+ it('Should be able to hide an element', () => {
72
+ const element = document.createElement('div')
73
+ hideElement(element)
74
+ expect(element.style.display).toBe('none')
75
+ })
76
+
77
+ it('Should be able to alter the class of a Nanosplash host', () => {
78
+ const div = document.createElement('div')
79
+ setNSHostClass(div, 'add')
80
+ expect(div.classList.contains(Nanosplash.nsHostClassName)).toBe(true)
81
+ setNSHostClass(div, 'remove')
82
+ expect(div.classList.contains(Nanosplash.nsHostClassName)).toBe(false)
83
+ })
84
+
85
+ it('Should be able to move a Nanosplash component', () => {
86
+ const ns = new Nanosplash()
87
+ const destination = document.createElement('div')
88
+ move(ns.getNSElement(), destination)
89
+ expect(destination.firstElementChild).toBe(ns.getNSElement())
90
+ })
91
+ })