@schukai/monster 4.11.0 → 4.11.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.
@@ -12,24 +12,24 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import { instanceSymbol } from "../../constants.mjs";
16
- import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
17
- import { CustomElement } from "../../dom/customelement.mjs";
15
+ import {instanceSymbol} from "../../constants.mjs";
16
+ import {ATTRIBUTE_ROLE} from "../../dom/constants.mjs";
17
+ import {CustomElement} from "../../dom/customelement.mjs";
18
18
  import {
19
- assembleMethodSymbol,
20
- registerCustomElement,
19
+ assembleMethodSymbol,
20
+ registerCustomElement,
21
21
  } from "../../dom/customelement.mjs";
22
- import { CameraCaptureStyleSheet } from "./stylesheet/camera-capture.mjs";
22
+ import {CameraCaptureStyleSheet} from "./stylesheet/camera-capture.mjs";
23
23
  import "../form/button.mjs";
24
24
  import "../state/state.mjs";
25
- import { getLocaleOfDocument } from "../../dom/locale.mjs";
26
- import { addErrorAttribute } from "../../dom/error.mjs";
27
- import { Queue } from "../../types/queue.mjs";
28
- import { fireCustomEvent } from "../../dom/events.mjs";
25
+ import {getLocaleOfDocument} from "../../dom/locale.mjs";
26
+ import {addErrorAttribute} from "../../dom/error.mjs";
27
+ import {Queue} from "../../types/queue.mjs";
28
+ import {fireCustomEvent} from "../../dom/events.mjs";
29
29
 
30
30
  import "../layout/full-screen.mjs";
31
31
 
32
- export { CameraCapture };
32
+ export {CameraCapture};
33
33
 
34
34
  /**
35
35
  * @private
@@ -86,202 +86,232 @@ const emptyHistoryStateElementSymbol = Symbol("emptyHistoryStateElement");
86
86
  * @fires monster-camera-capture-captured
87
87
  */
88
88
  class CameraCapture extends CustomElement {
89
- /**
90
- * Constructor for the CameraCapture class.
91
- * Calls the parent class constructor.
92
- */
93
- constructor() {
94
- super();
95
-
96
- this[queueSymbol] = new Queue();
97
- }
98
-
99
- /**
100
- * This method is called by the `instanceof` operator.
101
- * @return {symbol}
102
- */
103
- static get [instanceSymbol]() {
104
- return Symbol.for(
105
- "@schukai/monster/components/content/camera-capture@instance",
106
- );
107
- }
108
-
109
- /**
110
- *
111
- * @return {Components.Content.Copy
112
- */
113
- [assembleMethodSymbol]() {
114
- super[assembleMethodSymbol]();
115
- initControlReferences.call(this);
116
- initEventHandler.call(this);
117
- initCameraControl.call(this);
118
- return this;
119
- }
120
-
121
- /**
122
- * To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
123
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
124
- *
125
- * The individual configuration values can be found in the table.
126
- *
127
- * @property {Object} templates Template definitions
128
- * @property {string} templates.main Main template
129
- * @property {Object} actions Callbacks
130
- * @property {string} actions.click="throw Error" Callback when clicked
131
- * @property {Object} features Features
132
- * @property {boolean} features.stripTags=true Strip tags from the copied text
133
- * @property {boolean} features.preventOpenEventSent=false Prevent open event from being sent
134
- * @property {Object} popper Popper configuration
135
- * @property {string} popper.placement="top" Popper placement
136
- * @property {string[]} popper.middleware=["autoPlacement", "shift", "offset:15", "arrow"] Popper middleware
137
- * @property {boolean} disabled=false Disabled state
138
- */
139
- get defaults() {
140
- return Object.assign({}, super.defaults, {
141
- templates: {
142
- main: getTemplate(),
143
- },
144
-
145
- disabled: false,
146
- features: {},
147
-
148
- labels: getTranslations(),
149
- });
150
- }
151
-
152
- /**
153
- * @return {string}
154
- */
155
- static getTag() {
156
- return "monster-camera-capture";
157
- }
158
-
159
- /**
160
- * @return {CSSStyleSheet[]}
161
- */
162
- static getCSSStyleSheet() {
163
- return [CameraCaptureStyleSheet];
164
- }
165
-
166
- /**
167
- * Retrieve the next image from the queue.
168
- * If the queue is empty, it returns `null`.
169
- * @returns {string|null}
170
- */
171
- getNextImage() {
172
- if (!this[queueSymbol].isEmpty()) {
173
- const next = this[queueSymbol].poll();
174
- if (!next) {
175
- return null;
176
- }
177
- return next;
178
- }
179
- return null;
180
- }
181
-
182
- /**
183
- * Capture an image from the camera and add it to the queue.
184
- * The image is returned as a data URL.
185
- * @returns {string}
186
- */
187
- capture() {
188
- this[canvasElementSymbol].width = this[videoElementSymbol].videoWidth;
189
- this[canvasElementSymbol].height = this[videoElementSymbol].videoHeight;
190
- const ctx = this[canvasElementSymbol].getContext("2d");
191
- ctx.drawImage(
192
- this[videoElementSymbol],
193
- 0,
194
- 0,
195
- this[canvasElementSymbol].width,
196
- this[canvasElementSymbol].height,
197
- );
198
- const dataURL = this[canvasElementSymbol].toDataURL("image/png");
199
- this[queueSymbol].add(dataURL);
200
- return dataURL;
201
- }
89
+ /**
90
+ * Constructor for the CameraCapture class.
91
+ * Calls the parent class constructor.
92
+ */
93
+ constructor() {
94
+ super();
95
+
96
+ this[queueSymbol] = new Queue();
97
+ }
98
+
99
+ /**
100
+ * This method is called by the `instanceof` operator.
101
+ * @return {symbol}
102
+ */
103
+ static get [instanceSymbol]() {
104
+ return Symbol.for(
105
+ "@schukai/monster/components/content/camera-capture@instance",
106
+ );
107
+ }
108
+
109
+ /**
110
+ *
111
+ * @return {Components.Content.Copy
112
+ */
113
+ [assembleMethodSymbol]() {
114
+ super[assembleMethodSymbol]();
115
+ initControlReferences.call(this);
116
+ initEventHandler.call(this);
117
+ setupLazyCameraInit.call(this);
118
+ return this;
119
+ }
120
+
121
+ /**
122
+ * To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
123
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
124
+ *
125
+ * The individual configuration values can be found in the table.
126
+ *
127
+ * @property {Object} templates Template definitions
128
+ * @property {string} templates.main Main template
129
+ * @property {Object} actions Callbacks
130
+ * @property {string} actions.click="throw Error" Callback when clicked
131
+ * @property {Object} features Features
132
+ * @property {boolean} features.stripTags=true Strip tags from the copied text
133
+ * @property {boolean} features.preventOpenEventSent=false Prevent open event from being sent
134
+ * @property {Object} popper Popper configuration
135
+ * @property {string} popper.placement="top" Popper placement
136
+ * @property {string[]} popper.middleware=["autoPlacement", "shift", "offset:15", "arrow"] Popper middleware
137
+ * @property {boolean} disabled=false Disabled state
138
+ */
139
+ get defaults() {
140
+ return Object.assign({}, super.defaults, {
141
+ templates: {
142
+ main: getTemplate(),
143
+ },
144
+
145
+ disabled: false,
146
+ features: {},
147
+
148
+ labels: getTranslations(),
149
+ });
150
+ }
151
+
152
+ /**
153
+ * @return {string}
154
+ */
155
+ static getTag() {
156
+ return "monster-camera-capture";
157
+ }
158
+
159
+ /**
160
+ * @return {CSSStyleSheet[]}
161
+ */
162
+ static getCSSStyleSheet() {
163
+ return [CameraCaptureStyleSheet];
164
+ }
165
+
166
+ /**
167
+ * Retrieve the next image from the queue.
168
+ * If the queue is empty, it returns `null`.
169
+ * @returns {string|null}
170
+ */
171
+ getNextImage() {
172
+ if (!this[queueSymbol].isEmpty()) {
173
+ const next = this[queueSymbol].poll();
174
+ if (!next) {
175
+ return null;
176
+ }
177
+ return next;
178
+ }
179
+ return null;
180
+ }
181
+
182
+ /**
183
+ * Capture an image from the camera and add it to the queue.
184
+ * The image is returned as a data URL.
185
+ * @returns {string}
186
+ */
187
+ capture() {
188
+ this[canvasElementSymbol].width = this[videoElementSymbol].videoWidth;
189
+ this[canvasElementSymbol].height = this[videoElementSymbol].videoHeight;
190
+ const ctx = this[canvasElementSymbol].getContext("2d");
191
+ ctx.drawImage(
192
+ this[videoElementSymbol],
193
+ 0,
194
+ 0,
195
+ this[canvasElementSymbol].width,
196
+ this[canvasElementSymbol].height,
197
+ );
198
+ const dataURL = this[canvasElementSymbol].toDataURL("image/png");
199
+ this[queueSymbol].add(dataURL);
200
+ return dataURL;
201
+ }
202
202
  }
203
203
 
204
204
  /**
205
205
  * @private
206
206
  */
207
- function initCameraControl() {
208
- const self = this;
209
-
210
- if (
211
- !navigator ||
212
- !navigator.mediaDevices ||
213
- !navigator.mediaDevices.getUserMedia
214
- ) {
215
- self[fullScreenElementSymbol].style.display = "none";
216
- addErrorAttribute(self, "Browser not supported");
217
- return;
218
- }
219
-
220
- navigator.mediaDevices
221
- .getUserMedia({ video: true })
222
- .then((stream) => {
223
- stream.getTracks().forEach((track) => track.stop());
224
- return navigator.mediaDevices.enumerateDevices();
225
- })
226
- .then((devices) => {
227
- const cameras = devices.filter((device) => device.kind === "videoinput");
228
-
229
- if (cameras.length === 0) {
230
- addErrorAttribute(self, getTranslations().cameraNotSupportedOrNotAllowed);
231
- return;
232
- }
233
-
234
- if (cameras.length > 0) {
235
- const select = document.createElement("select");
236
- select.setAttribute("data-monster-role", "cameraSelector");
237
- select.style.marginBottom = "0.5rem";
238
- select.style.width = "100%";
239
- select.style.maxWidth = "100%";
240
- select.style.height = "1.4rem";
241
- select.style.marginTop = "0";
242
- select.style.marginBottom = "0";
243
-
244
- cameras.forEach((camera, index) => {
245
- const option = document.createElement("option");
246
- option.value = camera.deviceId;
247
- option.text = camera.label || `Camera ${index + 1}`;
248
- select.appendChild(option);
249
- });
250
-
251
- select.addEventListener("change", () => {
252
- startCameraWithDeviceId.call(self, select.value);
253
- });
254
-
255
- self[fullScreenElementSymbol].style.top = "2rem";
256
- self[controlElementSymbol].insertBefore(select, self[videoElementSymbol]);
257
- }
258
-
259
- startCameraWithDeviceId.call(self, cameras[0].deviceId);
260
- })
261
- .catch((err) => {
262
- self[fullScreenElementSymbol].style.display = "none";
263
- addErrorAttribute(self, err);
264
- });
207
+ function setupLazyCameraInit() {
208
+ const self = this;
209
+
210
+ let initialized = false;
211
+
212
+ const observer = new IntersectionObserver((entries) => {
213
+ for (const entry of entries) {
214
+ if (entry.isIntersecting && !initialized) {
215
+ initialized = true;
216
+ observer.disconnect();
217
+ initCameraControl.call(self);
218
+ }
219
+ }
220
+ }, {
221
+ root: null,
222
+ threshold: 0.1,
223
+ });
224
+
225
+ observer.observe(this);
265
226
  }
266
227
 
267
228
 
229
+ /**
230
+ * @private
231
+ */
232
+ function initCameraControl() {
233
+ const self = this;
234
+
235
+ if (
236
+ !navigator ||
237
+ !navigator.mediaDevices ||
238
+ !navigator.mediaDevices.getUserMedia
239
+ ) {
240
+ self[fullScreenElementSymbol].style.display = "none";
241
+ addErrorAttribute(self, "Browser not supported");
242
+ return;
243
+ }
244
+
245
+ navigator.mediaDevices
246
+ .getUserMedia({video: true})
247
+ .then((stream) => {
248
+ stream.getTracks().forEach((track) => track.stop());
249
+ return navigator.mediaDevices.enumerateDevices();
250
+ })
251
+ .then((devices) => {
252
+ const cameras = devices.filter((device) => device.kind === "videoinput");
253
+
254
+ if (cameras.length === 0) {
255
+ addErrorAttribute(
256
+ self,
257
+ getTranslations().cameraNotSupportedOrNotAllowed,
258
+ );
259
+ return;
260
+ }
261
+
262
+ if (cameras.length > 0) {
263
+ const select = document.createElement("select");
264
+ select.setAttribute("data-monster-role", "cameraSelector");
265
+ select.style.marginBottom = "0.5rem";
266
+ select.style.width = "100%";
267
+ select.style.maxWidth = "100%";
268
+ select.style.height = "1.4rem";
269
+ select.style.marginTop = "0";
270
+ select.style.marginBottom = "0";
271
+
272
+ cameras.forEach((camera, index) => {
273
+ const option = document.createElement("option");
274
+ option.value = camera.deviceId;
275
+ option.text = camera.label || `Camera ${index + 1}`;
276
+ select.appendChild(option);
277
+ });
278
+
279
+ select.addEventListener("change", () => {
280
+ startCameraWithDeviceId.call(self, select.value);
281
+ });
282
+
283
+ self[fullScreenElementSymbol].style.top = "2rem";
284
+ self[controlElementSymbol].insertBefore(
285
+ select,
286
+ self[videoElementSymbol],
287
+ );
288
+ }
289
+
290
+ startCameraWithDeviceId.call(self, cameras[0].deviceId);
291
+ })
292
+ .catch((err) => {
293
+ self[fullScreenElementSymbol].style.display = "none";
294
+ addErrorAttribute(self, err);
295
+ });
296
+ }
297
+
268
298
  function startCameraWithDeviceId(deviceId) {
269
- const self = this;
270
- navigator.mediaDevices
271
- .getUserMedia({ video: { deviceId: { exact: deviceId } } })
272
- .then(function (stream) {
273
- self[takePictureButtonElementSymbol].style.display = "block";
274
- self[videoElementSymbol].style.display = "block";
275
- self[emptyHistoryStateElementSymbol].style.display = "none";
276
-
277
- self[videoElementSymbol].srcObject = stream;
278
-
279
- self[fullScreenElementSymbol].style.display = "block";
280
- })
281
- .catch(function (e) {
282
- self[fullScreenElementSymbol].style.display = "none";
283
- addErrorAttribute(self, e);
284
- });
299
+ const self = this;
300
+ navigator.mediaDevices
301
+ .getUserMedia({video: {deviceId: {exact: deviceId}}})
302
+ .then(function (stream) {
303
+ self[takePictureButtonElementSymbol].style.display = "block";
304
+ self[videoElementSymbol].style.display = "block";
305
+ self[emptyHistoryStateElementSymbol].style.display = "none";
306
+
307
+ self[videoElementSymbol].srcObject = stream;
308
+
309
+ self[fullScreenElementSymbol].style.display = "block";
310
+ })
311
+ .catch(function (e) {
312
+ self[fullScreenElementSymbol].style.display = "none";
313
+ addErrorAttribute(self, e);
314
+ });
285
315
  }
286
316
 
287
317
  /**
@@ -289,147 +319,147 @@ function startCameraWithDeviceId(deviceId) {
289
319
  * @returns {{takePicture: string}}
290
320
  */
291
321
  function getTranslations() {
292
- const locale = getLocaleOfDocument();
293
- switch (locale.language) {
294
- case "de":
295
- return {
296
- takePicture: "Bild aufnehmen",
297
- cameraNotSupportedOrNotAllowed:
298
- "Die Kamera wird nicht unterstützt oder die Berechtigung wurde nicht erteilt.",
299
- };
300
-
301
- case "es":
302
- return {
303
- takePicture: "Tomar una foto",
304
- cameraNotSupportedOrNotAllowed:
305
- "La cámara no es compatible o no se ha otorgado permiso.",
306
- };
307
-
308
- case "zh":
309
- return {
310
- takePicture: "拍照",
311
- cameraNotSupportedOrNotAllowed: "相机不受支持或未授予权限。",
312
- };
313
-
314
- case "hi":
315
- return {
316
- takePicture: "तस्वीर खींचें",
317
- cameraNotSupportedOrNotAllowed:
318
- "कैमरा समर्थित नहीं है या अनुमति नहीं दी गई है।",
319
- };
320
-
321
- case "bn":
322
- return {
323
- takePicture: "ছবি তুলুন",
324
- cameraNotSupportedOrNotAllowed: "ক্যামেরা সমর্থিত নয় বা অনুমতি দেয়া হয়নি।",
325
- };
326
-
327
- case "pt":
328
- return {
329
- takePicture: "Tirar uma foto",
330
- cameraNotSupportedOrNotAllowed:
331
- "A câmera não é suportada ou a permissão não foi concedida.",
332
- };
333
-
334
- case "ru":
335
- return {
336
- takePicture: "Сделать фото",
337
- cameraNotSupportedOrNotAllowed:
338
- "Камера не поддерживается или разрешение не предоставлено.",
339
- };
340
-
341
- case "ja":
342
- return {
343
- takePicture: "写真を撮る",
344
- cameraNotSupportedOrNotAllowed:
345
- "カメラがサポートされていないか、許可が付与されていません。",
346
- };
347
-
348
- case "pa":
349
- return {
350
- takePicture: "ਤਸਵੀਰ ਖਿੱਚੋ",
351
- cameraNotSupportedOrNotAllowed:
352
- "ਕੈਮਰਾ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਹੈ ਜਾਂ ਅਨੁਮਤੀ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ।",
353
- };
354
-
355
- case "mr":
356
- return {
357
- takePicture: "फोटो घ्या",
358
- cameraNotSupportedOrNotAllowed:
359
- "कॅमेरा समर्थित नाही किंवा परवानगी दिलेली नाही.",
360
- };
361
-
362
- case "fr":
363
- return {
364
- takePicture: "Prendre une photo",
365
- cameraNotSupportedOrNotAllowed:
366
- "La caméra n'est pas prise en charge ou l'autorisation n'a pas été accordée.",
367
- };
368
-
369
- case "it":
370
- return {
371
- takePicture: "Scattare una foto",
372
- cameraNotSupportedOrNotAllowed:
373
- "La fotocamera non è supportata o l'autorizzazione non è stata concessa.",
374
- };
375
-
376
- case "nl":
377
- return {
378
- takePicture: "Maak een foto",
379
- cameraNotSupportedOrNotAllowed:
380
- "De camera wordt niet ondersteund of er is geen toestemming verleend.",
381
- };
382
-
383
- case "sv":
384
- return {
385
- takePicture: "Ta ett foto",
386
- cameraNotSupportedOrNotAllowed:
387
- "Kameran stöds inte eller tillståndet har inte beviljats.",
388
- };
389
-
390
- case "pl":
391
- return {
392
- takePicture: "Zrób zdjęcie",
393
- cameraNotSupportedOrNotAllowed:
394
- "Kamera nie jest obsługiwana lub nie udzielono zgody.",
395
- };
396
-
397
- case "da":
398
- return {
399
- takePicture: "Tag et billede",
400
- cameraNotSupportedOrNotAllowed:
401
- "Kameraen understøttes ikke eller tilladelsen er ikke givet.",
402
- };
403
-
404
- case "fi":
405
- return {
406
- takePicture: "Ota kuva",
407
- cameraNotSupportedOrNotAllowed:
408
- "Kameraa ei tueta tai lupaa ei ole myönnetty.",
409
- };
410
-
411
- case "no":
412
- return {
413
- takePicture: "Ta et bilde",
414
- cameraNotSupportedOrNotAllowed:
415
- "Kameraen støttes ikke eller tillatelsen er ikke gitt.",
416
- };
417
-
418
- case "cs":
419
- return {
420
- takePicture: "Vyfotit",
421
- cameraNotSupportedOrNotAllowed:
422
- "Fotoaparát není podporován nebo povolení nebylo uděleno.",
423
- };
424
-
425
- case "en":
426
- default:
427
- return {
428
- takePicture: "Take a picture",
429
- cameraNotSupportedOrNotAllowed:
430
- "The camera is not supported or permission has not been granted.",
431
- };
432
- }
322
+ const locale = getLocaleOfDocument();
323
+ switch (locale.language) {
324
+ case "de":
325
+ return {
326
+ takePicture: "Bild aufnehmen",
327
+ cameraNotSupportedOrNotAllowed:
328
+ "Die Kamera wird nicht unterstützt oder die Berechtigung wurde nicht erteilt.",
329
+ };
330
+
331
+ case "es":
332
+ return {
333
+ takePicture: "Tomar una foto",
334
+ cameraNotSupportedOrNotAllowed:
335
+ "La cámara no es compatible o no se ha otorgado permiso.",
336
+ };
337
+
338
+ case "zh":
339
+ return {
340
+ takePicture: "拍照",
341
+ cameraNotSupportedOrNotAllowed: "相机不受支持或未授予权限。",
342
+ };
343
+
344
+ case "hi":
345
+ return {
346
+ takePicture: "तस्वीर खींचें",
347
+ cameraNotSupportedOrNotAllowed:
348
+ "कैमरा समर्थित नहीं है या अनुमति नहीं दी गई है।",
349
+ };
350
+
351
+ case "bn":
352
+ return {
353
+ takePicture: "ছবি তুলুন",
354
+ cameraNotSupportedOrNotAllowed: "ক্যামেরা সমর্থিত নয় বা অনুমতি দেয়া হয়নি।",
355
+ };
356
+
357
+ case "pt":
358
+ return {
359
+ takePicture: "Tirar uma foto",
360
+ cameraNotSupportedOrNotAllowed:
361
+ "A câmera não é suportada ou a permissão não foi concedida.",
362
+ };
363
+
364
+ case "ru":
365
+ return {
366
+ takePicture: "Сделать фото",
367
+ cameraNotSupportedOrNotAllowed:
368
+ "Камера не поддерживается или разрешение не предоставлено.",
369
+ };
370
+
371
+ case "ja":
372
+ return {
373
+ takePicture: "写真を撮る",
374
+ cameraNotSupportedOrNotAllowed:
375
+ "カメラがサポートされていないか、許可が付与されていません。",
376
+ };
377
+
378
+ case "pa":
379
+ return {
380
+ takePicture: "ਤਸਵੀਰ ਖਿੱਚੋ",
381
+ cameraNotSupportedOrNotAllowed:
382
+ "ਕੈਮਰਾ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਹੈ ਜਾਂ ਅਨੁਮਤੀ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ।",
383
+ };
384
+
385
+ case "mr":
386
+ return {
387
+ takePicture: "फोटो घ्या",
388
+ cameraNotSupportedOrNotAllowed:
389
+ "कॅमेरा समर्थित नाही किंवा परवानगी दिलेली नाही.",
390
+ };
391
+
392
+ case "fr":
393
+ return {
394
+ takePicture: "Prendre une photo",
395
+ cameraNotSupportedOrNotAllowed:
396
+ "La caméra n'est pas prise en charge ou l'autorisation n'a pas été accordée.",
397
+ };
398
+
399
+ case "it":
400
+ return {
401
+ takePicture: "Scattare una foto",
402
+ cameraNotSupportedOrNotAllowed:
403
+ "La fotocamera non è supportata o l'autorizzazione non è stata concessa.",
404
+ };
405
+
406
+ case "nl":
407
+ return {
408
+ takePicture: "Maak een foto",
409
+ cameraNotSupportedOrNotAllowed:
410
+ "De camera wordt niet ondersteund of er is geen toestemming verleend.",
411
+ };
412
+
413
+ case "sv":
414
+ return {
415
+ takePicture: "Ta ett foto",
416
+ cameraNotSupportedOrNotAllowed:
417
+ "Kameran stöds inte eller tillståndet har inte beviljats.",
418
+ };
419
+
420
+ case "pl":
421
+ return {
422
+ takePicture: "Zrób zdjęcie",
423
+ cameraNotSupportedOrNotAllowed:
424
+ "Kamera nie jest obsługiwana lub nie udzielono zgody.",
425
+ };
426
+
427
+ case "da":
428
+ return {
429
+ takePicture: "Tag et billede",
430
+ cameraNotSupportedOrNotAllowed:
431
+ "Kameraen understøttes ikke eller tilladelsen er ikke givet.",
432
+ };
433
+
434
+ case "fi":
435
+ return {
436
+ takePicture: "Ota kuva",
437
+ cameraNotSupportedOrNotAllowed:
438
+ "Kameraa ei tueta tai lupaa ei ole myönnetty.",
439
+ };
440
+
441
+ case "no":
442
+ return {
443
+ takePicture: "Ta et bilde",
444
+ cameraNotSupportedOrNotAllowed:
445
+ "Kameraen støttes ikke eller tillatelsen er ikke gitt.",
446
+ };
447
+
448
+ case "cs":
449
+ return {
450
+ takePicture: "Vyfotit",
451
+ cameraNotSupportedOrNotAllowed:
452
+ "Fotoaparát není podporován nebo povolení nebylo uděleno.",
453
+ };
454
+
455
+ case "en":
456
+ default:
457
+ return {
458
+ takePicture: "Take a picture",
459
+ cameraNotSupportedOrNotAllowed:
460
+ "The camera is not supported or permission has not been granted.",
461
+ };
462
+ }
433
463
  }
434
464
 
435
465
  /**
@@ -438,17 +468,17 @@ function getTranslations() {
438
468
  * @fires monster-camera-capture-captured
439
469
  */
440
470
  function initEventHandler() {
441
- const self = this;
471
+ const self = this;
442
472
 
443
- this[takePictureButtonElementSymbol].setOption("actions.click", function () {
444
- self.capture();
473
+ this[takePictureButtonElementSymbol].setOption("actions.click", function () {
474
+ self.capture();
445
475
 
446
- fireCustomEvent(self, "monster-camera-capture-captured", {
447
- element: self,
448
- });
449
- });
476
+ fireCustomEvent(self, "monster-camera-capture-captured", {
477
+ element: self,
478
+ });
479
+ });
450
480
 
451
- return this;
481
+ return this;
452
482
  }
453
483
 
454
484
  /**
@@ -456,25 +486,25 @@ function initEventHandler() {
456
486
  * @return {void}
457
487
  */
458
488
  function initControlReferences() {
459
- this[controlElementSymbol] = this.shadowRoot.querySelector(
460
- `[${ATTRIBUTE_ROLE}="control"]`,
461
- );
489
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
490
+ `[${ATTRIBUTE_ROLE}="control"]`,
491
+ );
462
492
 
463
- this[takePictureButtonElementSymbol] = this.shadowRoot.querySelector(
464
- `[data-monster-role="takePicture"]`,
465
- );
493
+ this[takePictureButtonElementSymbol] = this.shadowRoot.querySelector(
494
+ `[data-monster-role="takePicture"]`,
495
+ );
466
496
 
467
- this[videoElementSymbol] = this.shadowRoot.querySelector(`video`);
497
+ this[videoElementSymbol] = this.shadowRoot.querySelector(`video`);
468
498
 
469
- this[canvasElementSymbol] = this.shadowRoot.querySelector(`canvas`);
499
+ this[canvasElementSymbol] = this.shadowRoot.querySelector(`canvas`);
470
500
 
471
- this[emptyHistoryStateElementSymbol] = this.shadowRoot.querySelector(
472
- `[data-monster-role="emptyHistoryState"]`,
473
- );
501
+ this[emptyHistoryStateElementSymbol] = this.shadowRoot.querySelector(
502
+ `[data-monster-role="emptyHistoryState"]`,
503
+ );
474
504
 
475
- this[fullScreenElementSymbol] = this.shadowRoot.querySelector(
476
- `[data-monster-role="full-screen"]`,
477
- );
505
+ this[fullScreenElementSymbol] = this.shadowRoot.querySelector(
506
+ `[data-monster-role="full-screen"]`,
507
+ );
478
508
  }
479
509
 
480
510
  /**
@@ -482,10 +512,11 @@ function initControlReferences() {
482
512
  * @return {string}
483
513
  */
484
514
  function getTemplate() {
485
- // language=HTML
486
- return `
515
+ // language=HTML
516
+ return `
487
517
  <div data-monster-role="control" part="control">
488
- <monster-full-screen part="full-screen" style="display: none" data-monster-role="full-screen" data-monster-option-selector="[data-monster-role=control]"></monster-full-screen>
518
+ <monster-full-screen part="full-screen" style="display: none" data-monster-role="full-screen"
519
+ data-monster-option-selector="[data-monster-role=control]"></monster-full-screen>
489
520
  <monster-state data-monster-role="emptyHistoryState">
490
521
  <svg slot="visual" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
491
522
  width="350"
@@ -514,10 +545,10 @@ function getTemplate() {
514
545
  </g>
515
546
  </svg>
516
547
 
517
- <p class="camera-not-supported-text" data-monster-replace="path:labels.cameraNotSupportedOrNotAllowed | default:there was an error:string"></p>
548
+ <p class="camera-not-supported-text"
549
+ data-monster-replace="path:labels.cameraNotSupportedOrNotAllowed | default:there was an error:string"></p>
518
550
  </monster-state>
519
551
 
520
-
521
552
 
522
553
  <video autoplay style="display:none"></video>
523
554
  <canvas style="display:none;"></canvas>