@smileid/web-components 11.4.4 → 11.5.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.
- package/dist/esm/{DocumentCaptureScreens-bLFW-yEM.js → DocumentCaptureScreens-ucJDu5nH.js} +555 -2470
- package/dist/esm/DocumentCaptureScreens-ucJDu5nH.js.map +1 -0
- package/dist/esm/{EndUserConsent-D26UoVk5.js → EndUserConsent-CsiwoThZ.js} +3 -3
- package/dist/esm/{EndUserConsent-D26UoVk5.js.map → EndUserConsent-CsiwoThZ.js.map} +1 -1
- package/dist/esm/{Navigation-nvehze1F.js → Navigation-Xg565kcu.js} +28 -22
- package/dist/esm/Navigation-Xg565kcu.js.map +1 -0
- package/dist/esm/SelfieCaptureScreens-D3KuMzZA.js +11471 -0
- package/dist/esm/SelfieCaptureScreens-D3KuMzZA.js.map +1 -0
- package/dist/esm/{TotpConsent-owUOdKzP.js → TotpConsent-CRtmtudl.js} +2 -2
- package/dist/esm/{TotpConsent-owUOdKzP.js.map → TotpConsent-CRtmtudl.js.map} +1 -1
- package/dist/esm/combobox.js +1 -1
- package/dist/esm/document.js +1 -1
- package/dist/esm/end-user-consent.js +1 -1
- package/dist/esm/index-CUwa6MPI.js +1363 -0
- package/dist/esm/{index-5Nn2kzHI.js.map → index-CUwa6MPI.js.map} +1 -1
- package/dist/esm/localisation.js +1 -1
- package/dist/esm/main.js +6 -6
- package/dist/esm/navigation.js +1 -1
- package/dist/esm/package-BmVbDNny.js +2535 -0
- package/dist/esm/package-BmVbDNny.js.map +1 -0
- package/dist/esm/selfie.js +1 -1
- package/dist/esm/smart-camera-web.js +67 -40
- package/dist/esm/smart-camera-web.js.map +1 -1
- package/dist/esm/totp-consent.js +1 -1
- package/dist/smart-camera-web.js +877 -122
- package/dist/smart-camera-web.js.map +1 -1
- package/dist/types/main.d.ts +13 -0
- package/lib/components/navigation/src/Navigation.js +27 -8
- package/lib/components/selfie/src/SelfieCaptureScreens.js +139 -8
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieCapture.tsx +684 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieConsent.tsx +71 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieSubmission.tsx +181 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/OvalProgress.tsx +87 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/Icon.svg +8 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/accessories.svg +77 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/active_liveness_animation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/device.svg +12 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/device_orientation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/good.svg +52 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/id-card.svg +9 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/illustrations.tsx +852 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/instructions-img.svg +3 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/multiple-faces.svg +69 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/person.svg +6 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/phone.svg +8 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/poor-lighting.svg +53 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/too_dark_animation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/ActiveLivenessOverlay.tsx +226 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/AlertDisplay.tsx +38 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/BackNavigation.tsx +45 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CameraPreview.tsx +96 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CaptureControls.tsx +97 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CaptureGuidelines.tsx +374 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/ConsentView.tsx +460 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/SubmissionView.tsx +426 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/index.ts +3 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/constants.ts +23 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/index.ts +2 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/useCamera.ts +238 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/useFaceCapture.ts +1075 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/index.ts +1 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/alertMessages.ts +20 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/canvas.ts +108 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/faceDetection.ts +545 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/imageCapture.ts +66 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/imageQuality.ts +151 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/index.ts +5 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/mediapipeManager.ts +215 -0
- package/lib/components/selfie/src/selfie-capture-wrapper/SelfieCaptureWrapper.tsx +163 -17
- package/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx +2 -2
- package/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts +15 -7
- package/lib/components/selfie/src/smartselfie-capture/utils/canvas.ts +4 -6
- package/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts +145 -9
- package/lib/components/signature-pad/package.json +1 -1
- package/lib/components/smart-camera-web/src/SmartCameraWeb.js +70 -11
- package/lib/domain/localisation/index.js +2 -2
- package/package.json +3 -3
- package/dist/esm/DocumentCaptureScreens-bLFW-yEM.js.map +0 -1
- package/dist/esm/Navigation-nvehze1F.js.map +0 -1
- package/dist/esm/SelfieCaptureScreens-BXIs6_tl.js +0 -7522
- package/dist/esm/SelfieCaptureScreens-BXIs6_tl.js.map +0 -1
- package/dist/esm/index-5Nn2kzHI.js +0 -1360
- package/dist/esm/package-DmH-I6GW.js +0 -565
- package/dist/esm/package-DmH-I6GW.js.map +0 -1
package/dist/types/main.d.ts
CHANGED
|
@@ -194,6 +194,7 @@ export declare class Navigation extends HTMLElement {
|
|
|
194
194
|
handleBack(): void;
|
|
195
195
|
handleClose(): void;
|
|
196
196
|
get showBackButton(): boolean;
|
|
197
|
+
get showCloseButton(): boolean;
|
|
197
198
|
get themeColor(): string;
|
|
198
199
|
get hasThemeColor(): string | undefined;
|
|
199
200
|
}
|
|
@@ -242,8 +243,10 @@ export declare class SelfieCaptureScreens extends HTMLElement {
|
|
|
242
243
|
}[] | null | undefined;
|
|
243
244
|
setUpEventListeners(): void;
|
|
244
245
|
forceWrapperRemount(): Promise<any>;
|
|
246
|
+
restartSelfieCapture(): void;
|
|
245
247
|
setActiveScreen(screen: any): void;
|
|
246
248
|
setupSelfieWrapperEventListeners(): void;
|
|
249
|
+
_selfieWrapperPublishHandler: ((event: any) => Promise<void>) | undefined;
|
|
247
250
|
_publishSelectedImages(): void;
|
|
248
251
|
get hideInstructions(): boolean;
|
|
249
252
|
get hideAttribution(): "" | "hide-attribution=\"\"";
|
|
@@ -255,6 +258,10 @@ export declare class SelfieCaptureScreens extends HTMLElement {
|
|
|
255
258
|
get hideBack(): "" | "hide-back=\"\"";
|
|
256
259
|
get disableImageTests(): "" | "disable-image-tests=\"\"";
|
|
257
260
|
get allowLegacySelfieFallback(): string;
|
|
261
|
+
get useStrictMode(): "" | "use-strict-mode=\"true\"";
|
|
262
|
+
get showBackOnGuidelines(): "" | "show-back-on-guidelines=\"true\"";
|
|
263
|
+
/** Boolean form of `use-strict-mode` for runtime checks. */
|
|
264
|
+
get isStrictMode(): boolean;
|
|
258
265
|
get themeColor(): string;
|
|
259
266
|
handleBackEvents(): void;
|
|
260
267
|
handleCloseEvent(): void;
|
|
@@ -333,6 +340,7 @@ export declare class SmartCameraWeb extends HTMLElement {
|
|
|
333
340
|
get hideBackOfId(): "" | "hide-back-of-id";
|
|
334
341
|
get newInstructions(): "" | "new-instructions";
|
|
335
342
|
get showNavigation(): "" | "show-navigation";
|
|
343
|
+
get showBackOnGuidelines(): "" | "show-back-on-guidelines";
|
|
336
344
|
get hideBackToHost(): "" | "hide-back";
|
|
337
345
|
get allowAgentMode(): string;
|
|
338
346
|
get allowAgentModeTests(): "" | "show-agent-mode-for-tests";
|
|
@@ -340,7 +348,12 @@ export declare class SmartCameraWeb extends HTMLElement {
|
|
|
340
348
|
get documentCaptureModes(): string;
|
|
341
349
|
get disableImageTests(): "" | "disable-image-tests";
|
|
342
350
|
get allowLegacySelfieFallback(): string;
|
|
351
|
+
get useStrictMode(): "" | "use-strict-mode=\"true\"";
|
|
343
352
|
get hideAttribution(): "" | "hide-attribution";
|
|
353
|
+
get hideConsent(): "" | "hide-consent";
|
|
354
|
+
get partnerName(): string;
|
|
355
|
+
get partnerLogo(): string;
|
|
356
|
+
get policyUrl(): string;
|
|
344
357
|
get hasThemeColor(): boolean;
|
|
345
358
|
get themeColor(): string | null;
|
|
346
359
|
get applyComponentThemeColor(): string;
|
|
@@ -12,12 +12,19 @@ class Navigation extends HTMLElement {
|
|
|
12
12
|
const iconColor = this.hasThemeColor ? this.themeColor : '#FFFFFF';
|
|
13
13
|
const focusColor = '#FFFFFF';
|
|
14
14
|
|
|
15
|
+
let justifyContent = 'flex-end';
|
|
16
|
+
if (this.showBackButton && this.showCloseButton) {
|
|
17
|
+
justifyContent = 'space-between';
|
|
18
|
+
} else if (this.showBackButton) {
|
|
19
|
+
justifyContent = 'flex-start';
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
const style = document.createElement('style');
|
|
16
23
|
style.textContent = `
|
|
17
24
|
:host {
|
|
18
25
|
display: flex;
|
|
19
26
|
max-inline-size: 100%;
|
|
20
|
-
justify-content: ${
|
|
27
|
+
justify-content: ${justifyContent};
|
|
21
28
|
direction: ${direction};
|
|
22
29
|
padding: var(--smileid-navigation-padding, ${hostPadding});
|
|
23
30
|
gap: 1rem;
|
|
@@ -135,23 +142,31 @@ button svg {
|
|
|
135
142
|
|
|
136
143
|
shadow.appendChild(style);
|
|
137
144
|
if (this.showBackButton) shadow.appendChild(backButton);
|
|
138
|
-
shadow.appendChild(closeButton);
|
|
145
|
+
if (this.showCloseButton) shadow.appendChild(closeButton);
|
|
139
146
|
|
|
140
147
|
// Set language direction attribute on host for CSS selectors
|
|
141
148
|
this.setAttribute('dir', direction);
|
|
142
149
|
|
|
143
150
|
// Back Button Controls
|
|
144
|
-
this.
|
|
145
|
-
|
|
151
|
+
if (this.showBackButton) {
|
|
152
|
+
this.backButton = backButton;
|
|
153
|
+
this.backButton.addEventListener('click', () => this.handleBack());
|
|
154
|
+
}
|
|
146
155
|
|
|
147
156
|
// Close Button Controls
|
|
148
|
-
this.
|
|
149
|
-
|
|
157
|
+
if (this.showCloseButton) {
|
|
158
|
+
this.closeButton = closeButton;
|
|
159
|
+
this.closeButton.addEventListener('click', () => this.handleClose());
|
|
160
|
+
}
|
|
150
161
|
}
|
|
151
162
|
|
|
152
163
|
disconnectedCallback() {
|
|
153
|
-
this.backButton
|
|
154
|
-
|
|
164
|
+
if (this.backButton) {
|
|
165
|
+
this.backButton.removeEventListener('click', () => this.handleBack());
|
|
166
|
+
}
|
|
167
|
+
if (this.closeButton) {
|
|
168
|
+
this.closeButton.removeEventListener('click', () => this.handleClose());
|
|
169
|
+
}
|
|
155
170
|
}
|
|
156
171
|
|
|
157
172
|
handleBack() {
|
|
@@ -166,6 +181,10 @@ button svg {
|
|
|
166
181
|
return !this.hasAttribute('hide-back');
|
|
167
182
|
}
|
|
168
183
|
|
|
184
|
+
get showCloseButton() {
|
|
185
|
+
return !this.hasAttribute('hide-close');
|
|
186
|
+
}
|
|
187
|
+
|
|
169
188
|
get themeColor() {
|
|
170
189
|
return this.getAttribute('theme-color') || '#001096';
|
|
171
190
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import './selfie-capture-instructions';
|
|
2
2
|
import './selfie-capture-review';
|
|
3
3
|
import './selfie-capture-wrapper/index.ts';
|
|
4
|
+
import { getMediapipeInstance } from './smartselfie-capture/utils/mediapipeManager.ts';
|
|
4
5
|
import SmartCamera from '../../../domain/camera/src/SmartCamera';
|
|
5
6
|
import styles from '../../../styles/src/styles';
|
|
6
7
|
import packageJson from '../../../../package.json';
|
|
@@ -10,6 +11,15 @@ const COMPONENTS_VERSION = packageJson.version;
|
|
|
10
11
|
|
|
11
12
|
const smartCameraWeb = document.querySelector('smart-camera-web');
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Minimum-correct HTML attribute escape. `&` must be replaced first so the
|
|
16
|
+
* subsequent `"` -> `"` substitution isn't double-encoded. Used by every
|
|
17
|
+
* getter that interpolates a partner-supplied value into the `innerHTML`
|
|
18
|
+
* template in `connectedCallback` — without this, a value containing `"`
|
|
19
|
+
* (or `&`) would break out of the attribute and inject markup.
|
|
20
|
+
*/
|
|
21
|
+
const escAttr = (s) => String(s).replace(/&/g, '&').replace(/"/g, '"');
|
|
22
|
+
|
|
13
23
|
const cropImageFromDataUri = (dataUri, cropPercentX = 0, cropPercentY = 0) =>
|
|
14
24
|
new Promise((resolve, reject) => {
|
|
15
25
|
if (!dataUri || typeof dataUri !== 'string') {
|
|
@@ -82,9 +92,9 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
82
92
|
this.innerHTML = `
|
|
83
93
|
${styles(this.themeColor)}
|
|
84
94
|
<div style="height: 100%;">
|
|
85
|
-
<selfie-capture-instructions theme-color=
|
|
86
|
-
<selfie-capture-wrapper theme-color=
|
|
87
|
-
<selfie-capture-review theme-color=
|
|
95
|
+
<selfie-capture-instructions theme-color="${escAttr(this.themeColor)}" ${this.showNavigation} ${this.hideAttribution} ${this.hideBack} hidden></selfie-capture-instructions>
|
|
96
|
+
<selfie-capture-wrapper theme-color="${escAttr(this.themeColor)}" ${this.showNavigation} ${this.allowAgentMode} ${this.allowAgentModeTests} ${this.hideAttribution} ${this.disableImageTests} ${this.allowLegacySelfieFallback} ${this.useStrictMode} ${this.showBackOnGuidelines} key="${this._remountKey}" start-countdown="false" hidden></selfie-capture-wrapper>
|
|
97
|
+
<selfie-capture-review theme-color="${escAttr(this.themeColor)}" ${this.showNavigation} ${this.hideAttribution} hidden></selfie-capture-review>
|
|
88
98
|
</div>
|
|
89
99
|
`;
|
|
90
100
|
|
|
@@ -100,7 +110,11 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
100
110
|
|
|
101
111
|
if (
|
|
102
112
|
this.getAttribute('initial-screen') === 'selfie-capture' ||
|
|
103
|
-
this.hideInstructions
|
|
113
|
+
this.hideInstructions ||
|
|
114
|
+
// In strict mode the modern `enhanced-smartselfie-capture` element
|
|
115
|
+
// renders its own guidelines screen, so we skip the legacy
|
|
116
|
+
// `selfie-capture-instructions` element entirely.
|
|
117
|
+
this.isStrictMode
|
|
104
118
|
) {
|
|
105
119
|
this.setActiveScreen(this.selfieCapture);
|
|
106
120
|
} else {
|
|
@@ -108,6 +122,37 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
108
122
|
}
|
|
109
123
|
|
|
110
124
|
this.setUpEventListeners();
|
|
125
|
+
|
|
126
|
+
// Pre-warm MediaPipe as soon as the selfie flow starts so the heavy WASM +
|
|
127
|
+
// model download (and on-device init) happens while the user reads the
|
|
128
|
+
// instructions — not behind a blocking spinner on the capture screen. This
|
|
129
|
+
// is fire-and-forget and idempotent: getMediapipeInstance() caches a single
|
|
130
|
+
// in-flight promise / instance, so the wrapper (and any remount) reuses the
|
|
131
|
+
// same load instead of starting a new one. Errors are handled by the
|
|
132
|
+
// wrapper's own retry/fallback path, so swallow them here.
|
|
133
|
+
//
|
|
134
|
+
// Skipped under Cypress to match `SelfieCaptureWrapper`'s existing test
|
|
135
|
+
// seam (`skipMediapipeForTests`). Specs rely on the wrapper short-circuiting
|
|
136
|
+
// to the legacy `selfie-capture` fallback; pre-warming here would race with
|
|
137
|
+
// that seam and (intermittently) flip the wrapper into the SmartSelfie path
|
|
138
|
+
// by populating `window.__smileIdentityMediapipe` before the wrapper mounts.
|
|
139
|
+
//
|
|
140
|
+
// The parent check covers the embed Cypress context where this element runs
|
|
141
|
+
// inside an iframe and window.Cypress is only set on the parent frame.
|
|
142
|
+
const isCypress =
|
|
143
|
+
!!window.Cypress ||
|
|
144
|
+
(() => {
|
|
145
|
+
try {
|
|
146
|
+
return !!window.parent.Cypress;
|
|
147
|
+
} catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
})() ||
|
|
151
|
+
(window.navigator.userAgent.includes('Electron') && window.__Cypress);
|
|
152
|
+
const forceMediapipeLoad = !!window.__SMILE_ID_TEST_FORCE_MEDIAPIPE_LOAD__;
|
|
153
|
+
if (!isCypress || forceMediapipeLoad) {
|
|
154
|
+
getMediapipeInstance().catch(() => {});
|
|
155
|
+
}
|
|
111
156
|
}
|
|
112
157
|
|
|
113
158
|
getAgentMode() {
|
|
@@ -230,6 +275,45 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
230
275
|
});
|
|
231
276
|
}
|
|
232
277
|
|
|
278
|
+
// Return to a clean selfie capture screen. Used when navigating back from the
|
|
279
|
+
// document flow. Previously this was driven by toggling the `initial-screen`
|
|
280
|
+
// attribute on this element, which re-fired a full `connectedCallback()`
|
|
281
|
+
// rebuild every time (even when the value was unchanged). We now swap in a
|
|
282
|
+
// fresh `selfie-capture-wrapper` synchronously and navigate explicitly, so we
|
|
283
|
+
// land on a clean capture screen — not the stale review — without rebuilding
|
|
284
|
+
// the whole screen tree or depending on timers.
|
|
285
|
+
restartSelfieCapture() {
|
|
286
|
+
SmartCamera.stopMedia();
|
|
287
|
+
|
|
288
|
+
const container = this.querySelector('div');
|
|
289
|
+
const oldWrapper = this.selfieCapture;
|
|
290
|
+
|
|
291
|
+
if (oldWrapper && container) {
|
|
292
|
+
this._remountKey++;
|
|
293
|
+
|
|
294
|
+
const newWrapper = document.createElement('selfie-capture-wrapper');
|
|
295
|
+
Array.from(oldWrapper.attributes).forEach((attr) => {
|
|
296
|
+
newWrapper.setAttribute(attr.name, attr.value);
|
|
297
|
+
});
|
|
298
|
+
newWrapper.setAttribute('key', this._remountKey.toString());
|
|
299
|
+
newWrapper.setAttribute('start-countdown', 'false');
|
|
300
|
+
newWrapper.setAttribute('hidden', '');
|
|
301
|
+
|
|
302
|
+
const reviewElement = container.querySelector('selfie-capture-review');
|
|
303
|
+
oldWrapper.remove();
|
|
304
|
+
if (reviewElement) {
|
|
305
|
+
container.insertBefore(newWrapper, reviewElement);
|
|
306
|
+
} else {
|
|
307
|
+
container.appendChild(newWrapper);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
this.selfieCapture = newWrapper;
|
|
311
|
+
this.setupSelfieWrapperEventListeners();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this.setActiveScreen(this.selfieCapture);
|
|
315
|
+
}
|
|
316
|
+
|
|
233
317
|
// Override setActiveScreen to enable countdown when selfie-capture is active
|
|
234
318
|
setActiveScreen(screen) {
|
|
235
319
|
if (this.activeScreen === screen) {
|
|
@@ -256,6 +340,17 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
256
340
|
window.removeEventListener(event, handler);
|
|
257
341
|
});
|
|
258
342
|
}
|
|
343
|
+
// Also remove the previously-attached element-level publish handler so we
|
|
344
|
+
// don't accumulate duplicates across remounts (each call to
|
|
345
|
+
// setupSelfieWrapperEventListeners would otherwise add another listener,
|
|
346
|
+
// causing multiple transitions to review / multiple metadata events on
|
|
347
|
+
// navigating back from document capture).
|
|
348
|
+
if (this._selfieWrapperPublishHandler) {
|
|
349
|
+
this.removeEventListener(
|
|
350
|
+
'selfie-capture.publish',
|
|
351
|
+
this._selfieWrapperPublishHandler,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
259
354
|
|
|
260
355
|
// Create new event handlers
|
|
261
356
|
const cancelledHandler = async () => {
|
|
@@ -264,7 +359,7 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
264
359
|
// Force remount of selfie-capture-wrapper for clean state on next visit
|
|
265
360
|
await this.forceWrapperRemount();
|
|
266
361
|
|
|
267
|
-
if (this.hideInstructions) {
|
|
362
|
+
if (this.hideInstructions || this.isStrictMode) {
|
|
268
363
|
this.handleBackEvents();
|
|
269
364
|
return;
|
|
270
365
|
}
|
|
@@ -285,6 +380,18 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
285
380
|
smartCameraWeb?.dispatchEvent(
|
|
286
381
|
new CustomEvent('metadata.selfie-capture-end'),
|
|
287
382
|
);
|
|
383
|
+
this._data.images = event.detail.images;
|
|
384
|
+
SmartCamera.stopMedia();
|
|
385
|
+
|
|
386
|
+
// In strict mode (Enhanced SmartSelfie), the ESS component already
|
|
387
|
+
// shows its own review screen and only re-dispatches `publish` after
|
|
388
|
+
// the user confirms. Skip the legacy `selfie-capture-review` step and
|
|
389
|
+
// publish straight up to the host page.
|
|
390
|
+
if (this.isStrictMode) {
|
|
391
|
+
this._publishSelectedImages();
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
288
395
|
this.selfieReview.setAttribute(
|
|
289
396
|
'data-image',
|
|
290
397
|
await cropImageFromDataUri(event.detail.referenceImage, 20, 20),
|
|
@@ -294,8 +401,6 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
294
401
|
'mirror-image',
|
|
295
402
|
shouldMirror ? 'true' : 'false',
|
|
296
403
|
);
|
|
297
|
-
this._data.images = event.detail.images;
|
|
298
|
-
SmartCamera.stopMedia();
|
|
299
404
|
this.setActiveScreen(this.selfieReview);
|
|
300
405
|
};
|
|
301
406
|
|
|
@@ -313,6 +418,7 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
313
418
|
|
|
314
419
|
// Also listen for the publish event on the parent SelfieCaptureScreens element
|
|
315
420
|
// in case smartselfie-capture dispatches it there
|
|
421
|
+
this._selfieWrapperPublishHandler = publishHandler;
|
|
316
422
|
this.addEventListener('selfie-capture.publish', publishHandler);
|
|
317
423
|
}
|
|
318
424
|
|
|
@@ -367,10 +473,31 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
367
473
|
|
|
368
474
|
get allowLegacySelfieFallback() {
|
|
369
475
|
return this.hasAttribute('allow-legacy-selfie-fallback')
|
|
370
|
-
? `allow-legacy-selfie-fallback=
|
|
476
|
+
? `allow-legacy-selfie-fallback="${escAttr(this.getAttribute('allow-legacy-selfie-fallback'))}"`
|
|
477
|
+
: '';
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
get useStrictMode() {
|
|
481
|
+
return this.hasAttribute('use-strict-mode') &&
|
|
482
|
+
this.getAttribute('use-strict-mode') !== 'false'
|
|
483
|
+
? 'use-strict-mode="true"'
|
|
371
484
|
: '';
|
|
372
485
|
}
|
|
373
486
|
|
|
487
|
+
get showBackOnGuidelines() {
|
|
488
|
+
return this.hasAttribute('show-back-on-guidelines')
|
|
489
|
+
? 'show-back-on-guidelines="true"'
|
|
490
|
+
: '';
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/** Boolean form of `use-strict-mode` for runtime checks. */
|
|
494
|
+
get isStrictMode() {
|
|
495
|
+
return (
|
|
496
|
+
this.hasAttribute('use-strict-mode') &&
|
|
497
|
+
this.getAttribute('use-strict-mode') !== 'false'
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
374
501
|
get themeColor() {
|
|
375
502
|
return this.getAttribute('theme-color') || '#001096';
|
|
376
503
|
}
|
|
@@ -394,6 +521,8 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
394
521
|
'allow-legacy-selfie-fallback',
|
|
395
522
|
'show-agent-mode-for-tests',
|
|
396
523
|
'disable-image-tests',
|
|
524
|
+
'use-strict-mode',
|
|
525
|
+
'show-back-on-guidelines',
|
|
397
526
|
];
|
|
398
527
|
}
|
|
399
528
|
|
|
@@ -406,6 +535,8 @@ class SelfieCaptureScreens extends HTMLElement {
|
|
|
406
535
|
case 'allow-legacy-selfie-fallback':
|
|
407
536
|
case 'show-agent-mode-for-tests':
|
|
408
537
|
case 'disable-image-tests':
|
|
538
|
+
case 'use-strict-mode':
|
|
539
|
+
case 'show-back-on-guidelines':
|
|
409
540
|
this.connectedCallback();
|
|
410
541
|
break;
|
|
411
542
|
default:
|