@knowark/componarkjs 1.13.4 → 1.14.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 (35) hide show
  1. package/lib/base/component/component.js +17 -1
  2. package/lib/base/component/component.test.js +475 -389
  3. package/lib/base/utils/define.js +28 -6
  4. package/lib/base/utils/define.test.js +129 -42
  5. package/lib/base/utils/format.test.js +16 -16
  6. package/lib/base/utils/helpers.js +11 -4
  7. package/lib/base/utils/helpers.test.js +134 -115
  8. package/lib/base/utils/slots.test.js +38 -38
  9. package/lib/base/utils/uuid.test.js +13 -13
  10. package/lib/components/audio/components/audio.js +19 -1
  11. package/lib/components/audio/components/audio.test.js +120 -90
  12. package/lib/components/camera/components/camera.js +5 -0
  13. package/lib/components/camera/components/camera.test.js +96 -91
  14. package/lib/components/capture/components/capture.js +30 -2
  15. package/lib/components/capture/components/capture.test.js +165 -97
  16. package/lib/components/droparea/components/droparea-preview.js +58 -8
  17. package/lib/components/droparea/components/droparea-preview.test.js +262 -80
  18. package/lib/components/droparea/components/droparea.js +41 -4
  19. package/lib/components/droparea/components/droparea.test.js +309 -299
  20. package/lib/components/emit/components/emit.js +23 -3
  21. package/lib/components/emit/components/emit.test.js +192 -134
  22. package/lib/components/list/components/item.test.js +69 -68
  23. package/lib/components/list/components/list.js +33 -3
  24. package/lib/components/list/components/list.test.js +358 -227
  25. package/lib/components/paginator/components/paginator.test.js +146 -143
  26. package/lib/components/spinner/components/spinner.test.js +36 -41
  27. package/lib/components/splitview/components/splitview.detail.test.js +75 -73
  28. package/lib/components/splitview/components/splitview.js +36 -8
  29. package/lib/components/splitview/components/splitview.master.js +27 -2
  30. package/lib/components/splitview/components/splitview.master.test.js +52 -52
  31. package/lib/components/splitview/components/splitview.test.js +135 -31
  32. package/lib/components/translate/components/translate.js +28 -8
  33. package/lib/components/translate/components/translate.test.js +492 -133
  34. package/package.json +3 -27
  35. package/scripts/node-test-setup.js +94 -0
@@ -1,55 +1,55 @@
1
+ import { it } from 'node:test';
2
+ import assert from 'node:assert/strict';
1
3
  import './splitview.master.js'
2
4
 
3
- describe('SplitViewMaster', () => {
4
- let container = null
5
- beforeEach(() => {
6
- container = document.createElement('div')
7
- document.body.appendChild(container)
8
- })
9
-
10
- afterEach(() => {
11
- container.remove()
12
- container = null
13
- })
14
-
15
- it('can be instantiated', () => {
16
- container.innerHTML = /* html */`
17
- <ark-splitview-master>
18
- </ark-splitview-master>
19
- `
20
- const master = container.querySelector('ark-splitview-master')
21
- master.init()
22
- master.connectedCallback()
23
-
24
- expect(master).toBeTruthy()
25
- expect(master).toBe(master.init())
26
- expect(master.getAttribute('master-event')).toEqual('')
27
- })
28
-
29
- it('can be instantiated with master-event attribute', () => {
30
- container.innerHTML = `
31
- <ark-splitview-master master-event="my-event">
32
- </ark-splitview-master>
33
- `
34
- const master = container.querySelector('ark-splitview-master')
35
- expect(master.getAttribute('master-event')).toEqual('my-event')
36
- expect(master.masterEvent).toEqual('my-event')
37
- })
38
-
39
- it('can throw a master-change event', () => {
40
- container.innerHTML = `
41
- <ark-splitview-master master-event="click">
42
- <button>Button</button>
43
- </ark-splitview-master>
44
- `
45
- const master = container.querySelector('ark-splitview-master')
46
- const button = master.select('button')
47
-
48
- let masterEvent = null
49
- master.addEventListener('master-change', (event) => { masterEvent = event })
50
-
51
- button.click()
52
-
53
- expect(masterEvent).toBeTruthy()
54
- })
5
+ let container = null
6
+
7
+ const setup = () => {
8
+ document.body.innerHTML = '';
9
+ container = document.createElement('div')
10
+ document.body.appendChild(container)
11
+ };
12
+
13
+ it('can be instantiated', () => {
14
+ setup();
15
+ container.innerHTML = /* html */`
16
+ <ark-splitview-master>
17
+ </ark-splitview-master>
18
+ `
19
+ const master = container.querySelector('ark-splitview-master')
20
+ master.init()
21
+ master.connectedCallback()
22
+
23
+ assert.ok(master)
24
+ assert.strictEqual(master, master.init())
25
+ assert.deepStrictEqual(master.getAttribute('master-event'), '')
26
+ })
27
+
28
+ it('can be instantiated with master-event attribute', () => {
29
+ setup();
30
+ container.innerHTML = `
31
+ <ark-splitview-master master-event="my-event">
32
+ </ark-splitview-master>
33
+ `
34
+ const master = container.querySelector('ark-splitview-master')
35
+ assert.deepStrictEqual(master.getAttribute('master-event'), 'my-event')
36
+ assert.deepStrictEqual(master.masterEvent, 'my-event')
37
+ })
38
+
39
+ it('can throw a master-change event', () => {
40
+ setup();
41
+ container.innerHTML = `
42
+ <ark-splitview-master master-event="click">
43
+ <button>Button</button>
44
+ </ark-splitview-master>
45
+ `
46
+ const master = container.querySelector('ark-splitview-master')
47
+ const button = master.select('button')
48
+
49
+ let masterEvent = null
50
+ master.addEventListener('master-change', (event) => { masterEvent = event })
51
+
52
+ button.click()
53
+
54
+ assert.ok(masterEvent)
55
55
  })
@@ -1,6 +1,8 @@
1
+ import { it } from 'node:test';
2
+ import assert from 'node:assert/strict';
1
3
  import { Component } from '#base/index.js'
2
4
  import './splitview.js'
3
- import './splitview.detail'
5
+ import './splitview.detail.js'
4
6
  import './splitview.master.js'
5
7
 
6
8
  class NestedMaster extends Component {
@@ -28,47 +30,149 @@ class NestedDetail extends Component {
28
30
  }
29
31
  Component.define('nested-detail', NestedDetail)
30
32
 
31
- describe('SplitView', () => {
32
- let container = null
33
- beforeEach(() => {
34
- container = document.createElement('div')
35
- document.body.appendChild(container)
36
- })
33
+ let container = null
37
34
 
38
- afterEach(() => {
39
- container.remove()
40
- container = null
41
- })
35
+ const setup = () => {
36
+ document.body.innerHTML = '';
37
+ container = document.createElement('div')
38
+ document.body.appendChild(container)
39
+ };
40
+
41
+ it('can be instantiated', () => {
42
+ setup();
43
+ container.innerHTML = /* html */`
44
+ <ark-splitview></ark-splitview>
45
+ `
46
+ const splitview = container.querySelector('ark-splitview')
47
+
48
+ assert.ok(splitview)
49
+ assert.strictEqual(splitview.init(), splitview)
50
+ })
51
+
52
+ it('can coordinate the master and the detail components', () => {
53
+ setup();
54
+ container.innerHTML = /* html */`
55
+ <ark-splitview>
56
+ <ark-splitview-master master-event="nested:master">
57
+ <nested-master></nested-master>
58
+ </ark-splitview-master>
59
+ <ark-splitview-detail>
60
+ <nested-detail></nested-detail>
61
+ </ark-splitview-detail>
62
+ </ark-splitview>
63
+ `
64
+ const splitview = container.querySelector('ark-splitview')
65
+
66
+ const nestedMaster = splitview.select('nested-master')
67
+
68
+ nestedMaster.click()
69
+
70
+ const nestedDetail = splitview.select('nested-detail')
42
71
 
43
- it('can be instantiated', () => {
72
+ assert.deepStrictEqual(nestedDetail.content, 'NESTED MASTER VALUE')
73
+ })
74
+
75
+ it('cleans up global resize listeners when disconnected', () => {
76
+ setup()
77
+ const addEventListener = globalThis.addEventListener
78
+ const removeEventListener = globalThis.removeEventListener
79
+ let resizeAdded = 0
80
+ let resizeRemoved = 0
81
+
82
+ globalThis.addEventListener = function (type, listener, options) {
83
+ if (type === 'resize') resizeAdded += 1
84
+ return addEventListener(type, listener, options)
85
+ }
86
+
87
+ globalThis.removeEventListener = function (type, listener, options) {
88
+ if (type === 'resize') resizeRemoved += 1
89
+ return removeEventListener(type, listener, options)
90
+ }
91
+
92
+ try {
44
93
  container.innerHTML = /* html */`
45
94
  <ark-splitview></ark-splitview>
46
95
  `
47
96
  const splitview = container.querySelector('ark-splitview')
97
+ splitview.remove()
98
+ } finally {
99
+ globalThis.addEventListener = addEventListener
100
+ globalThis.removeEventListener = removeEventListener
101
+ }
48
102
 
49
- expect(splitview).toBeTruthy()
50
- expect(splitview.init()).toBe(splitview)
103
+ assert.ok(resizeAdded > 0)
104
+ assert.ok(resizeRemoved > 0)
105
+ })
106
+
107
+ it('returns early when there is no detail component to render', () => {
108
+ setup()
109
+ container.innerHTML = /* html */`
110
+ <ark-splitview></ark-splitview>
111
+ `
112
+ const splitview = container.querySelector('ark-splitview')
113
+
114
+ assert.doesNotThrow(() => {
115
+ splitview.renderDetail({ value: 'ignored' })
51
116
  })
117
+ })
52
118
 
53
- it('can coordinate the master and the detail components', () => {
54
- container.innerHTML = /* html */`
55
- <ark-splitview>
56
- <ark-splitview-master master-event="nested:master">
57
- <nested-master></nested-master>
58
- </ark-splitview-master>
59
- <ark-splitview-detail>
60
- <nested-detail></nested-detail>
61
- </ark-splitview-detail>
62
- </ark-splitview>
63
- `
64
- const splitview = container.querySelector('ark-splitview')
119
+ it('returns early when removing master listener with no master bound', () => {
120
+ setup()
121
+ container.innerHTML = /* html */`
122
+ <ark-splitview></ark-splitview>
123
+ `
124
+ const splitview = container.querySelector('ark-splitview')
65
125
 
66
- const nestedMaster = splitview.select('nested-master')
126
+ assert.doesNotThrow(() => {
127
+ splitview._removeMasterListener()
128
+ })
129
+ })
67
130
 
68
- nestedMaster.click()
131
+ it('does not rebind master listener when the master is unchanged', () => {
132
+ setup()
133
+ container.innerHTML = /* html */`
134
+ <ark-splitview>
135
+ <ark-splitview-master master-event="nested:master"></ark-splitview-master>
136
+ <ark-splitview-detail>
137
+ <nested-detail></nested-detail>
138
+ </ark-splitview-detail>
139
+ </ark-splitview>
140
+ `
141
+ const splitview = container.querySelector('ark-splitview')
142
+ const master = splitview.master
143
+ const addSpy = master.addEventListener
144
+ let added = 0
145
+ master.addEventListener = function (type, listener, options) {
146
+ added += 1
147
+ return addSpy.call(this, type, listener, options)
148
+ }
69
149
 
70
- const nestedDetail = splitview.select('nested-detail')
150
+ try {
151
+ splitview._removeMasterListener()
152
+ splitview._setMasterListener()
153
+ splitview._setMasterListener()
154
+ } finally {
155
+ master.addEventListener = addSpy
156
+ }
71
157
 
72
- expect(nestedDetail.content).toEqual('NESTED MASTER VALUE')
73
- })
158
+ assert.deepStrictEqual(added, 1)
159
+ })
160
+
161
+ it('returns early when viewport dimensions are unavailable', () => {
162
+ setup()
163
+ container.innerHTML = /* html */`
164
+ <ark-splitview></ark-splitview>
165
+ `
166
+ const splitview = container.querySelector('ark-splitview')
167
+ const originalInnerHeight = globalThis.innerHeight
168
+ const originalInnerWidth = globalThis.innerWidth
169
+
170
+ globalThis.innerHeight = undefined
171
+ assert.doesNotThrow(() => splitview.setDimensions())
172
+
173
+ globalThis.innerHeight = originalInnerHeight
174
+ globalThis.innerWidth = undefined
175
+ assert.doesNotThrow(() => splitview.setDimensions())
176
+
177
+ globalThis.innerWidth = originalInnerWidth
74
178
  })
@@ -14,7 +14,11 @@ export class Translate extends Component {
14
14
  /** @type {HTMLTemplateElement} */ (this.querySelector('template')))
15
15
  if (dictionary) {
16
16
  const content = dictionary.content.textContent
17
- this.dictionary = JSON.parse(content)
17
+ try {
18
+ this.dictionary = JSON.parse(content)
19
+ } catch (error) {
20
+ this.emit('error', error)
21
+ }
18
22
  }
19
23
 
20
24
  return super.init(context)
@@ -31,9 +35,12 @@ export class Translate extends Component {
31
35
 
32
36
  this.content = `
33
37
  <select listen on-change="onLanguageChanged">
34
- ${languages.map(code => `
35
- <option value="${code}">${LANGUAGE_LIST[code].name}</option>
36
- `)}
38
+ ${languages.map(code => {
39
+ const normalizedCode = code.trim()
40
+ const language = LANGUAGE_LIST[normalizedCode]
41
+ const name = language ? language.name : normalizedCode
42
+ return `<option value="${normalizedCode}">${name}</option>`
43
+ }).join('')}
37
44
  </select>
38
45
  `
39
46
  return super.render()
@@ -49,10 +56,18 @@ export class Translate extends Component {
49
56
  const language = options.language || 'es'
50
57
  const root = this.global.document.querySelector(
51
58
  options.root || this.root)
59
+ if (!root) return
60
+
61
+ const dictionaries = {}
52
62
 
53
63
  for (const node of root.querySelectorAll('[data-i18n]')) {
54
64
  const { key, namespace } = this.parseKey(node.dataset.i18n)
55
- const dictionary = await this.resolveDictionary(language, namespace)
65
+ dictionaries[namespace] || (
66
+ dictionaries[namespace] = await this.resolveDictionary(
67
+ language, namespace
68
+ )
69
+ )
70
+ const dictionary = dictionaries[namespace]
56
71
 
57
72
  node.textContent = dictionary[key] || node.textContent
58
73
  }
@@ -80,9 +95,14 @@ export class Translate extends Component {
80
95
  if (!this.global.fetch) return {}
81
96
 
82
97
  const url = `${this.endpoint}/${language}/${namespace}.json`
83
- const response = await this.global.fetch(url)
84
-
85
- dictionary = await response.json()
98
+ try {
99
+ const response = await this.global.fetch(url)
100
+ if (response.ok === false) return {}
101
+ dictionary = await response.json()
102
+ } catch (error) {
103
+ this.emit('error', error)
104
+ return {}
105
+ }
86
106
 
87
107
  this.dictionary[language] || (this.dictionary[language] = {})
88
108
  this.dictionary[language][namespace] = dictionary