@youidian/sdk 3.3.10 → 3.4.2
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/client.cjs +1123 -41
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +74 -4
- package/dist/client.d.ts +74 -4
- package/dist/client.js +1120 -41
- package/dist/client.js.map +1 -1
- package/dist/feedback.cjs +682 -0
- package/dist/feedback.cjs.map +1 -0
- package/dist/feedback.d.cts +38 -0
- package/dist/feedback.d.ts +38 -0
- package/dist/feedback.js +656 -0
- package/dist/feedback.js.map +1 -0
- package/dist/index.cjs +1866 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1861 -41
- package/dist/index.js.map +1 -1
- package/dist/{login-DerOcXcH.d.cts → login-Dqemys65.d.cts} +8 -4
- package/dist/{login-DerOcXcH.d.ts → login-Dqemys65.d.ts} +8 -4
- package/dist/login.cjs +334 -33
- package/dist/login.cjs.map +1 -1
- package/dist/login.d.cts +1 -1
- package/dist/login.d.ts +1 -1
- package/dist/login.js +334 -33
- package/dist/login.js.map +1 -1
- package/dist/server.cjs +87 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +146 -1
- package/dist/server.d.ts +146 -1
- package/dist/server.js +87 -0
- package/dist/server.js.map +1 -1
- package/package.json +6 -1
package/dist/client.js
CHANGED
|
@@ -2,6 +2,221 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
|
|
5
|
+
// src/brand-logo.ts
|
|
6
|
+
function ensureSdkBrandLogoStyles() {
|
|
7
|
+
if (document.getElementById?.("youidian-sdk-brand-logo-style")) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const style = document.createElement("style");
|
|
11
|
+
style.id = "youidian-sdk-brand-logo-style";
|
|
12
|
+
style.textContent = `
|
|
13
|
+
.youidian-sdk-brand-logo__ring,
|
|
14
|
+
.youidian-sdk-brand-logo__dot,
|
|
15
|
+
.youidian-sdk-brand-logo__copy,
|
|
16
|
+
.youidian-sdk-brand-logo__tagline {
|
|
17
|
+
transform-box: fill-box;
|
|
18
|
+
transform-origin: center;
|
|
19
|
+
will-change: opacity, transform;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__ring {
|
|
23
|
+
animation: youidian-sdk-brand-logo-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__dot {
|
|
27
|
+
animation: youidian-sdk-brand-logo-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__copy {
|
|
31
|
+
animation: youidian-sdk-brand-logo-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__tagline {
|
|
35
|
+
animation: youidian-sdk-brand-logo-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@keyframes youidian-sdk-brand-logo-ring {
|
|
39
|
+
0%,
|
|
40
|
+
100% {
|
|
41
|
+
opacity: 0.72;
|
|
42
|
+
transform: rotate(0deg) scale(0.98);
|
|
43
|
+
}
|
|
44
|
+
50% {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
transform: rotate(8deg) scale(1.02);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@keyframes youidian-sdk-brand-logo-dot {
|
|
51
|
+
0%,
|
|
52
|
+
100% {
|
|
53
|
+
opacity: 0.58;
|
|
54
|
+
transform: scale(0.9);
|
|
55
|
+
}
|
|
56
|
+
50% {
|
|
57
|
+
opacity: 1;
|
|
58
|
+
transform: scale(1.08);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@keyframes youidian-sdk-brand-logo-copy {
|
|
63
|
+
0%,
|
|
64
|
+
100% {
|
|
65
|
+
opacity: 0.86;
|
|
66
|
+
transform: translateY(0);
|
|
67
|
+
}
|
|
68
|
+
50% {
|
|
69
|
+
opacity: 1;
|
|
70
|
+
transform: translateY(-1px);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@keyframes youidian-sdk-brand-logo-tagline {
|
|
75
|
+
0%,
|
|
76
|
+
100% {
|
|
77
|
+
opacity: 0.64;
|
|
78
|
+
}
|
|
79
|
+
50% {
|
|
80
|
+
opacity: 0.92;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media (prefers-reduced-motion: reduce) {
|
|
85
|
+
.youidian-sdk-brand-logo__ring,
|
|
86
|
+
.youidian-sdk-brand-logo__dot,
|
|
87
|
+
.youidian-sdk-brand-logo__copy,
|
|
88
|
+
.youidian-sdk-brand-logo__tagline {
|
|
89
|
+
animation: none;
|
|
90
|
+
opacity: 1;
|
|
91
|
+
transform: none;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
document.head?.appendChild(style);
|
|
96
|
+
}
|
|
97
|
+
function createSdkBrandLogoMark({
|
|
98
|
+
animated,
|
|
99
|
+
inverted,
|
|
100
|
+
size,
|
|
101
|
+
theme,
|
|
102
|
+
variant = "brand"
|
|
103
|
+
}) {
|
|
104
|
+
ensureSdkBrandLogoStyles();
|
|
105
|
+
const mark = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
106
|
+
mark.setAttribute("viewBox", "0 0 512 512");
|
|
107
|
+
mark.setAttribute("fill", "none");
|
|
108
|
+
mark.setAttribute("aria-hidden", "true");
|
|
109
|
+
Object.assign(mark.style, {
|
|
110
|
+
width: `${size}px`,
|
|
111
|
+
height: `${size}px`,
|
|
112
|
+
color: inverted ? "#ffffff" : theme.primary,
|
|
113
|
+
display: "block",
|
|
114
|
+
flex: "0 0 auto",
|
|
115
|
+
overflow: "visible"
|
|
116
|
+
});
|
|
117
|
+
const logoGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
118
|
+
logoGroup.setAttribute(
|
|
119
|
+
"transform",
|
|
120
|
+
variant === "mark" ? "matrix(0.74 0 0 0.74 -124 -114)" : "matrix(0.58 0 0 0.58 -40 -31)"
|
|
121
|
+
);
|
|
122
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
123
|
+
ring.setAttribute("class", animated ? "youidian-sdk-brand-logo__ring" : "");
|
|
124
|
+
ring.setAttribute("fill", inverted ? "currentColor" : theme.primary);
|
|
125
|
+
ring.setAttribute(
|
|
126
|
+
"d",
|
|
127
|
+
"M704.298 679.54A264 264 0 1 1 704.298 309.46A49 49 0 0 1 634.4 378.149A166 166 0 1 0 634.4 610.851A49 49 0 0 1 704.298 679.54Z"
|
|
128
|
+
);
|
|
129
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
130
|
+
dot.setAttribute("class", animated ? "youidian-sdk-brand-logo__dot" : "");
|
|
131
|
+
dot.setAttribute("fill", inverted ? "currentColor" : theme.secondary);
|
|
132
|
+
dot.setAttribute("cx", "714.5");
|
|
133
|
+
dot.setAttribute("cy", "490.5");
|
|
134
|
+
dot.setAttribute("r", "68");
|
|
135
|
+
dot.setAttribute("opacity", inverted ? "0.78" : "1");
|
|
136
|
+
logoGroup.appendChild(ring);
|
|
137
|
+
logoGroup.appendChild(dot);
|
|
138
|
+
mark.appendChild(logoGroup);
|
|
139
|
+
return mark;
|
|
140
|
+
}
|
|
141
|
+
function createSdkBrandLogo({
|
|
142
|
+
animated,
|
|
143
|
+
brand,
|
|
144
|
+
brandWidth,
|
|
145
|
+
copyWidth,
|
|
146
|
+
gap = 10,
|
|
147
|
+
markMarginRight,
|
|
148
|
+
markSize,
|
|
149
|
+
nameSize,
|
|
150
|
+
subtitleMarginTop = 6,
|
|
151
|
+
subtitleSize,
|
|
152
|
+
subtitleWeight = "800",
|
|
153
|
+
theme,
|
|
154
|
+
variant = "brand"
|
|
155
|
+
}) {
|
|
156
|
+
ensureSdkBrandLogoStyles();
|
|
157
|
+
const wrapper = document.createElement("div");
|
|
158
|
+
wrapper.className = "youidian-sdk-brand-logo";
|
|
159
|
+
wrapper.setAttribute("data-animated", animated ? "true" : "false");
|
|
160
|
+
Object.assign(wrapper.style, {
|
|
161
|
+
display: "inline-flex",
|
|
162
|
+
alignItems: "center",
|
|
163
|
+
justifyContent: "center",
|
|
164
|
+
gap: `${gap}px`,
|
|
165
|
+
width: brandWidth ? `${brandWidth}px` : void 0
|
|
166
|
+
});
|
|
167
|
+
const copy = document.createElement("div");
|
|
168
|
+
copy.className = "youidian-sdk-brand-logo__copy";
|
|
169
|
+
copy.setAttribute("data-brand-locale", brand.language);
|
|
170
|
+
Object.assign(copy.style, {
|
|
171
|
+
display: "flex",
|
|
172
|
+
flexDirection: "column",
|
|
173
|
+
alignItems: "flex-start",
|
|
174
|
+
justifyContent: "center",
|
|
175
|
+
lineHeight: "1",
|
|
176
|
+
width: copyWidth ? `${copyWidth}px` : void 0
|
|
177
|
+
});
|
|
178
|
+
const name = document.createElement("div");
|
|
179
|
+
name.className = "youidian-sdk-brand-logo__name";
|
|
180
|
+
name.textContent = brand.name;
|
|
181
|
+
Object.assign(name.style, {
|
|
182
|
+
color: theme.foreground,
|
|
183
|
+
fontFamily: brand.language === "zh" ? '"Noto Sans TC", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' : '"Unbounded", "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
184
|
+
fontSize: `${nameSize}px`,
|
|
185
|
+
fontWeight: brand.language === "zh" ? "900" : "800",
|
|
186
|
+
letterSpacing: brand.language === "zh" ? "0.08em" : "0.01em",
|
|
187
|
+
lineHeight: "1",
|
|
188
|
+
whiteSpace: "nowrap"
|
|
189
|
+
});
|
|
190
|
+
const subtitle = document.createElement("div");
|
|
191
|
+
subtitle.className = "youidian-sdk-brand-logo__tagline";
|
|
192
|
+
subtitle.textContent = brand.subtitle;
|
|
193
|
+
Object.assign(subtitle.style, {
|
|
194
|
+
color: theme.muted,
|
|
195
|
+
fontFamily: brand.language === "zh" ? '"Noto Sans TC", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' : '"Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
196
|
+
fontSize: `${subtitleSize}px`,
|
|
197
|
+
fontWeight: subtitleWeight,
|
|
198
|
+
letterSpacing: brand.language === "zh" ? "0.24em" : "0.07em",
|
|
199
|
+
lineHeight: "1",
|
|
200
|
+
marginTop: `${subtitleMarginTop}px`,
|
|
201
|
+
textTransform: brand.language === "zh" ? "none" : "uppercase",
|
|
202
|
+
whiteSpace: "nowrap"
|
|
203
|
+
});
|
|
204
|
+
copy.appendChild(name);
|
|
205
|
+
copy.appendChild(subtitle);
|
|
206
|
+
const mark = createSdkBrandLogoMark({
|
|
207
|
+
animated,
|
|
208
|
+
size: markSize,
|
|
209
|
+
theme,
|
|
210
|
+
variant
|
|
211
|
+
});
|
|
212
|
+
if (typeof markMarginRight === "number") {
|
|
213
|
+
mark.style.marginRight = `${markMarginRight}px`;
|
|
214
|
+
}
|
|
215
|
+
wrapper.appendChild(mark);
|
|
216
|
+
wrapper.appendChild(copy);
|
|
217
|
+
return wrapper;
|
|
218
|
+
}
|
|
219
|
+
|
|
5
220
|
// src/hosted-modal.ts
|
|
6
221
|
var SDK_SUPPORTED_LOCALES = [
|
|
7
222
|
"en",
|
|
@@ -125,7 +340,7 @@ var HostedFrameModal = class {
|
|
|
125
340
|
const container = document.createElement("div");
|
|
126
341
|
Object.assign(container.style, {
|
|
127
342
|
width: options.width || "450px",
|
|
128
|
-
height: options.height || "min(
|
|
343
|
+
height: options.height || "min(760px, calc(100vh - 32px))",
|
|
129
344
|
backgroundColor: "transparent",
|
|
130
345
|
borderRadius: "28px",
|
|
131
346
|
overflow: "visible",
|
|
@@ -133,8 +348,7 @@ var HostedFrameModal = class {
|
|
|
133
348
|
boxShadow: "none",
|
|
134
349
|
maxWidth: "calc(100vw - 32px)",
|
|
135
350
|
maxHeight: "calc(100vh - 32px)",
|
|
136
|
-
transition: "
|
|
137
|
-
willChange: "height"
|
|
351
|
+
transition: "none"
|
|
138
352
|
});
|
|
139
353
|
const closeBtn = document.createElement("button");
|
|
140
354
|
closeBtn.innerHTML = "\xD7";
|
|
@@ -204,6 +418,91 @@ var HostedFrameModal = class {
|
|
|
204
418
|
}
|
|
205
419
|
};
|
|
206
420
|
|
|
421
|
+
// src/environment.ts
|
|
422
|
+
function normalizeText(value) {
|
|
423
|
+
return value || "";
|
|
424
|
+
}
|
|
425
|
+
function getRuntimeInput() {
|
|
426
|
+
if (typeof navigator === "undefined") {
|
|
427
|
+
return {};
|
|
428
|
+
}
|
|
429
|
+
const nav = navigator;
|
|
430
|
+
const coarsePointer = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(pointer: coarse)").matches : void 0;
|
|
431
|
+
return {
|
|
432
|
+
coarsePointer,
|
|
433
|
+
maxTouchPoints: nav.maxTouchPoints || 0,
|
|
434
|
+
platform: nav.platform || "",
|
|
435
|
+
standalone: nav.standalone,
|
|
436
|
+
userAgent: nav.userAgent || "",
|
|
437
|
+
userAgentDataMobile: nav.userAgentData?.mobile
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function includesAny(value, patterns) {
|
|
441
|
+
return patterns.some((pattern) => pattern.test(value));
|
|
442
|
+
}
|
|
443
|
+
function detectLoginEnvironment(input = getRuntimeInput()) {
|
|
444
|
+
const userAgent = normalizeText(input.userAgent);
|
|
445
|
+
const platform = normalizeText(input.platform);
|
|
446
|
+
const rawMaxTouchPoints = input.maxTouchPoints ?? 0;
|
|
447
|
+
const maxTouchPoints = Number.isFinite(rawMaxTouchPoints) ? Math.max(0, rawMaxTouchPoints) : 0;
|
|
448
|
+
const isCoarsePointer = input.coarsePointer === true;
|
|
449
|
+
const isTouch = maxTouchPoints > 0 || isCoarsePointer;
|
|
450
|
+
const isWeChat = /micromessenger/i.test(userAgent);
|
|
451
|
+
const isAndroid = /\bandroid\b/i.test(userAgent);
|
|
452
|
+
const hasExplicitIOSDevice = /\b(iPad|iPhone|iPod)\b/i.test(userAgent);
|
|
453
|
+
const hasMacintoshUserAgent = /\bMacintosh\b/i.test(userAgent);
|
|
454
|
+
const hasMacPlatform = /^Mac/i.test(platform);
|
|
455
|
+
const isIPadOS = !hasExplicitIOSDevice && hasMacintoshUserAgent && hasMacPlatform && typeof input.standalone !== "undefined" && maxTouchPoints > 2;
|
|
456
|
+
const isIOS = hasExplicitIOSDevice || isIPadOS;
|
|
457
|
+
const isTabletByUa = includesAny(userAgent, [
|
|
458
|
+
/\biPad\b/i,
|
|
459
|
+
/\btablet\b/i,
|
|
460
|
+
/\bplaybook\b/i,
|
|
461
|
+
/\bsilk\b(?!.*\bmobile\b)/i,
|
|
462
|
+
/\bkindle\b/i,
|
|
463
|
+
/\bnexus 7\b/i,
|
|
464
|
+
/\bnexus 9\b/i,
|
|
465
|
+
/\bxoom\b/i,
|
|
466
|
+
/\bsm-t\d+/i,
|
|
467
|
+
/\bgt-p\d+/i,
|
|
468
|
+
/\bmi pad\b/i
|
|
469
|
+
]);
|
|
470
|
+
const isMobileByUa = includesAny(userAgent, [
|
|
471
|
+
/\bMobile\b/i,
|
|
472
|
+
/\biPhone\b/i,
|
|
473
|
+
/\biPod\b/i,
|
|
474
|
+
/\bWindows Phone\b/i,
|
|
475
|
+
/\bIEMobile\b/i,
|
|
476
|
+
/\bBlackBerry\b/i,
|
|
477
|
+
/\bBB10\b/i,
|
|
478
|
+
/\bOpera Mini\b/i,
|
|
479
|
+
/\bOpera Mobi\b/i,
|
|
480
|
+
/\bwebOS\b/i
|
|
481
|
+
]);
|
|
482
|
+
const isAndroidTablet = isAndroid && !/\bMobile\b/i.test(userAgent);
|
|
483
|
+
const isTablet = isIPadOS || isTabletByUa || isAndroidTablet;
|
|
484
|
+
const isMobile = input.userAgentDataMobile === true || isMobileByUa || isAndroid && !isTablet || isIOS && !isTablet;
|
|
485
|
+
const deviceType = isTablet ? "tablet" : isMobile ? "mobile" : userAgent || platform || isTouch ? "desktop" : "unknown";
|
|
486
|
+
const shouldUseRedirectLogin = deviceType === "mobile" || deviceType === "tablet" || isWeChat;
|
|
487
|
+
return {
|
|
488
|
+
deviceType,
|
|
489
|
+
isAndroid,
|
|
490
|
+
isCoarsePointer,
|
|
491
|
+
isDesktop: deviceType === "desktop",
|
|
492
|
+
isIOS,
|
|
493
|
+
isIPadOS,
|
|
494
|
+
isMobile,
|
|
495
|
+
isStandalone: input.standalone === true,
|
|
496
|
+
isTablet,
|
|
497
|
+
isTouch,
|
|
498
|
+
isWeChat,
|
|
499
|
+
maxTouchPoints,
|
|
500
|
+
platform,
|
|
501
|
+
shouldUseRedirectLogin,
|
|
502
|
+
userAgent
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
207
506
|
// src/login.ts
|
|
208
507
|
function getOrigin(value) {
|
|
209
508
|
if (!value) return null;
|
|
@@ -213,6 +512,15 @@ function getOrigin(value) {
|
|
|
213
512
|
return null;
|
|
214
513
|
}
|
|
215
514
|
}
|
|
515
|
+
function isValidLoginRedirectUrl(value) {
|
|
516
|
+
if (!value) return false;
|
|
517
|
+
try {
|
|
518
|
+
const url = new URL(value);
|
|
519
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
520
|
+
} catch {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
216
524
|
function createLoginCallbackState() {
|
|
217
525
|
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
218
526
|
return crypto.randomUUID().replace(/-/g, "");
|
|
@@ -559,6 +867,24 @@ function applyLoginPanelStyle(panel) {
|
|
|
559
867
|
backdropFilter: "blur(16px)"
|
|
560
868
|
});
|
|
561
869
|
}
|
|
870
|
+
function applyLoginLoadingPanelStyle(panel) {
|
|
871
|
+
Object.assign(panel.style, {
|
|
872
|
+
position: "absolute",
|
|
873
|
+
inset: "0",
|
|
874
|
+
display: "flex",
|
|
875
|
+
alignItems: "center",
|
|
876
|
+
justifyContent: "center",
|
|
877
|
+
border: "0",
|
|
878
|
+
borderRadius: "28px",
|
|
879
|
+
background: "rgba(255,255,255,0.94)",
|
|
880
|
+
color: "#0f172a",
|
|
881
|
+
padding: "24px",
|
|
882
|
+
textAlign: "center",
|
|
883
|
+
zIndex: "1",
|
|
884
|
+
boxShadow: "none",
|
|
885
|
+
backdropFilter: "blur(16px)"
|
|
886
|
+
});
|
|
887
|
+
}
|
|
562
888
|
function createLoginPanelContent() {
|
|
563
889
|
const content = document.createElement("div");
|
|
564
890
|
Object.assign(content.style, {
|
|
@@ -583,6 +909,71 @@ function createLoginPanelContent() {
|
|
|
583
909
|
content.appendChild(badge);
|
|
584
910
|
return content;
|
|
585
911
|
}
|
|
912
|
+
function createBrandLoadingMark() {
|
|
913
|
+
const logo = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
914
|
+
logo.setAttribute("viewBox", "0 0 1024 1024");
|
|
915
|
+
logo.setAttribute("fill", "none");
|
|
916
|
+
logo.setAttribute("aria-hidden", "true");
|
|
917
|
+
Object.assign(logo.style, {
|
|
918
|
+
width: "112px",
|
|
919
|
+
height: "112px",
|
|
920
|
+
color: "#22c55e",
|
|
921
|
+
display: "block",
|
|
922
|
+
overflow: "visible"
|
|
923
|
+
});
|
|
924
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
925
|
+
group.setAttribute("fill", "currentColor");
|
|
926
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
927
|
+
ring.setAttribute(
|
|
928
|
+
"d",
|
|
929
|
+
"M704.298 679.54A264 264 0 1 1 704.298 309.46A49 49 0 0 1 634.4 378.149A166 166 0 1 0 634.4 610.851A49 49 0 0 1 704.298 679.54Z"
|
|
930
|
+
);
|
|
931
|
+
ring.setAttribute("class", "youidian-sdk-brand-loading__ring");
|
|
932
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
933
|
+
dot.setAttribute("class", "youidian-sdk-brand-loading__dot");
|
|
934
|
+
dot.setAttribute("cx", "714.5");
|
|
935
|
+
dot.setAttribute("cy", "490.5");
|
|
936
|
+
dot.setAttribute("r", "68");
|
|
937
|
+
group.appendChild(ring);
|
|
938
|
+
group.appendChild(dot);
|
|
939
|
+
logo.appendChild(group);
|
|
940
|
+
return logo;
|
|
941
|
+
}
|
|
942
|
+
function createBrandLoadingCopy() {
|
|
943
|
+
const brand = document.createElement("div");
|
|
944
|
+
brand.className = "youidian-sdk-brand-loading__copy";
|
|
945
|
+
Object.assign(brand.style, {
|
|
946
|
+
display: "flex",
|
|
947
|
+
flexDirection: "column",
|
|
948
|
+
alignItems: "flex-start",
|
|
949
|
+
justifyContent: "center",
|
|
950
|
+
lineHeight: "1"
|
|
951
|
+
});
|
|
952
|
+
const name = document.createElement("div");
|
|
953
|
+
name.className = "youidian-sdk-brand-loading__name";
|
|
954
|
+
name.textContent = "\u4F18\u6613\u70B9";
|
|
955
|
+
Object.assign(name.style, {
|
|
956
|
+
color: "#0f172a",
|
|
957
|
+
fontSize: "34px",
|
|
958
|
+
fontWeight: "900",
|
|
959
|
+
letterSpacing: "0",
|
|
960
|
+
lineHeight: "1"
|
|
961
|
+
});
|
|
962
|
+
const tagline = document.createElement("div");
|
|
963
|
+
tagline.className = "youidian-sdk-brand-loading__tagline";
|
|
964
|
+
tagline.textContent = "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0";
|
|
965
|
+
Object.assign(tagline.style, {
|
|
966
|
+
color: "#64748b",
|
|
967
|
+
fontSize: "16px",
|
|
968
|
+
fontWeight: "700",
|
|
969
|
+
letterSpacing: "0.24em",
|
|
970
|
+
lineHeight: "1",
|
|
971
|
+
marginTop: "6px"
|
|
972
|
+
});
|
|
973
|
+
brand.appendChild(name);
|
|
974
|
+
brand.appendChild(tagline);
|
|
975
|
+
return brand;
|
|
976
|
+
}
|
|
586
977
|
function createLoginPanelTitle(value) {
|
|
587
978
|
const title = document.createElement("div");
|
|
588
979
|
title.textContent = value;
|
|
@@ -612,32 +1003,111 @@ function ensureLoginLoadingStyles() {
|
|
|
612
1003
|
}
|
|
613
1004
|
const style = document.createElement("style");
|
|
614
1005
|
style.id = "youidian-login-loading-style";
|
|
615
|
-
style.textContent =
|
|
1006
|
+
style.textContent = `
|
|
1007
|
+
.youidian-sdk-brand-loading__ring,
|
|
1008
|
+
.youidian-sdk-brand-loading__dot {
|
|
1009
|
+
transform-box: fill-box;
|
|
1010
|
+
transform-origin: center;
|
|
1011
|
+
will-change: opacity, transform;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
.youidian-sdk-brand-loading__ring {
|
|
1015
|
+
animation: youidian-sdk-brand-loading-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
.youidian-sdk-brand-loading__dot {
|
|
1019
|
+
animation: youidian-sdk-brand-loading-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
.youidian-sdk-brand-loading__copy {
|
|
1023
|
+
will-change: opacity, transform;
|
|
1024
|
+
animation: youidian-sdk-brand-loading-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
.youidian-sdk-brand-loading__tagline {
|
|
1028
|
+
will-change: opacity;
|
|
1029
|
+
animation: youidian-sdk-brand-loading-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
@keyframes youidian-sdk-brand-loading-ring {
|
|
1033
|
+
0%,
|
|
1034
|
+
100% {
|
|
1035
|
+
opacity: 0.72;
|
|
1036
|
+
transform: rotate(0deg) scale(0.98);
|
|
1037
|
+
}
|
|
1038
|
+
50% {
|
|
1039
|
+
opacity: 1;
|
|
1040
|
+
transform: rotate(8deg) scale(1.02);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
@keyframes youidian-sdk-brand-loading-dot {
|
|
1045
|
+
0%,
|
|
1046
|
+
100% {
|
|
1047
|
+
opacity: 0.55;
|
|
1048
|
+
transform: scale(0.9);
|
|
1049
|
+
}
|
|
1050
|
+
50% {
|
|
1051
|
+
opacity: 1;
|
|
1052
|
+
transform: scale(1.08);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
@keyframes youidian-sdk-brand-loading-copy {
|
|
1057
|
+
0%,
|
|
1058
|
+
100% {
|
|
1059
|
+
opacity: 0.86;
|
|
1060
|
+
transform: translateY(0);
|
|
1061
|
+
}
|
|
1062
|
+
50% {
|
|
1063
|
+
opacity: 1;
|
|
1064
|
+
transform: translateY(-1px);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
@keyframes youidian-sdk-brand-loading-tagline {
|
|
1069
|
+
0%,
|
|
1070
|
+
100% {
|
|
1071
|
+
opacity: 0.64;
|
|
1072
|
+
}
|
|
1073
|
+
50% {
|
|
1074
|
+
opacity: 0.92;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1079
|
+
.youidian-sdk-brand-loading__ring,
|
|
1080
|
+
.youidian-sdk-brand-loading__dot,
|
|
1081
|
+
.youidian-sdk-brand-loading__copy,
|
|
1082
|
+
.youidian-sdk-brand-loading__tagline {
|
|
1083
|
+
animation: none;
|
|
1084
|
+
opacity: 1;
|
|
1085
|
+
transform: none;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
`;
|
|
616
1089
|
document.head.appendChild(style);
|
|
617
1090
|
}
|
|
618
|
-
function createLoginLoadingPanel(
|
|
1091
|
+
function createLoginLoadingPanel() {
|
|
619
1092
|
ensureLoginLoadingStyles();
|
|
620
1093
|
const panel = document.createElement("div");
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
margin: "0 auto 18px",
|
|
631
|
-
animation: "youidian-login-spin 780ms linear infinite"
|
|
1094
|
+
applyLoginLoadingPanelStyle(panel);
|
|
1095
|
+
panel.setAttribute("role", "status");
|
|
1096
|
+
panel.setAttribute("aria-label", "\u4F18\u6613\u70B9\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0");
|
|
1097
|
+
const content = document.createElement("div");
|
|
1098
|
+
Object.assign(content.style, {
|
|
1099
|
+
display: "flex",
|
|
1100
|
+
alignItems: "center",
|
|
1101
|
+
justifyContent: "center",
|
|
1102
|
+
gap: "12px"
|
|
632
1103
|
});
|
|
633
|
-
content.appendChild(
|
|
634
|
-
content.appendChild(
|
|
635
|
-
content.appendChild(createLoginPanelDescription(options.description));
|
|
1104
|
+
content.appendChild(createBrandLoadingMark());
|
|
1105
|
+
content.appendChild(createBrandLoadingCopy());
|
|
636
1106
|
panel.appendChild(content);
|
|
637
1107
|
return panel;
|
|
638
1108
|
}
|
|
639
|
-
function createLoginRedirectingPanel(
|
|
640
|
-
return createLoginLoadingPanel(
|
|
1109
|
+
function createLoginRedirectingPanel(_options) {
|
|
1110
|
+
return createLoginLoadingPanel();
|
|
641
1111
|
}
|
|
642
1112
|
function createLoginFallbackPanel(options) {
|
|
643
1113
|
const panel = document.createElement("div");
|
|
@@ -719,6 +1189,7 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
719
1189
|
this.completed = false;
|
|
720
1190
|
}
|
|
721
1191
|
markIframeReady() {
|
|
1192
|
+
if (this.iframeReady) return;
|
|
722
1193
|
this.iframeReady = true;
|
|
723
1194
|
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
724
1195
|
window.clearTimeout(this.iframeLoadTimer);
|
|
@@ -737,14 +1208,11 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
737
1208
|
this.iframeFallbackPanel = null;
|
|
738
1209
|
this.iframeLoadingPanel = null;
|
|
739
1210
|
}
|
|
740
|
-
showIframeLoading(container
|
|
1211
|
+
showIframeLoading(container) {
|
|
741
1212
|
if (this.iframeLoadingPanel || this.iframeReady) {
|
|
742
1213
|
return;
|
|
743
1214
|
}
|
|
744
|
-
const panel = createLoginLoadingPanel(
|
|
745
|
-
description: options?.loadingDescription || "Please wait while the secure login page opens.",
|
|
746
|
-
title: options?.loadingTitle || "Opening login page"
|
|
747
|
-
});
|
|
1215
|
+
const panel = createLoginLoadingPanel();
|
|
748
1216
|
this.iframeLoadingPanel = panel;
|
|
749
1217
|
container.appendChild(panel);
|
|
750
1218
|
}
|
|
@@ -832,6 +1300,20 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
832
1300
|
break;
|
|
833
1301
|
case "LOGIN_RESIZE":
|
|
834
1302
|
break;
|
|
1303
|
+
case "LOGIN_REDIRECT_REQUIRED":
|
|
1304
|
+
if (!isValidLoginRedirectUrl(data.authUrl)) {
|
|
1305
|
+
logLoginWarn("Login redirect requested with invalid authUrl");
|
|
1306
|
+
options?.onError?.("Login redirect URL is invalid", data);
|
|
1307
|
+
break;
|
|
1308
|
+
}
|
|
1309
|
+
logLoginInfo("Login redirect requested by hosted page", {
|
|
1310
|
+
attemptId: data.attemptId || null,
|
|
1311
|
+
channel: data.channel || null,
|
|
1312
|
+
authUrl: data.authUrl
|
|
1313
|
+
});
|
|
1314
|
+
this.close();
|
|
1315
|
+
window.location.assign(data.authUrl);
|
|
1316
|
+
break;
|
|
835
1317
|
case "LOGIN_ERROR":
|
|
836
1318
|
if (this.completed) {
|
|
837
1319
|
break;
|
|
@@ -855,6 +1337,25 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
855
1337
|
break;
|
|
856
1338
|
}
|
|
857
1339
|
}
|
|
1340
|
+
openLoginRedirect(params, options) {
|
|
1341
|
+
if (typeof window === "undefined") return;
|
|
1342
|
+
const { callbackState, finalUrl, launchPayload } = this.buildOpenContext(
|
|
1343
|
+
params,
|
|
1344
|
+
options
|
|
1345
|
+
);
|
|
1346
|
+
logLoginInfo("Redirecting to hosted login page", {
|
|
1347
|
+
appId: params.appId,
|
|
1348
|
+
callbackState,
|
|
1349
|
+
callbackUrl: launchPayload.callbackUrl || null,
|
|
1350
|
+
hasCallbackUrl: Boolean(launchPayload.callbackUrl),
|
|
1351
|
+
loginUrl: finalUrl,
|
|
1352
|
+
autoClose: options?.autoClose ?? true,
|
|
1353
|
+
displayMode: "redirect",
|
|
1354
|
+
pageUrl: window.location.href,
|
|
1355
|
+
parentOrigin: launchPayload.origin || null
|
|
1356
|
+
});
|
|
1357
|
+
window.location.assign(finalUrl);
|
|
1358
|
+
}
|
|
858
1359
|
listenForLoginCallback(callbackState, options) {
|
|
859
1360
|
try {
|
|
860
1361
|
this.callbackChannel = new BroadcastChannel(
|
|
@@ -931,21 +1432,28 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
931
1432
|
options?.onCancel?.();
|
|
932
1433
|
options?.onClose?.();
|
|
933
1434
|
},
|
|
934
|
-
onMessage: (data,
|
|
1435
|
+
onMessage: (data, _container, event) => {
|
|
935
1436
|
const isIframeEvent = event.source === this.iframe?.contentWindow;
|
|
1437
|
+
if (!isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE")) {
|
|
1438
|
+
logLoginWarn(
|
|
1439
|
+
"Login lifecycle event ignored: event.source does not match iframe contentWindow",
|
|
1440
|
+
{
|
|
1441
|
+
type: data.type,
|
|
1442
|
+
eventOrigin: event.origin,
|
|
1443
|
+
hasIframe: Boolean(this.iframe),
|
|
1444
|
+
hasIframeContentWindow: Boolean(this.iframe?.contentWindow)
|
|
1445
|
+
}
|
|
1446
|
+
);
|
|
1447
|
+
}
|
|
936
1448
|
if (isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE") || data.type === "LOGIN_SUCCESS" || data.type === "LOGIN_ERROR") {
|
|
937
1449
|
this.markIframeReady();
|
|
938
1450
|
}
|
|
939
|
-
if (data.type === "LOGIN_RESIZE" && data.height) {
|
|
940
|
-
const maxHeight = window.innerHeight * 0.94;
|
|
941
|
-
container.style.height = `${Math.min(data.height, maxHeight)}px`;
|
|
942
|
-
}
|
|
943
1451
|
this.handleLoginEvent(data, options);
|
|
944
1452
|
},
|
|
945
1453
|
width: "min(520px, 100%)"
|
|
946
1454
|
});
|
|
947
1455
|
if (hostedFrame) {
|
|
948
|
-
this.showIframeLoading(hostedFrame.container
|
|
1456
|
+
this.showIframeLoading(hostedFrame.container);
|
|
949
1457
|
this.startIframeWatchdog({
|
|
950
1458
|
container: hostedFrame.container,
|
|
951
1459
|
finalUrl,
|
|
@@ -1049,11 +1557,19 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1049
1557
|
}
|
|
1050
1558
|
openLogin(params, options) {
|
|
1051
1559
|
if (typeof window === "undefined") return;
|
|
1052
|
-
const displayMode = options?.displayMode ?? "
|
|
1560
|
+
const displayMode = options?.displayMode ?? "auto";
|
|
1561
|
+
if (displayMode === "redirect") {
|
|
1562
|
+
this.openLoginRedirect(params, options);
|
|
1563
|
+
return;
|
|
1564
|
+
}
|
|
1053
1565
|
if (displayMode === "popup") {
|
|
1054
1566
|
this.openLoginPopup(params, options);
|
|
1055
1567
|
return;
|
|
1056
1568
|
}
|
|
1569
|
+
if (displayMode === "auto" && detectLoginEnvironment().shouldUseRedirectLogin) {
|
|
1570
|
+
this.openLoginRedirect(params, options);
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1057
1573
|
this.openLoginModal(params, options);
|
|
1058
1574
|
}
|
|
1059
1575
|
};
|
|
@@ -1063,6 +1579,406 @@ function createLoginUI() {
|
|
|
1063
1579
|
handleLoginCallbackIfPresent({ autoClose: false });
|
|
1064
1580
|
|
|
1065
1581
|
// src/client.ts
|
|
1582
|
+
var DEFAULT_PAYMENT_IFRAME_LOAD_TIMEOUT_MS = 8e3;
|
|
1583
|
+
var PAYMENT_UI_LOG_PREFIX = "[Youidian PaymentUI]";
|
|
1584
|
+
function hexToRgb(value) {
|
|
1585
|
+
const normalized = value.trim().replace(/^#/, "");
|
|
1586
|
+
if (!/^[0-9a-f]{3}([0-9a-f]{3})?$/i.test(normalized)) return null;
|
|
1587
|
+
const hex = normalized.length === 3 ? normalized.split("").map((char) => `${char}${char}`).join("") : normalized;
|
|
1588
|
+
const number = Number.parseInt(hex, 16);
|
|
1589
|
+
return {
|
|
1590
|
+
b: number & 255,
|
|
1591
|
+
g: number >> 8 & 255,
|
|
1592
|
+
r: number >> 16 & 255
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
function alphaColor(value, alpha) {
|
|
1596
|
+
const rgb = hexToRgb(value);
|
|
1597
|
+
if (!rgb)
|
|
1598
|
+
return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
|
|
1599
|
+
return `rgba(${rgb.r},${rgb.g},${rgb.b},${alpha})`;
|
|
1600
|
+
}
|
|
1601
|
+
function resolvePaymentTheme(options) {
|
|
1602
|
+
const primary = options?.theme?.primary || "#16a34a";
|
|
1603
|
+
const secondary = options?.theme?.secondary || "color-mix(in srgb, #16a34a 78%, white)";
|
|
1604
|
+
const foreground = options?.theme?.foreground || "#0f172a";
|
|
1605
|
+
const muted = options?.theme?.muted || "#64748b";
|
|
1606
|
+
const surface = options?.theme?.surface || "#ffffff";
|
|
1607
|
+
return {
|
|
1608
|
+
foreground,
|
|
1609
|
+
muted,
|
|
1610
|
+
primary,
|
|
1611
|
+
primary10: alphaColor(primary, 0.1),
|
|
1612
|
+
primary14: alphaColor(primary, 0.14),
|
|
1613
|
+
primary20: alphaColor(primary, 0.2),
|
|
1614
|
+
primary28: alphaColor(primary, 0.28),
|
|
1615
|
+
primary36: alphaColor(primary, 0.36),
|
|
1616
|
+
primary64: alphaColor(primary, 0.64),
|
|
1617
|
+
secondary,
|
|
1618
|
+
surface
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
function logPaymentInfo(message, details) {
|
|
1622
|
+
if (typeof console === "undefined") return;
|
|
1623
|
+
console.info(PAYMENT_UI_LOG_PREFIX, message, details || {});
|
|
1624
|
+
}
|
|
1625
|
+
function logPaymentWarn(message, details) {
|
|
1626
|
+
if (typeof console === "undefined") return;
|
|
1627
|
+
console.warn(PAYMENT_UI_LOG_PREFIX, message, details || {});
|
|
1628
|
+
}
|
|
1629
|
+
function getPaymentIframeLoadTimeoutMs(options) {
|
|
1630
|
+
const timeout = options?.iframeLoadTimeoutMs;
|
|
1631
|
+
if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
|
|
1632
|
+
return DEFAULT_PAYMENT_IFRAME_LOAD_TIMEOUT_MS;
|
|
1633
|
+
}
|
|
1634
|
+
return Math.max(0, timeout);
|
|
1635
|
+
}
|
|
1636
|
+
function isChinesePaymentLocale(locale) {
|
|
1637
|
+
return locale?.toLowerCase().startsWith("zh") || false;
|
|
1638
|
+
}
|
|
1639
|
+
function getPaymentFallbackText(options) {
|
|
1640
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1641
|
+
return {
|
|
1642
|
+
buttonText: options?.fallbackButtonText || (isChinese ? "\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00" : "Open in new page"),
|
|
1643
|
+
description: isChinese ? "\u5F53\u524D\u7F51\u7EDC\u53EF\u80FD\u8F83\u6162\uFF0C\u5EFA\u8BAE\u91CD\u65B0\u5C1D\u8BD5\u6216\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00\uFF0C\u4EE5\u83B7\u5F97\u66F4\u6D41\u7545\u7684\u652F\u4ED8\u4F53\u9A8C\u3002" : "Your network may be slow. Try again or open the payment page in a new page to continue.",
|
|
1644
|
+
retryText: options?.fallbackRetryText || (isChinese ? "\u91CD\u65B0\u5C1D\u8BD5" : "Try again"),
|
|
1645
|
+
title: isChinese ? "\u652F\u4ED8\u9875\u9762\u6253\u5F00\u8F83\u6162" : "Payment page is taking longer"
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
function getPaymentBrandText(options) {
|
|
1649
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1650
|
+
return {
|
|
1651
|
+
language: isChinese ? "zh" : "en",
|
|
1652
|
+
name: isChinese ? "\u4F18\u6613\u70B9" : "Youidian",
|
|
1653
|
+
subtitle: isChinese ? "\u5F00\u53D1\u8005\u670D\u52A1\u5E73\u53F0" : "Developer Service Platform"
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
function getPaymentBrandLoadingText(options) {
|
|
1657
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1658
|
+
return {
|
|
1659
|
+
language: isChinese ? "zh" : "en",
|
|
1660
|
+
name: isChinese ? "\u4F18\u6613\u70B9" : "Youidian",
|
|
1661
|
+
subtitle: isChinese ? "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0" : "Developer Service"
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
function getPaymentLoadingText(options) {
|
|
1665
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1666
|
+
return options?.loadingTitle || options?.loadingDescription || (isChinese ? "\u52A0\u8F7D\u4E2D..." : "Loading...");
|
|
1667
|
+
}
|
|
1668
|
+
function applyPaymentPanelStyle(panel, theme) {
|
|
1669
|
+
Object.assign(panel.style, {
|
|
1670
|
+
position: "absolute",
|
|
1671
|
+
inset: "0",
|
|
1672
|
+
display: "flex",
|
|
1673
|
+
alignItems: "center",
|
|
1674
|
+
justifyContent: "center",
|
|
1675
|
+
borderRadius: "28px",
|
|
1676
|
+
background: `linear-gradient(180deg, ${theme.surface} 0%, rgba(248,250,252,0.98) 100%)`,
|
|
1677
|
+
color: theme.foreground,
|
|
1678
|
+
padding: "28px 24px",
|
|
1679
|
+
textAlign: "center",
|
|
1680
|
+
zIndex: "1",
|
|
1681
|
+
boxShadow: "none",
|
|
1682
|
+
backdropFilter: "blur(16px)"
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
function createPaymentIcon(type) {
|
|
1686
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
1687
|
+
svg.setAttribute("viewBox", "0 0 24 24");
|
|
1688
|
+
svg.setAttribute("fill", "none");
|
|
1689
|
+
svg.setAttribute("aria-hidden", "true");
|
|
1690
|
+
Object.assign(svg.style, {
|
|
1691
|
+
display: "block",
|
|
1692
|
+
flex: "0 0 auto"
|
|
1693
|
+
});
|
|
1694
|
+
const paths = type === "external" ? [
|
|
1695
|
+
"M7 17L17 7",
|
|
1696
|
+
"M10 7H17V14",
|
|
1697
|
+
"M6.5 6.5H5.5A2.5 2.5 0 0 0 3 9V18.5A2.5 2.5 0 0 0 5.5 21H15A2.5 2.5 0 0 0 17.5 18.5V17.5"
|
|
1698
|
+
] : type === "refresh" ? [
|
|
1699
|
+
"M20 6V11H15",
|
|
1700
|
+
"M4 18V13H9",
|
|
1701
|
+
"M18.2 9A7 7 0 0 0 6.2 6.6L4 9",
|
|
1702
|
+
"M5.8 15A7 7 0 0 0 17.8 17.4L20 15"
|
|
1703
|
+
] : ["M12 7V12L15 14", "M21 12A9 9 0 1 1 3 12A9 9 0 0 1 21 12"];
|
|
1704
|
+
for (const value of paths) {
|
|
1705
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
1706
|
+
path.setAttribute("d", value);
|
|
1707
|
+
path.setAttribute("stroke", "currentColor");
|
|
1708
|
+
path.setAttribute("stroke-width", "2");
|
|
1709
|
+
path.setAttribute("stroke-linecap", "round");
|
|
1710
|
+
path.setAttribute("stroke-linejoin", "round");
|
|
1711
|
+
svg.appendChild(path);
|
|
1712
|
+
}
|
|
1713
|
+
return svg;
|
|
1714
|
+
}
|
|
1715
|
+
function createPaymentFallbackArtwork(theme) {
|
|
1716
|
+
const artwork = document.createElement("div");
|
|
1717
|
+
Object.assign(artwork.style, {
|
|
1718
|
+
height: "164px",
|
|
1719
|
+
margin: "0 auto 34px",
|
|
1720
|
+
position: "relative",
|
|
1721
|
+
width: "184px"
|
|
1722
|
+
});
|
|
1723
|
+
const wash = document.createElement("div");
|
|
1724
|
+
Object.assign(wash.style, {
|
|
1725
|
+
position: "absolute",
|
|
1726
|
+
left: "16px",
|
|
1727
|
+
top: "20px",
|
|
1728
|
+
width: "152px",
|
|
1729
|
+
height: "126px",
|
|
1730
|
+
borderRadius: "48% 52% 43% 57% / 54% 42% 58% 46%",
|
|
1731
|
+
background: `radial-gradient(circle at 48% 42%, ${theme.primary20}, ${theme.primary10} 52%, transparent 76%)`,
|
|
1732
|
+
filter: "blur(1px)",
|
|
1733
|
+
transform: "rotate(-10deg)"
|
|
1734
|
+
});
|
|
1735
|
+
const blob = document.createElement("div");
|
|
1736
|
+
Object.assign(blob.style, {
|
|
1737
|
+
position: "absolute",
|
|
1738
|
+
left: "26px",
|
|
1739
|
+
top: "28px",
|
|
1740
|
+
width: "132px",
|
|
1741
|
+
height: "116px",
|
|
1742
|
+
borderRadius: "42% 58% 53% 47% / 45% 39% 61% 55%",
|
|
1743
|
+
background: `linear-gradient(150deg, ${theme.primary14}, ${theme.primary10})`,
|
|
1744
|
+
boxShadow: `0 30px 64px ${theme.primary14}`,
|
|
1745
|
+
transform: "rotate(8deg)"
|
|
1746
|
+
});
|
|
1747
|
+
const tile = document.createElement("div");
|
|
1748
|
+
Object.assign(tile.style, {
|
|
1749
|
+
position: "absolute",
|
|
1750
|
+
left: "50%",
|
|
1751
|
+
top: "50%",
|
|
1752
|
+
transform: "translate(-50%, -50%) rotate(-4deg)",
|
|
1753
|
+
width: "112px",
|
|
1754
|
+
height: "106px",
|
|
1755
|
+
borderRadius: "38% 62% 50% 50% / 44% 43% 57% 56%",
|
|
1756
|
+
background: `linear-gradient(145deg, ${theme.primary}, ${theme.secondary})`,
|
|
1757
|
+
border: `1px solid ${theme.primary36}`,
|
|
1758
|
+
color: "#ffffff",
|
|
1759
|
+
display: "inline-flex",
|
|
1760
|
+
alignItems: "center",
|
|
1761
|
+
justifyContent: "center",
|
|
1762
|
+
boxShadow: `0 26px 54px ${theme.primary28}`
|
|
1763
|
+
});
|
|
1764
|
+
const icon = createPaymentIcon("slow");
|
|
1765
|
+
Object.assign(icon.style, {
|
|
1766
|
+
width: "52px",
|
|
1767
|
+
height: "52px",
|
|
1768
|
+
transform: "rotate(4deg)"
|
|
1769
|
+
});
|
|
1770
|
+
tile.appendChild(icon);
|
|
1771
|
+
artwork.appendChild(wash);
|
|
1772
|
+
artwork.appendChild(blob);
|
|
1773
|
+
artwork.appendChild(tile);
|
|
1774
|
+
return artwork;
|
|
1775
|
+
}
|
|
1776
|
+
function createPaymentBrandLoading(options, theme) {
|
|
1777
|
+
const brand = getPaymentBrandLoadingText(options);
|
|
1778
|
+
const wrapper = document.createElement("div");
|
|
1779
|
+
Object.assign(wrapper.style, {
|
|
1780
|
+
display: "flex",
|
|
1781
|
+
flexDirection: "column",
|
|
1782
|
+
alignItems: "center",
|
|
1783
|
+
justifyContent: "center",
|
|
1784
|
+
margin: "0 auto 16px"
|
|
1785
|
+
});
|
|
1786
|
+
wrapper.appendChild(
|
|
1787
|
+
createSdkBrandLogo({
|
|
1788
|
+
animated: true,
|
|
1789
|
+
brand,
|
|
1790
|
+
brandWidth: 292,
|
|
1791
|
+
copyWidth: 176,
|
|
1792
|
+
gap: 6,
|
|
1793
|
+
markMarginRight: -10,
|
|
1794
|
+
markSize: 112,
|
|
1795
|
+
nameSize: 39,
|
|
1796
|
+
subtitleMarginTop: 8,
|
|
1797
|
+
subtitleSize: 14,
|
|
1798
|
+
subtitleWeight: "700",
|
|
1799
|
+
theme,
|
|
1800
|
+
variant: "brand"
|
|
1801
|
+
})
|
|
1802
|
+
);
|
|
1803
|
+
return wrapper;
|
|
1804
|
+
}
|
|
1805
|
+
function createPaymentPlatformLogo(options, theme) {
|
|
1806
|
+
const brand = getPaymentBrandText(options);
|
|
1807
|
+
const wrapper = document.createElement("div");
|
|
1808
|
+
Object.assign(wrapper.style, {
|
|
1809
|
+
display: "flex",
|
|
1810
|
+
alignItems: "center",
|
|
1811
|
+
justifyContent: "center",
|
|
1812
|
+
margin: "0 auto 10px"
|
|
1813
|
+
});
|
|
1814
|
+
wrapper.appendChild(
|
|
1815
|
+
createSdkBrandLogo({
|
|
1816
|
+
brand,
|
|
1817
|
+
markSize: 48,
|
|
1818
|
+
nameSize: brand.language === "zh" ? 22 : 22,
|
|
1819
|
+
subtitleSize: brand.language === "zh" ? 9 : 9,
|
|
1820
|
+
theme
|
|
1821
|
+
})
|
|
1822
|
+
);
|
|
1823
|
+
return wrapper;
|
|
1824
|
+
}
|
|
1825
|
+
function createPaymentPanelContent() {
|
|
1826
|
+
const content = document.createElement("div");
|
|
1827
|
+
Object.assign(content.style, {
|
|
1828
|
+
display: "flex",
|
|
1829
|
+
flexDirection: "column",
|
|
1830
|
+
justifyContent: "center",
|
|
1831
|
+
maxWidth: "364px",
|
|
1832
|
+
minHeight: "100%",
|
|
1833
|
+
width: "100%"
|
|
1834
|
+
});
|
|
1835
|
+
return content;
|
|
1836
|
+
}
|
|
1837
|
+
function createPaymentPanelTitle(value, theme) {
|
|
1838
|
+
const title = document.createElement("div");
|
|
1839
|
+
title.textContent = value;
|
|
1840
|
+
Object.assign(title.style, {
|
|
1841
|
+
color: theme?.foreground || "#0f172a",
|
|
1842
|
+
fontSize: "24px",
|
|
1843
|
+
fontWeight: "900",
|
|
1844
|
+
lineHeight: "1.22",
|
|
1845
|
+
marginBottom: "16px"
|
|
1846
|
+
});
|
|
1847
|
+
return title;
|
|
1848
|
+
}
|
|
1849
|
+
function createPaymentPanelDescription(value, theme) {
|
|
1850
|
+
const description = document.createElement("div");
|
|
1851
|
+
description.textContent = value;
|
|
1852
|
+
Object.assign(description.style, {
|
|
1853
|
+
color: theme?.muted || "#64748b",
|
|
1854
|
+
fontSize: "14px",
|
|
1855
|
+
fontWeight: "600",
|
|
1856
|
+
lineHeight: "1.62",
|
|
1857
|
+
margin: "0 auto",
|
|
1858
|
+
maxWidth: "320px"
|
|
1859
|
+
});
|
|
1860
|
+
return description;
|
|
1861
|
+
}
|
|
1862
|
+
function createPaymentLoadingDescription(value, theme) {
|
|
1863
|
+
const description = document.createElement("div");
|
|
1864
|
+
description.textContent = value;
|
|
1865
|
+
Object.assign(description.style, {
|
|
1866
|
+
color: theme?.muted || "#64748b",
|
|
1867
|
+
fontSize: "14px",
|
|
1868
|
+
fontWeight: "500",
|
|
1869
|
+
lineHeight: "1.25",
|
|
1870
|
+
margin: "12px auto 0",
|
|
1871
|
+
maxWidth: "320px"
|
|
1872
|
+
});
|
|
1873
|
+
return description;
|
|
1874
|
+
}
|
|
1875
|
+
function createPaymentFallbackMessage(options) {
|
|
1876
|
+
const message = document.createElement("div");
|
|
1877
|
+
Object.assign(message.style, {
|
|
1878
|
+
margin: "0 auto",
|
|
1879
|
+
textAlign: "center"
|
|
1880
|
+
});
|
|
1881
|
+
message.appendChild(createPaymentFallbackArtwork(options.theme));
|
|
1882
|
+
message.appendChild(createPaymentPanelTitle(options.title, options.theme));
|
|
1883
|
+
message.appendChild(
|
|
1884
|
+
createPaymentPanelDescription(options.description, options.theme)
|
|
1885
|
+
);
|
|
1886
|
+
return message;
|
|
1887
|
+
}
|
|
1888
|
+
function createPaymentLoadingPanel(options) {
|
|
1889
|
+
const panel = document.createElement("div");
|
|
1890
|
+
const theme = resolvePaymentTheme(options);
|
|
1891
|
+
applyPaymentPanelStyle(panel, theme);
|
|
1892
|
+
const content = createPaymentPanelContent();
|
|
1893
|
+
content.appendChild(createPaymentBrandLoading(options, theme));
|
|
1894
|
+
content.appendChild(
|
|
1895
|
+
createPaymentLoadingDescription(getPaymentLoadingText(options), theme)
|
|
1896
|
+
);
|
|
1897
|
+
panel.appendChild(content);
|
|
1898
|
+
return panel;
|
|
1899
|
+
}
|
|
1900
|
+
function createPaymentButton(value, options) {
|
|
1901
|
+
const primary = options?.primary || false;
|
|
1902
|
+
const theme = options?.theme || resolvePaymentTheme();
|
|
1903
|
+
const button = document.createElement("button");
|
|
1904
|
+
button.type = "button";
|
|
1905
|
+
Object.assign(button.style, {
|
|
1906
|
+
width: "100%",
|
|
1907
|
+
height: "50px",
|
|
1908
|
+
borderRadius: "14px",
|
|
1909
|
+
border: primary ? `1px solid ${theme.primary}` : `1px solid ${theme.primary64}`,
|
|
1910
|
+
background: primary ? `linear-gradient(135deg, ${theme.primary}, ${theme.secondary})` : "#ffffff",
|
|
1911
|
+
color: primary ? "#ffffff" : theme.primary,
|
|
1912
|
+
cursor: "pointer",
|
|
1913
|
+
display: "inline-flex",
|
|
1914
|
+
alignItems: "center",
|
|
1915
|
+
justifyContent: "center",
|
|
1916
|
+
gap: "10px",
|
|
1917
|
+
fontSize: "15px",
|
|
1918
|
+
fontWeight: "800",
|
|
1919
|
+
marginTop: primary ? "12px" : "0",
|
|
1920
|
+
boxShadow: primary ? `0 14px 28px ${theme.primary20}` : "none"
|
|
1921
|
+
});
|
|
1922
|
+
if (options?.icon) {
|
|
1923
|
+
const icon = createPaymentIcon(options.icon);
|
|
1924
|
+
Object.assign(icon.style, {
|
|
1925
|
+
width: "17px",
|
|
1926
|
+
height: "17px"
|
|
1927
|
+
});
|
|
1928
|
+
button.appendChild(icon);
|
|
1929
|
+
}
|
|
1930
|
+
const label = document.createElement("span");
|
|
1931
|
+
label.textContent = value;
|
|
1932
|
+
button.appendChild(label);
|
|
1933
|
+
return button;
|
|
1934
|
+
}
|
|
1935
|
+
function createPaymentFallbackPanel(options) {
|
|
1936
|
+
const panel = document.createElement("div");
|
|
1937
|
+
const theme = resolvePaymentTheme(options.paymentOptions);
|
|
1938
|
+
applyPaymentPanelStyle(panel, theme);
|
|
1939
|
+
const content = createPaymentPanelContent();
|
|
1940
|
+
Object.assign(content.style, {
|
|
1941
|
+
justifyContent: "space-between"
|
|
1942
|
+
});
|
|
1943
|
+
const main = document.createElement("div");
|
|
1944
|
+
Object.assign(main.style, {
|
|
1945
|
+
display: "flex",
|
|
1946
|
+
flexDirection: "column",
|
|
1947
|
+
alignItems: "center",
|
|
1948
|
+
marginTop: "38px",
|
|
1949
|
+
width: "100%"
|
|
1950
|
+
});
|
|
1951
|
+
main.appendChild(
|
|
1952
|
+
createPaymentFallbackMessage({
|
|
1953
|
+
description: options.description,
|
|
1954
|
+
theme,
|
|
1955
|
+
title: options.title
|
|
1956
|
+
})
|
|
1957
|
+
);
|
|
1958
|
+
const actions = document.createElement("div");
|
|
1959
|
+
Object.assign(actions.style, {
|
|
1960
|
+
marginTop: "46px",
|
|
1961
|
+
width: "100%"
|
|
1962
|
+
});
|
|
1963
|
+
const retryButton = createPaymentButton(options.retryText, {
|
|
1964
|
+
icon: "refresh",
|
|
1965
|
+
theme
|
|
1966
|
+
});
|
|
1967
|
+
retryButton.onclick = options.onRetry;
|
|
1968
|
+
actions.appendChild(retryButton);
|
|
1969
|
+
const openButton = createPaymentButton(options.buttonText, {
|
|
1970
|
+
icon: "external",
|
|
1971
|
+
primary: true,
|
|
1972
|
+
theme
|
|
1973
|
+
});
|
|
1974
|
+
openButton.onclick = options.onOpen;
|
|
1975
|
+
actions.appendChild(openButton);
|
|
1976
|
+
main.appendChild(actions);
|
|
1977
|
+
content.appendChild(main);
|
|
1978
|
+
content.appendChild(createPaymentPlatformLogo(options.paymentOptions, theme));
|
|
1979
|
+
panel.appendChild(content);
|
|
1980
|
+
return panel;
|
|
1981
|
+
}
|
|
1066
1982
|
var PaymentUI = class extends HostedFrameModal {
|
|
1067
1983
|
constructor() {
|
|
1068
1984
|
super(...arguments);
|
|
@@ -1071,6 +1987,127 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1071
1987
|
__publicField(this, "activeOrderId", null);
|
|
1072
1988
|
__publicField(this, "paymentCompleted", false);
|
|
1073
1989
|
__publicField(this, "cancelRequestedOrderId", null);
|
|
1990
|
+
__publicField(this, "iframeFallbackPanel", null);
|
|
1991
|
+
__publicField(this, "iframeLoadingPanel", null);
|
|
1992
|
+
__publicField(this, "iframeLoadTimer", null);
|
|
1993
|
+
__publicField(this, "iframeReady", false);
|
|
1994
|
+
}
|
|
1995
|
+
cleanupPaymentFrameState() {
|
|
1996
|
+
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
1997
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
1998
|
+
}
|
|
1999
|
+
if (this.iframeFallbackPanel?.parentNode) {
|
|
2000
|
+
this.iframeFallbackPanel.parentNode.removeChild(this.iframeFallbackPanel);
|
|
2001
|
+
}
|
|
2002
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2003
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2004
|
+
}
|
|
2005
|
+
this.iframeFallbackPanel = null;
|
|
2006
|
+
this.iframeLoadingPanel = null;
|
|
2007
|
+
this.iframeLoadTimer = null;
|
|
2008
|
+
this.iframeReady = false;
|
|
2009
|
+
}
|
|
2010
|
+
markPaymentIframeReady() {
|
|
2011
|
+
if (this.iframeReady) return;
|
|
2012
|
+
this.iframeReady = true;
|
|
2013
|
+
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
2014
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
2015
|
+
this.iframeLoadTimer = null;
|
|
2016
|
+
}
|
|
2017
|
+
if (this.iframeFallbackPanel?.parentNode) {
|
|
2018
|
+
this.iframeFallbackPanel.parentNode.removeChild(this.iframeFallbackPanel);
|
|
2019
|
+
}
|
|
2020
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2021
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2022
|
+
}
|
|
2023
|
+
this.iframeFallbackPanel = null;
|
|
2024
|
+
this.iframeLoadingPanel = null;
|
|
2025
|
+
}
|
|
2026
|
+
showPaymentIframeLoading(container, options) {
|
|
2027
|
+
if (this.iframeLoadingPanel || this.iframeReady) return;
|
|
2028
|
+
const panel = createPaymentLoadingPanel(options);
|
|
2029
|
+
this.iframeLoadingPanel = panel;
|
|
2030
|
+
container.appendChild(panel);
|
|
2031
|
+
}
|
|
2032
|
+
openFallbackPaymentPage(finalUrl, options) {
|
|
2033
|
+
if (typeof window === "undefined") return;
|
|
2034
|
+
const popup = window.open(
|
|
2035
|
+
finalUrl,
|
|
2036
|
+
"youidian-payment-checkout",
|
|
2037
|
+
"popup=yes,width=480,height=760,resizable=yes,scrollbars=yes"
|
|
2038
|
+
);
|
|
2039
|
+
if (popup) {
|
|
2040
|
+
logPaymentInfo("Opened hosted checkout fallback page", {
|
|
2041
|
+
checkoutUrl: finalUrl
|
|
2042
|
+
});
|
|
2043
|
+
options?.onFallbackOpen?.(finalUrl);
|
|
2044
|
+
try {
|
|
2045
|
+
popup.focus();
|
|
2046
|
+
} catch {
|
|
2047
|
+
}
|
|
2048
|
+
return;
|
|
2049
|
+
}
|
|
2050
|
+
logPaymentWarn("Hosted checkout fallback popup was blocked", {
|
|
2051
|
+
checkoutUrl: finalUrl
|
|
2052
|
+
});
|
|
2053
|
+
options?.onFallbackBlocked?.(finalUrl);
|
|
2054
|
+
window.location.assign(finalUrl);
|
|
2055
|
+
}
|
|
2056
|
+
showPaymentIframeFallback(options) {
|
|
2057
|
+
if (this.iframeReady || this.iframeFallbackPanel) return;
|
|
2058
|
+
const { container, finalUrl, paymentOptions } = options;
|
|
2059
|
+
logPaymentWarn("Hosted checkout iframe did not report ready in time", {
|
|
2060
|
+
checkoutUrl: finalUrl
|
|
2061
|
+
});
|
|
2062
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2063
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2064
|
+
}
|
|
2065
|
+
this.iframeLoadingPanel = null;
|
|
2066
|
+
const fallbackText = getPaymentFallbackText(paymentOptions);
|
|
2067
|
+
const panel = createPaymentFallbackPanel({
|
|
2068
|
+
buttonText: fallbackText.buttonText,
|
|
2069
|
+
description: fallbackText.description,
|
|
2070
|
+
onOpen: () => {
|
|
2071
|
+
this.openFallbackPaymentPage(finalUrl, paymentOptions);
|
|
2072
|
+
},
|
|
2073
|
+
onRetry: () => {
|
|
2074
|
+
this.iframeFallbackPanel = null;
|
|
2075
|
+
if (panel.parentNode) {
|
|
2076
|
+
panel.parentNode.removeChild(panel);
|
|
2077
|
+
}
|
|
2078
|
+
this.iframeReady = false;
|
|
2079
|
+
this.showPaymentIframeLoading(container, paymentOptions);
|
|
2080
|
+
if (this.iframe) {
|
|
2081
|
+
this.iframe.src = finalUrl;
|
|
2082
|
+
}
|
|
2083
|
+
this.startPaymentIframeWatchdog({
|
|
2084
|
+
container,
|
|
2085
|
+
finalUrl,
|
|
2086
|
+
paymentOptions
|
|
2087
|
+
});
|
|
2088
|
+
},
|
|
2089
|
+
paymentOptions,
|
|
2090
|
+
retryText: fallbackText.retryText,
|
|
2091
|
+
title: fallbackText.title
|
|
2092
|
+
});
|
|
2093
|
+
this.iframeFallbackPanel = panel;
|
|
2094
|
+
container.appendChild(panel);
|
|
2095
|
+
paymentOptions?.onFallbackVisible?.();
|
|
2096
|
+
}
|
|
2097
|
+
startPaymentIframeWatchdog(options) {
|
|
2098
|
+
if (typeof window === "undefined") return;
|
|
2099
|
+
if (this.iframeLoadTimer) {
|
|
2100
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
2101
|
+
}
|
|
2102
|
+
const timeoutMs = getPaymentIframeLoadTimeoutMs(options.paymentOptions);
|
|
2103
|
+
if (timeoutMs === 0) {
|
|
2104
|
+
this.showPaymentIframeFallback(options);
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
this.iframeLoadTimer = window.setTimeout(() => {
|
|
2108
|
+
this.iframeLoadTimer = null;
|
|
2109
|
+
this.showPaymentIframeFallback(options);
|
|
2110
|
+
}, timeoutMs);
|
|
1074
2111
|
}
|
|
1075
2112
|
cancelHostedOrder(reason = "user_cancel", orderId) {
|
|
1076
2113
|
const targetOrderId = orderId || this.activeOrderId;
|
|
@@ -1113,6 +2150,7 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1113
2150
|
this.activeOrderId = null;
|
|
1114
2151
|
this.paymentCompleted = false;
|
|
1115
2152
|
this.cancelRequestedOrderId = null;
|
|
2153
|
+
this.cleanupPaymentFrameState();
|
|
1116
2154
|
if (typeof urlOrParams === "string") {
|
|
1117
2155
|
checkoutUrl = urlOrParams;
|
|
1118
2156
|
try {
|
|
@@ -1181,14 +2219,21 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1181
2219
|
checkoutUrl,
|
|
1182
2220
|
getAutoResolvedLocale(options?.locale)
|
|
1183
2221
|
);
|
|
1184
|
-
this.openHostedFrame(finalUrl, {
|
|
2222
|
+
const hostedFrame = this.openHostedFrame(finalUrl, {
|
|
1185
2223
|
allowedOrigin: options?.allowedOrigin,
|
|
2224
|
+
height: "min(760px, calc(100vh - 32px))",
|
|
1186
2225
|
onCloseButton: () => {
|
|
1187
2226
|
this.cancelHostedOrder("modal_close");
|
|
1188
2227
|
options?.onCancel?.(this.activeOrderId || void 0);
|
|
1189
2228
|
},
|
|
1190
|
-
onMessage: (data, container) => {
|
|
2229
|
+
onMessage: (data, container, event) => {
|
|
2230
|
+
const isIframeMessage = event.source === this.iframe?.contentWindow;
|
|
2231
|
+
if (isIframeMessage && (data.type === "PAYMENT_READY" || data.type === "PAYMENT_RESIZE" || data.type === "PAYMENT_STARTED")) {
|
|
2232
|
+
this.markPaymentIframeReady();
|
|
2233
|
+
}
|
|
1191
2234
|
switch (data.type) {
|
|
2235
|
+
case "PAYMENT_READY":
|
|
2236
|
+
break;
|
|
1192
2237
|
case "PAYMENT_STARTED":
|
|
1193
2238
|
if (data.orderId) {
|
|
1194
2239
|
this.activeOrderId = data.orderId;
|
|
@@ -1203,11 +2248,6 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1203
2248
|
options?.onCancel?.(data.orderId);
|
|
1204
2249
|
break;
|
|
1205
2250
|
case "PAYMENT_RESIZE":
|
|
1206
|
-
if (data.height) {
|
|
1207
|
-
const maxHeight = window.innerHeight * 0.9;
|
|
1208
|
-
const newHeight = Math.min(data.height, maxHeight);
|
|
1209
|
-
container.style.height = `${newHeight}px`;
|
|
1210
|
-
}
|
|
1211
2251
|
break;
|
|
1212
2252
|
case "PAYMENT_CLOSE":
|
|
1213
2253
|
this.cancelHostedOrder("payment_close", data.orderId);
|
|
@@ -1215,8 +2255,21 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1215
2255
|
options?.onClose?.();
|
|
1216
2256
|
break;
|
|
1217
2257
|
}
|
|
1218
|
-
}
|
|
2258
|
+
},
|
|
2259
|
+
width: "min(450px, 100%)"
|
|
1219
2260
|
});
|
|
2261
|
+
if (hostedFrame) {
|
|
2262
|
+
this.showPaymentIframeLoading(hostedFrame.container, options);
|
|
2263
|
+
this.startPaymentIframeWatchdog({
|
|
2264
|
+
container: hostedFrame.container,
|
|
2265
|
+
finalUrl,
|
|
2266
|
+
paymentOptions: options
|
|
2267
|
+
});
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
close() {
|
|
2271
|
+
super.close();
|
|
2272
|
+
this.cleanupPaymentFrameState();
|
|
1220
2273
|
}
|
|
1221
2274
|
/**
|
|
1222
2275
|
* Poll order status from integrator's API endpoint
|
|
@@ -1262,14 +2315,40 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1262
2315
|
});
|
|
1263
2316
|
}
|
|
1264
2317
|
};
|
|
2318
|
+
var MessageUI = class {
|
|
2319
|
+
openWechatBinding(options) {
|
|
2320
|
+
const bindingUrl = options.bindingUrl?.trim();
|
|
2321
|
+
if (!bindingUrl) {
|
|
2322
|
+
throw new Error("bindingUrl is required");
|
|
2323
|
+
}
|
|
2324
|
+
if (options.displayMode === "popup") {
|
|
2325
|
+
const popup = window.open(
|
|
2326
|
+
bindingUrl,
|
|
2327
|
+
options.popupName || "youidian-wechat-message-binding",
|
|
2328
|
+
"width=480,height=720,noopener,noreferrer"
|
|
2329
|
+
);
|
|
2330
|
+
if (!popup) {
|
|
2331
|
+
window.location.href = bindingUrl;
|
|
2332
|
+
}
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
window.location.href = bindingUrl;
|
|
2336
|
+
}
|
|
2337
|
+
};
|
|
2338
|
+
function createMessageUI() {
|
|
2339
|
+
return new MessageUI();
|
|
2340
|
+
}
|
|
1265
2341
|
function createPaymentUI() {
|
|
1266
2342
|
return new PaymentUI();
|
|
1267
2343
|
}
|
|
1268
2344
|
export {
|
|
1269
2345
|
LoginUI,
|
|
2346
|
+
MessageUI,
|
|
1270
2347
|
PaymentUI,
|
|
1271
2348
|
createLoginUI,
|
|
2349
|
+
createMessageUI,
|
|
1272
2350
|
createPaymentUI,
|
|
2351
|
+
detectLoginEnvironment,
|
|
1273
2352
|
handleLoginCallbackIfPresent
|
|
1274
2353
|
};
|
|
1275
2354
|
//# sourceMappingURL=client.js.map
|