@vpmedia/phaser 1.113.0 → 1.115.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 (170) hide show
  1. package/dist/index.js +402 -379
  2. package/dist/index.js.map +1 -1
  3. package/dist/phaser/core/animation_manager.d.ts +2 -1
  4. package/dist/phaser/core/animation_manager.d.ts.map +1 -1
  5. package/dist/phaser/core/array_set.d.ts +1 -1
  6. package/dist/phaser/core/array_set.d.ts.map +1 -1
  7. package/dist/phaser/core/cache.d.ts +1 -1
  8. package/dist/phaser/core/cache.d.ts.map +1 -1
  9. package/dist/phaser/core/factory.d.ts +1 -1
  10. package/dist/phaser/core/factory.d.ts.map +1 -1
  11. package/dist/phaser/core/game.d.ts +2 -0
  12. package/dist/phaser/core/game.d.ts.map +1 -1
  13. package/dist/phaser/core/input.d.ts +5 -5
  14. package/dist/phaser/core/input.d.ts.map +1 -1
  15. package/dist/phaser/core/input_event.d.ts +35 -0
  16. package/dist/phaser/core/input_event.d.ts.map +1 -0
  17. package/dist/phaser/core/input_handler.d.ts +2 -2
  18. package/dist/phaser/core/input_handler.d.ts.map +1 -1
  19. package/dist/phaser/core/input_mouse.d.ts +27 -26
  20. package/dist/phaser/core/input_mouse.d.ts.map +1 -1
  21. package/dist/phaser/core/input_mspointer.d.ts +16 -15
  22. package/dist/phaser/core/input_mspointer.d.ts.map +1 -1
  23. package/dist/phaser/core/input_pointer.d.ts +9 -8
  24. package/dist/phaser/core/input_pointer.d.ts.map +1 -1
  25. package/dist/phaser/core/input_touch.d.ts +18 -17
  26. package/dist/phaser/core/input_touch.d.ts.map +1 -1
  27. package/dist/phaser/core/loader.d.ts +64 -30
  28. package/dist/phaser/core/loader.d.ts.map +1 -1
  29. package/dist/phaser/core/scale_manager.d.ts +1 -1
  30. package/dist/phaser/core/scale_manager.d.ts.map +1 -1
  31. package/dist/phaser/core/scene_manager.d.ts +14 -4
  32. package/dist/phaser/core/scene_manager.d.ts.map +1 -1
  33. package/dist/phaser/core/signal.d.ts +8 -8
  34. package/dist/phaser/core/signal.d.ts.map +1 -1
  35. package/dist/phaser/core/signal_binding.d.ts +2 -2
  36. package/dist/phaser/core/signal_binding.d.ts.map +1 -1
  37. package/dist/phaser/core/sound.d.ts +1 -1
  38. package/dist/phaser/core/sound.d.ts.map +1 -1
  39. package/dist/phaser/core/sound_manager.d.ts +3 -3
  40. package/dist/phaser/core/sound_manager.d.ts.map +1 -1
  41. package/dist/phaser/core/sound_sprite.d.ts +1 -1
  42. package/dist/phaser/core/sound_sprite.d.ts.map +1 -1
  43. package/dist/phaser/core/timer.d.ts +5 -5
  44. package/dist/phaser/core/timer.d.ts.map +1 -1
  45. package/dist/phaser/core/timer_event.d.ts +2 -2
  46. package/dist/phaser/core/timer_event.d.ts.map +1 -1
  47. package/dist/phaser/core/tween.d.ts +4 -4
  48. package/dist/phaser/core/tween.d.ts.map +1 -1
  49. package/dist/phaser/core/tween_data.d.ts +2 -1
  50. package/dist/phaser/core/tween_data.d.ts.map +1 -1
  51. package/dist/phaser/core/tween_manager.d.ts +1 -1
  52. package/dist/phaser/core/tween_manager.d.ts.map +1 -1
  53. package/dist/phaser/display/button.d.ts +1 -1
  54. package/dist/phaser/display/button.d.ts.map +1 -1
  55. package/dist/phaser/display/canvas/buffer.d.ts +3 -3
  56. package/dist/phaser/display/canvas/buffer.d.ts.map +1 -1
  57. package/dist/phaser/display/canvas/graphics.d.ts +2 -2
  58. package/dist/phaser/display/canvas/graphics.d.ts.map +1 -1
  59. package/dist/phaser/display/canvas/masker.d.ts +5 -2
  60. package/dist/phaser/display/canvas/masker.d.ts.map +1 -1
  61. package/dist/phaser/display/canvas/renderer.d.ts +6 -5
  62. package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
  63. package/dist/phaser/display/canvas/tinter.d.ts +2 -1
  64. package/dist/phaser/display/canvas/tinter.d.ts.map +1 -1
  65. package/dist/phaser/display/canvas/util.d.ts +11 -4
  66. package/dist/phaser/display/canvas/util.d.ts.map +1 -1
  67. package/dist/phaser/display/display_object.d.ts +4 -3
  68. package/dist/phaser/display/display_object.d.ts.map +1 -1
  69. package/dist/phaser/display/graphics.d.ts +47 -27
  70. package/dist/phaser/display/graphics.d.ts.map +1 -1
  71. package/dist/phaser/display/graphics_data.d.ts +20 -11
  72. package/dist/phaser/display/graphics_data.d.ts.map +1 -1
  73. package/dist/phaser/display/image.d.ts +4 -3
  74. package/dist/phaser/display/image.d.ts.map +1 -1
  75. package/dist/phaser/display/render_session.d.ts +44 -0
  76. package/dist/phaser/display/render_session.d.ts.map +1 -0
  77. package/dist/phaser/display/sprite_util.d.ts +4 -3
  78. package/dist/phaser/display/sprite_util.d.ts.map +1 -1
  79. package/dist/phaser/display/text.d.ts +65 -31
  80. package/dist/phaser/display/text.d.ts.map +1 -1
  81. package/dist/phaser/display/webgl/base_texture.d.ts +3 -3
  82. package/dist/phaser/display/webgl/base_texture.d.ts.map +1 -1
  83. package/dist/phaser/display/webgl/earcut.d.ts +25 -25
  84. package/dist/phaser/display/webgl/earcut.d.ts.map +1 -1
  85. package/dist/phaser/display/webgl/earcut_node.d.ts +2 -2
  86. package/dist/phaser/display/webgl/earcut_node.d.ts.map +1 -1
  87. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts +3 -2
  88. package/dist/phaser/display/webgl/fast_sprite_batch.d.ts.map +1 -1
  89. package/dist/phaser/display/webgl/filter_manager.d.ts +1 -1
  90. package/dist/phaser/display/webgl/filter_manager.d.ts.map +1 -1
  91. package/dist/phaser/display/webgl/graphics.d.ts +2 -1
  92. package/dist/phaser/display/webgl/graphics.d.ts.map +1 -1
  93. package/dist/phaser/display/webgl/graphics_data.d.ts +9 -9
  94. package/dist/phaser/display/webgl/graphics_data.d.ts.map +1 -1
  95. package/dist/phaser/display/webgl/mask_manager.d.ts +3 -2
  96. package/dist/phaser/display/webgl/mask_manager.d.ts.map +1 -1
  97. package/dist/phaser/display/webgl/render_texture.d.ts +3 -3
  98. package/dist/phaser/display/webgl/render_texture.d.ts.map +1 -1
  99. package/dist/phaser/display/webgl/renderer.d.ts +5 -4
  100. package/dist/phaser/display/webgl/renderer.d.ts.map +1 -1
  101. package/dist/phaser/display/webgl/shader/normal.d.ts +3 -1
  102. package/dist/phaser/display/webgl/shader/normal.d.ts.map +1 -1
  103. package/dist/phaser/display/webgl/shader_manager.d.ts +10 -4
  104. package/dist/phaser/display/webgl/shader_manager.d.ts.map +1 -1
  105. package/dist/phaser/display/webgl/sprite_batch.d.ts +4 -3
  106. package/dist/phaser/display/webgl/sprite_batch.d.ts.map +1 -1
  107. package/dist/phaser/display/webgl/stencil_manager.d.ts +4 -3
  108. package/dist/phaser/display/webgl/stencil_manager.d.ts.map +1 -1
  109. package/dist/phaser/display/webgl/texture.d.ts +6 -6
  110. package/dist/phaser/display/webgl/texture.d.ts.map +1 -1
  111. package/package.json +1 -1
  112. package/src/phaser/core/animation_manager.ts +2 -2
  113. package/src/phaser/core/array_set.ts +1 -1
  114. package/src/phaser/core/cache.ts +1 -1
  115. package/src/phaser/core/factory.ts +1 -1
  116. package/src/phaser/core/game.ts +2 -0
  117. package/src/phaser/core/input.ts +7 -6
  118. package/src/phaser/core/input_event.ts +34 -0
  119. package/src/phaser/core/input_handler.ts +2 -11
  120. package/src/phaser/core/input_mouse.ts +53 -36
  121. package/src/phaser/core/input_mspointer.ts +54 -29
  122. package/src/phaser/core/input_pointer.test.ts +149 -0
  123. package/src/phaser/core/input_pointer.ts +20 -21
  124. package/src/phaser/core/input_touch.ts +48 -31
  125. package/src/phaser/core/loader.test.ts +139 -0
  126. package/src/phaser/core/loader.ts +146 -83
  127. package/src/phaser/core/scale_manager.ts +1 -1
  128. package/src/phaser/core/scene_manager.ts +16 -8
  129. package/src/phaser/core/signal.ts +8 -8
  130. package/src/phaser/core/signal_binding.ts +2 -2
  131. package/src/phaser/core/sound.ts +4 -4
  132. package/src/phaser/core/sound_manager.ts +17 -19
  133. package/src/phaser/core/sound_sprite.ts +2 -2
  134. package/src/phaser/core/timer.ts +6 -6
  135. package/src/phaser/core/timer_event.ts +2 -2
  136. package/src/phaser/core/tween.ts +6 -6
  137. package/src/phaser/core/tween_data.ts +2 -1
  138. package/src/phaser/core/tween_manager.ts +1 -1
  139. package/src/phaser/display/button.ts +1 -1
  140. package/src/phaser/display/canvas/buffer.ts +3 -3
  141. package/src/phaser/display/canvas/graphics.ts +24 -20
  142. package/src/phaser/display/canvas/masker.ts +5 -2
  143. package/src/phaser/display/canvas/renderer.ts +10 -11
  144. package/src/phaser/display/canvas/tinter.ts +4 -3
  145. package/src/phaser/display/canvas/util.ts +15 -5
  146. package/src/phaser/display/display_object.ts +6 -5
  147. package/src/phaser/display/graphics.test.ts +122 -0
  148. package/src/phaser/display/graphics.ts +73 -64
  149. package/src/phaser/display/graphics_data.ts +22 -12
  150. package/src/phaser/display/image.ts +4 -3
  151. package/src/phaser/display/render_session.ts +45 -0
  152. package/src/phaser/display/sprite_util.ts +10 -8
  153. package/src/phaser/display/text.test.ts +136 -0
  154. package/src/phaser/display/text.ts +183 -119
  155. package/src/phaser/display/webgl/base_texture.ts +3 -3
  156. package/src/phaser/display/webgl/earcut.test.ts +132 -0
  157. package/src/phaser/display/webgl/earcut.ts +84 -74
  158. package/src/phaser/display/webgl/earcut_node.ts +5 -5
  159. package/src/phaser/display/webgl/fast_sprite_batch.ts +4 -4
  160. package/src/phaser/display/webgl/filter_manager.ts +1 -1
  161. package/src/phaser/display/webgl/graphics.ts +26 -17
  162. package/src/phaser/display/webgl/graphics_data.ts +9 -9
  163. package/src/phaser/display/webgl/mask_manager.ts +3 -2
  164. package/src/phaser/display/webgl/render_texture.ts +3 -3
  165. package/src/phaser/display/webgl/renderer.ts +7 -6
  166. package/src/phaser/display/webgl/shader/normal.ts +23 -6
  167. package/src/phaser/display/webgl/shader_manager.ts +15 -6
  168. package/src/phaser/display/webgl/sprite_batch.ts +4 -3
  169. package/src/phaser/display/webgl/stencil_manager.ts +10 -3
  170. package/src/phaser/display/webgl/texture.ts +6 -6
@@ -1,8 +1,9 @@
1
1
  import type { Game } from './game.js';
2
+ import type { InputEvent } from './input_event.js';
2
3
  export class Touch {
3
- public game!: any;
4
+ public game!: Game;
4
5
  public enabled!: any;
5
- public callbackContext!: any;
6
+ public callbackContext!: unknown;
6
7
  public touchStartCallback!: any;
7
8
  public touchMoveCallback!: any;
8
9
  public touchEndCallback!: any;
@@ -10,14 +11,14 @@ export class Touch {
10
11
  public touchLeaveCallback!: any;
11
12
  public touchCancelCallback!: any;
12
13
  public preventDefault!: any;
13
- public event!: any;
14
- public _onTouchStart: ((event: TouchEvent) => void) | null;
15
- public _onTouchMove: ((event: TouchEvent) => void) | null;
16
- public _onTouchEnd: ((event: TouchEvent) => void) | null;
17
- public _onTouchEnter: ((event: TouchEvent) => void) | null;
18
- public _onTouchLeave: ((event: TouchEvent) => void) | null;
19
- public _onTouchCancel: ((event: TouchEvent) => void) | null;
20
- public _documentTouchMove!: (event: TouchEvent) => void;
14
+ public event!: InputEvent | null;
15
+ public _onTouchStart: EventListener | null;
16
+ public _onTouchMove: EventListener | null;
17
+ public _onTouchEnd: EventListener | null;
18
+ public _onTouchEnter: EventListener | null;
19
+ public _onTouchLeave: EventListener | null;
20
+ public _onTouchCancel: EventListener | null;
21
+ public _documentTouchMove!: EventListener;
21
22
  /**
22
23
  * TBD.
23
24
  * @param {Game} game - TBD.
@@ -84,12 +85,24 @@ export class Touch {
84
85
  if (!this.game.device.touch) {
85
86
  return;
86
87
  }
87
- this.game.canvas.removeEventListener('touchstart', this._onTouchStart);
88
- this.game.canvas.removeEventListener('touchmove', this._onTouchMove);
89
- this.game.canvas.removeEventListener('touchend', this._onTouchEnd);
90
- this.game.canvas.removeEventListener('touchenter', this._onTouchEnter);
91
- this.game.canvas.removeEventListener('touchleave', this._onTouchLeave);
92
- this.game.canvas.removeEventListener('touchcancel', this._onTouchCancel);
88
+ if (this._onTouchStart) {
89
+ this.game.canvas.removeEventListener('touchstart', this._onTouchStart);
90
+ }
91
+ if (this._onTouchMove) {
92
+ this.game.canvas.removeEventListener('touchmove', this._onTouchMove);
93
+ }
94
+ if (this._onTouchEnd) {
95
+ this.game.canvas.removeEventListener('touchend', this._onTouchEnd);
96
+ }
97
+ if (this._onTouchEnter) {
98
+ this.game.canvas.removeEventListener('touchenter', this._onTouchEnter);
99
+ }
100
+ if (this._onTouchLeave) {
101
+ this.game.canvas.removeEventListener('touchleave', this._onTouchLeave);
102
+ }
103
+ if (this._onTouchCancel) {
104
+ this.game.canvas.removeEventListener('touchcancel', this._onTouchCancel);
105
+ }
93
106
  }
94
107
 
95
108
  /**
@@ -106,7 +119,7 @@ export class Touch {
106
119
  * TBD.
107
120
  * @param {TouchEvent} event - TBD.
108
121
  */
109
- public onTouchStart(event: any) {
122
+ public onTouchStart(event: InputEvent) {
110
123
  this.event = event;
111
124
  if (!this.game.input.enabled || !this.enabled) {
112
125
  return;
@@ -118,8 +131,9 @@ export class Touch {
118
131
  // event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element)
119
132
  // event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element
120
133
  // event.changedTouches = the touches that CHANGED in this event, not the total number of them
121
- for (let i = 0; i < event.changedTouches.length; i += 1) {
122
- this.game.input.startPointer(event.changedTouches[i]);
134
+ const changed = event.changedTouches ?? [];
135
+ for (let i = 0; i < changed.length; i += 1) {
136
+ this.game.input.startPointer(changed[i]!);
123
137
  }
124
138
  }
125
139
 
@@ -127,7 +141,7 @@ export class Touch {
127
141
  * TBD.
128
142
  * @param {TouchEvent} event - TBD.
129
143
  */
130
- public onTouchCancel(event: any) {
144
+ public onTouchCancel(event: InputEvent) {
131
145
  this.event = event;
132
146
  if (this.touchCancelCallback) {
133
147
  this.touchCancelCallback.call(this.callbackContext, event);
@@ -138,8 +152,9 @@ export class Touch {
138
152
  this.eventPreventDefault(event);
139
153
  // Touch cancel - touches that were disrupted (perhaps by moving into a plugin or browser chrome)
140
154
  // http://www.w3.org/TR/touch-events/#dfn-touchcancel
141
- for (let i = 0; i < event.changedTouches.length; i += 1) {
142
- this.game.input.stopPointer(event.changedTouches[i]);
155
+ const changed = event.changedTouches ?? [];
156
+ for (let i = 0; i < changed.length; i += 1) {
157
+ this.game.input.stopPointer(changed[i]!);
143
158
  }
144
159
  }
145
160
 
@@ -147,7 +162,7 @@ export class Touch {
147
162
  * TBD.
148
163
  * @param {TouchEvent} event - TBD.
149
164
  */
150
- public onTouchEnter(event: any) {
165
+ public onTouchEnter(event: InputEvent) {
151
166
  this.event = event;
152
167
  if (this.touchEnterCallback) {
153
168
  this.touchEnterCallback.call(this.callbackContext, event);
@@ -162,7 +177,7 @@ export class Touch {
162
177
  * TBD.
163
178
  * @param {TouchEvent} event - TBD.
164
179
  */
165
- public onTouchLeave(event: any) {
180
+ public onTouchLeave(event: InputEvent) {
166
181
  this.event = event;
167
182
  if (this.touchLeaveCallback) {
168
183
  this.touchLeaveCallback.call(this.callbackContext, event);
@@ -174,14 +189,15 @@ export class Touch {
174
189
  * TBD.
175
190
  * @param {TouchEvent} event - TBD.
176
191
  */
177
- public onTouchMove(event: any) {
192
+ public onTouchMove(event: InputEvent) {
178
193
  this.event = event;
179
194
  if (this.touchMoveCallback) {
180
195
  this.touchMoveCallback.call(this.callbackContext, event);
181
196
  }
182
197
  this.eventPreventDefault(event);
183
- for (let i = 0; i < event.changedTouches.length; i += 1) {
184
- this.game.input.updatePointer(event.changedTouches[i]);
198
+ const changed = event.changedTouches ?? [];
199
+ for (let i = 0; i < changed.length; i += 1) {
200
+ this.game.input.updatePointer(changed[i]!);
185
201
  }
186
202
  }
187
203
 
@@ -189,7 +205,7 @@ export class Touch {
189
205
  * TBD.
190
206
  * @param {TouchEvent} event - TBD.
191
207
  */
192
- public onTouchEnd(event: any) {
208
+ public onTouchEnd(event: InputEvent) {
193
209
  this.event = event;
194
210
  if (this.touchEndCallback) {
195
211
  this.touchEndCallback.call(this.callbackContext, event);
@@ -198,8 +214,9 @@ export class Touch {
198
214
  // For touch end its a list of the touch points that have been removed from the surface
199
215
  // https://developer.mozilla.org/en-US/docs/DOM/TouchList
200
216
  // event.changedTouches = the touches that CHANGED in this event, not the total number of them
201
- for (let i = 0; i < event.changedTouches.length; i += 1) {
202
- this.game.input.stopPointer(event.changedTouches[i]);
217
+ const changed = event.changedTouches ?? [];
218
+ for (let i = 0; i < changed.length; i += 1) {
219
+ this.game.input.stopPointer(changed[i]!);
203
220
  }
204
221
  }
205
222
 
@@ -207,7 +224,7 @@ export class Touch {
207
224
  * TBD.
208
225
  * @param {TouchEvent} event - TBD.
209
226
  */
210
- public eventPreventDefault(event: any) {
227
+ public eventPreventDefault(event: InputEvent) {
211
228
  if (this.preventDefault) {
212
229
  if (typeof event.cancelable !== 'boolean' || event.cancelable) {
213
230
  event.preventDefault();
@@ -0,0 +1,139 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import type { Game } from './game.js';
3
+ import { Loader } from './loader.js';
4
+
5
+ const createGame = (formats: Record<string, boolean> = {}, noAudio = false): Game =>
6
+ ({
7
+ logger: { warn: () => undefined, info: () => undefined, debug: () => undefined },
8
+ config: { maxParallelDownloads: 4 },
9
+ cache: {},
10
+ sound: { noAudio },
11
+ device: { noAudioFormat: false, supportedAudioFormats: formats },
12
+ }) as unknown as Game;
13
+
14
+ const createLoader = (formats: Record<string, boolean> = {}, noAudio = false): Loader =>
15
+ new Loader(createGame(formats, noAudio));
16
+
17
+ describe('Loader', () => {
18
+ describe('getAudioURL', () => {
19
+ it('returns null when the device has no audio', () => {
20
+ expect(createLoader({}, true).getAudioURL(['track.ogg'])).toBeNull();
21
+ });
22
+
23
+ it('picks a plain url whose extension the device can play', () => {
24
+ expect(createLoader({ ogg: true }).getAudioURL(['track.ogg'])).toBe('track.ogg');
25
+ });
26
+
27
+ it('skips an extension the device cannot play', () => {
28
+ expect(createLoader({ ogg: false, mp3: true }).getAudioURL(['track.ogg', 'track.mp3'])).toBe('track.mp3');
29
+ });
30
+
31
+ it('returns null when no candidate is playable', () => {
32
+ expect(createLoader({ ogg: false, mp3: false }).getAudioURL(['track.ogg', 'track.mp3'])).toBeNull();
33
+ });
34
+
35
+ it('accepts a bare string as a single candidate', () => {
36
+ expect(createLoader({ mp3: true }).getAudioURL('track.mp3')).toBe('track.mp3');
37
+ });
38
+
39
+ it('reads the format from a uri and type pair', () => {
40
+ expect(createLoader({ ogg: true }).getAudioURL([{ uri: 'track-no-extension', type: 'ogg' }])).toBe(
41
+ 'track-no-extension'
42
+ );
43
+ });
44
+
45
+ it('skips a pair whose type the device cannot play', () => {
46
+ const loader = createLoader({ ogg: false, mp3: true });
47
+ expect(
48
+ loader.getAudioURL([
49
+ { uri: 'a', type: 'ogg' },
50
+ { uri: 'b', type: 'mp3' },
51
+ ])
52
+ ).toBe('b');
53
+ });
54
+
55
+ it('takes a blob url without checking the format', () => {
56
+ expect(createLoader().getAudioURL(['blob:https://example.test/abc'])).toBe('blob:https://example.test/abc');
57
+ });
58
+
59
+ it('takes a data uri without checking the format', () => {
60
+ expect(createLoader().getAudioURL(['data:audio/mp3;base64,AAAA'])).toBe('data:audio/mp3;base64,AAAA');
61
+ });
62
+
63
+ it('ignores a query string when reading the extension', () => {
64
+ expect(createLoader({ mp3: true }).getAudioURL(['track.mp3?v=2'])).toBe('track.mp3?v=2');
65
+ });
66
+
67
+ it('returns null for an empty candidate list', () => {
68
+ expect(createLoader({ mp3: true }).getAudioURL([])).toBeNull();
69
+ });
70
+ });
71
+
72
+ describe('transformUrl', () => {
73
+ const file = { path: 'assets/' } as Parameters<Loader['transformUrl']>[1];
74
+
75
+ it('returns false for a missing url', () => {
76
+ expect(createLoader().transformUrl(null, file)).toBe(false);
77
+ });
78
+
79
+ it('returns false for an unresolved candidate list', () => {
80
+ expect(createLoader().transformUrl(['a.mp3'], file)).toBe(false);
81
+ });
82
+
83
+ it('passes an absolute url through', () => {
84
+ expect(createLoader().transformUrl('https://example.test/a.png', file)).toBe('https://example.test/a.png');
85
+ });
86
+
87
+ it('passes a protocol relative url through', () => {
88
+ expect(createLoader().transformUrl('//example.test/a.png', file)).toBe('//example.test/a.png');
89
+ });
90
+
91
+ it('passes a data uri through', () => {
92
+ expect(createLoader().transformUrl('data:image/png;base64,AAAA', file)).toBe('data:image/png;base64,AAAA');
93
+ });
94
+
95
+ it('prefixes a relative url with the base url and file path', () => {
96
+ const loader = createLoader();
97
+ loader.baseURL = 'https://cdn.test/';
98
+ expect(loader.transformUrl('a.png', file)).toBe('https://cdn.test/assets/a.png');
99
+ });
100
+ });
101
+
102
+ describe('addToFileList', () => {
103
+ it('records the core fields for a queued file', () => {
104
+ const loader = createLoader();
105
+ loader.image('logo', 'logo.png');
106
+ const asset = loader.getAsset('image', 'logo');
107
+ expect(asset?.file).toMatchObject({
108
+ type: 'image',
109
+ key: 'logo',
110
+ url: 'logo.png',
111
+ loaded: false,
112
+ loading: false,
113
+ error: false,
114
+ });
115
+ });
116
+
117
+ it('folds the per-type extras onto the file', () => {
118
+ const loader = createLoader();
119
+ loader.audio('theme', ['theme.mp3']);
120
+ expect(loader.getAsset('audio', 'theme')?.file).toMatchObject({
121
+ type: 'audio',
122
+ autoDecode: true,
123
+ url: ['theme.mp3'],
124
+ });
125
+ });
126
+
127
+ it('skips a file with no key', () => {
128
+ const loader = createLoader();
129
+ loader.image('', 'logo.png');
130
+ expect(loader.getAsset('image', '')).toBeNull();
131
+ });
132
+
133
+ it('derives the url from the key and extension when none is given', () => {
134
+ const loader = createLoader();
135
+ loader.image('logo');
136
+ expect(loader.getAsset('image', 'logo')?.file.url).toBe('logo.png');
137
+ });
138
+ });
139
+ });