@schukai/monster 4.10.1 → 4.10.3

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