@magicfeedback/popup-sdk 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -1
- package/dist/assets/assets/style.css +63 -14
- package/dist/{chunk-AN7JIVWB.mjs → chunk-W6MPSWMS.mjs} +352 -15
- package/dist/chunk-W6MPSWMS.mjs.map +1 -0
- package/dist/{chunk-Z3LLJMSH.mjs → chunk-WNIUIOKF.mjs} +332 -15
- package/dist/chunk-WNIUIOKF.mjs.map +1 -0
- package/dist/index.d.mts +99 -1
- package/dist/index.d.ts +99 -1
- package/dist/index.js +1647 -1366
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -28
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +13 -0
- package/dist/react-native.d.ts +13 -0
- package/dist/react-native.js +550 -55
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +189 -28
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-SELXQ3UE.mjs → renderPopup-EWGKG53W.mjs} +42 -18
- package/dist/renderPopup-EWGKG53W.mjs.map +1 -0
- package/dist/renderPopup-HHQMAW3G.mjs +3114 -0
- package/dist/renderPopup-HHQMAW3G.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-AN7JIVWB.mjs.map +0 -1
- package/dist/chunk-Z3LLJMSH.mjs.map +0 -1
- package/dist/renderPopup-M6MKTDEH.mjs +0 -3330
- package/dist/renderPopup-M6MKTDEH.mjs.map +0 -1
- package/dist/renderPopup-SELXQ3UE.mjs.map +0 -1
package/dist/react-native.js
CHANGED
|
@@ -178,6 +178,274 @@ var init_font = __esm({
|
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
+
// src/i18n/labels.ts
|
|
182
|
+
function resolveLocale(lang) {
|
|
183
|
+
if (typeof lang !== "string") return "en";
|
|
184
|
+
const normalized = lang.trim().toLowerCase().replace(/_/g, "-");
|
|
185
|
+
if (!normalized) return "en";
|
|
186
|
+
if (normalized === "zh" || normalized.startsWith("zh-")) return "zh-CN";
|
|
187
|
+
const primary = normalized.split("-")[0];
|
|
188
|
+
switch (primary) {
|
|
189
|
+
case "en":
|
|
190
|
+
return "en";
|
|
191
|
+
case "es":
|
|
192
|
+
return "es";
|
|
193
|
+
case "da":
|
|
194
|
+
return "da";
|
|
195
|
+
case "no":
|
|
196
|
+
case "nb":
|
|
197
|
+
case "nn":
|
|
198
|
+
return "no";
|
|
199
|
+
case "sv":
|
|
200
|
+
return "sv";
|
|
201
|
+
case "fi":
|
|
202
|
+
return "fi";
|
|
203
|
+
case "de":
|
|
204
|
+
return "de";
|
|
205
|
+
case "fr":
|
|
206
|
+
return "fr";
|
|
207
|
+
case "pt":
|
|
208
|
+
return "pt";
|
|
209
|
+
case "ar":
|
|
210
|
+
return "ar";
|
|
211
|
+
case "bn":
|
|
212
|
+
return "bn";
|
|
213
|
+
default:
|
|
214
|
+
return "en";
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function isRtlLanguage(lang) {
|
|
218
|
+
return RTL_LOCALES.includes(resolveLocale(lang));
|
|
219
|
+
}
|
|
220
|
+
function directionFor(lang) {
|
|
221
|
+
return isRtlLanguage(lang) ? "rtl" : "ltr";
|
|
222
|
+
}
|
|
223
|
+
function getLabels(lang) {
|
|
224
|
+
return LABELS[resolveLocale(lang)];
|
|
225
|
+
}
|
|
226
|
+
function resolveActionLabels(actions, lang) {
|
|
227
|
+
const labels = getLabels(lang);
|
|
228
|
+
const pick = (value, fallback) => {
|
|
229
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
230
|
+
return trimmed ? value : fallback;
|
|
231
|
+
};
|
|
232
|
+
return {
|
|
233
|
+
accept: pick(actions?.accept?.label, labels.accept),
|
|
234
|
+
decline: pick(actions?.decline?.label, labels.decline),
|
|
235
|
+
start: pick(actions?.start?.label, labels.start),
|
|
236
|
+
complete: pick(actions?.complete?.label, labels.complete),
|
|
237
|
+
back: pick(actions?.back?.label, labels.back)
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
var EN, ES, DA, NO, SV, FI, DE, FR, PT, AR, BN, ZH_CN, LABELS, RTL_LOCALES, RESOLVE_LOCALE_JS;
|
|
241
|
+
var init_labels = __esm({
|
|
242
|
+
"src/i18n/labels.ts"() {
|
|
243
|
+
"use strict";
|
|
244
|
+
EN = {
|
|
245
|
+
accept: "Send",
|
|
246
|
+
decline: "Cancel",
|
|
247
|
+
start: "Start survey",
|
|
248
|
+
complete: "Complete survey",
|
|
249
|
+
back: "Back",
|
|
250
|
+
question: "Question",
|
|
251
|
+
of: "of",
|
|
252
|
+
followUp: "Follow-up",
|
|
253
|
+
closeAria: "Close popup",
|
|
254
|
+
loadingAria: "Loading survey",
|
|
255
|
+
errorRequired: "Please answer the required question to continue.",
|
|
256
|
+
errorSubmit: "An error occurred while submitting. Please try again or close the popup."
|
|
257
|
+
};
|
|
258
|
+
ES = {
|
|
259
|
+
accept: "Enviar",
|
|
260
|
+
decline: "Cancelar",
|
|
261
|
+
start: "Empezar encuesta",
|
|
262
|
+
complete: "Completar encuesta",
|
|
263
|
+
back: "Atr\xE1s",
|
|
264
|
+
question: "Pregunta",
|
|
265
|
+
of: "de",
|
|
266
|
+
followUp: "Seguimiento",
|
|
267
|
+
closeAria: "Cerrar ventana emergente",
|
|
268
|
+
loadingAria: "Cargando encuesta",
|
|
269
|
+
errorRequired: "Responde la pregunta obligatoria para continuar.",
|
|
270
|
+
errorSubmit: "Se produjo un error al enviar. Int\xE9ntalo de nuevo o cierra la ventana."
|
|
271
|
+
};
|
|
272
|
+
DA = {
|
|
273
|
+
accept: "Send",
|
|
274
|
+
decline: "Annuller",
|
|
275
|
+
start: "Start unders\xF8gelse",
|
|
276
|
+
complete: "Afslut unders\xF8gelse",
|
|
277
|
+
back: "Tilbage",
|
|
278
|
+
question: "Sp\xF8rgsm\xE5l",
|
|
279
|
+
of: "af",
|
|
280
|
+
followUp: "Opf\xF8lgning",
|
|
281
|
+
closeAria: "Luk pop op",
|
|
282
|
+
loadingAria: "Indl\xE6ser unders\xF8gelse",
|
|
283
|
+
errorRequired: "Besvar venligst det obligatoriske sp\xF8rgsm\xE5l for at forts\xE6tte.",
|
|
284
|
+
errorSubmit: "Der opstod en fejl under afsendelsen. Pr\xF8v igen, eller luk pop op-vinduet."
|
|
285
|
+
};
|
|
286
|
+
NO = {
|
|
287
|
+
accept: "Send",
|
|
288
|
+
decline: "Avbryt",
|
|
289
|
+
start: "Start unders\xF8kelse",
|
|
290
|
+
complete: "Fullf\xF8r unders\xF8kelse",
|
|
291
|
+
back: "Tilbake",
|
|
292
|
+
question: "Sp\xF8rsm\xE5l",
|
|
293
|
+
of: "av",
|
|
294
|
+
followUp: "Oppf\xF8lging",
|
|
295
|
+
closeAria: "Lukk popup",
|
|
296
|
+
loadingAria: "Laster unders\xF8kelse",
|
|
297
|
+
errorRequired: "Svar p\xE5 det obligatoriske sp\xF8rsm\xE5let for \xE5 fortsette.",
|
|
298
|
+
errorSubmit: "Det oppstod en feil under innsendingen. Pr\xF8v igjen, eller lukk popupen."
|
|
299
|
+
};
|
|
300
|
+
SV = {
|
|
301
|
+
accept: "Skicka",
|
|
302
|
+
decline: "Avbryt",
|
|
303
|
+
start: "Starta unders\xF6kning",
|
|
304
|
+
complete: "Slutf\xF6r unders\xF6kning",
|
|
305
|
+
back: "Tillbaka",
|
|
306
|
+
question: "Fr\xE5ga",
|
|
307
|
+
of: "av",
|
|
308
|
+
followUp: "Uppf\xF6ljning",
|
|
309
|
+
closeAria: "St\xE4ng popup",
|
|
310
|
+
loadingAria: "Laddar unders\xF6kning",
|
|
311
|
+
errorRequired: "Svara p\xE5 den obligatoriska fr\xE5gan f\xF6r att forts\xE4tta.",
|
|
312
|
+
errorSubmit: "Ett fel uppstod vid inskickningen. F\xF6rs\xF6k igen eller st\xE4ng popupen."
|
|
313
|
+
};
|
|
314
|
+
FI = {
|
|
315
|
+
accept: "L\xE4het\xE4",
|
|
316
|
+
decline: "Peruuta",
|
|
317
|
+
start: "Aloita kysely",
|
|
318
|
+
complete: "Viimeistele kysely",
|
|
319
|
+
back: "Takaisin",
|
|
320
|
+
question: "Kysymys",
|
|
321
|
+
of: "/",
|
|
322
|
+
followUp: "Jatkokysymys",
|
|
323
|
+
closeAria: "Sulje ponnahdusikkuna",
|
|
324
|
+
loadingAria: "Ladataan kysely\xE4",
|
|
325
|
+
errorRequired: "Vastaa pakolliseen kysymykseen jatkaaksesi.",
|
|
326
|
+
errorSubmit: "L\xE4hetyksess\xE4 tapahtui virhe. Yrit\xE4 uudelleen tai sulje ponnahdusikkuna."
|
|
327
|
+
};
|
|
328
|
+
DE = {
|
|
329
|
+
accept: "Senden",
|
|
330
|
+
decline: "Abbrechen",
|
|
331
|
+
start: "Umfrage starten",
|
|
332
|
+
complete: "Umfrage abschlie\xDFen",
|
|
333
|
+
back: "Zur\xFCck",
|
|
334
|
+
question: "Frage",
|
|
335
|
+
of: "von",
|
|
336
|
+
followUp: "Folgefrage",
|
|
337
|
+
closeAria: "Popup schlie\xDFen",
|
|
338
|
+
loadingAria: "Umfrage wird geladen",
|
|
339
|
+
errorRequired: "Bitte beantworte die Pflichtfrage, um fortzufahren.",
|
|
340
|
+
errorSubmit: "Beim Senden ist ein Fehler aufgetreten. Versuche es erneut oder schlie\xDFe das Popup."
|
|
341
|
+
};
|
|
342
|
+
FR = {
|
|
343
|
+
accept: "Envoyer",
|
|
344
|
+
decline: "Annuler",
|
|
345
|
+
start: "Commencer l'enqu\xEAte",
|
|
346
|
+
complete: "Terminer l'enqu\xEAte",
|
|
347
|
+
back: "Retour",
|
|
348
|
+
question: "Question",
|
|
349
|
+
of: "sur",
|
|
350
|
+
followUp: "Question compl\xE9mentaire",
|
|
351
|
+
closeAria: "Fermer la fen\xEAtre",
|
|
352
|
+
loadingAria: "Chargement de l'enqu\xEAte",
|
|
353
|
+
errorRequired: "Veuillez r\xE9pondre \xE0 la question obligatoire pour continuer.",
|
|
354
|
+
errorSubmit: "Une erreur s'est produite lors de l'envoi. R\xE9essayez ou fermez la fen\xEAtre."
|
|
355
|
+
};
|
|
356
|
+
PT = {
|
|
357
|
+
accept: "Enviar",
|
|
358
|
+
decline: "Cancelar",
|
|
359
|
+
start: "Iniciar question\xE1rio",
|
|
360
|
+
complete: "Concluir question\xE1rio",
|
|
361
|
+
back: "Voltar",
|
|
362
|
+
question: "Pergunta",
|
|
363
|
+
of: "de",
|
|
364
|
+
followUp: "Seguimento",
|
|
365
|
+
closeAria: "Fechar janela",
|
|
366
|
+
loadingAria: "A carregar question\xE1rio",
|
|
367
|
+
errorRequired: "Responda \xE0 pergunta obrigat\xF3ria para continuar.",
|
|
368
|
+
errorSubmit: "Ocorreu um erro ao enviar. Tente novamente ou feche a janela."
|
|
369
|
+
};
|
|
370
|
+
AR = {
|
|
371
|
+
accept: "\u0625\u0631\u0633\u0627\u0644",
|
|
372
|
+
decline: "\u0625\u0644\u063A\u0627\u0621",
|
|
373
|
+
start: "\u0627\u0628\u062F\u0623 \u0627\u0644\u0627\u0633\u062A\u0628\u064A\u0627\u0646",
|
|
374
|
+
complete: "\u0625\u0646\u0647\u0627\u0621 \u0627\u0644\u0627\u0633\u062A\u0628\u064A\u0627\u0646",
|
|
375
|
+
back: "\u0631\u062C\u0648\u0639",
|
|
376
|
+
question: "\u0633\u0624\u0627\u0644",
|
|
377
|
+
of: "\u0645\u0646",
|
|
378
|
+
followUp: "\u0633\u0624\u0627\u0644 \u0645\u062A\u0627\u0628\u0639\u0629",
|
|
379
|
+
closeAria: "\u0625\u063A\u0644\u0627\u0642 \u0627\u0644\u0646\u0627\u0641\u0630\u0629 \u0627\u0644\u0645\u0646\u0628\u062B\u0642\u0629",
|
|
380
|
+
loadingAria: "\u062C\u0627\u0631\u064D \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0627\u0633\u062A\u0628\u064A\u0627\u0646",
|
|
381
|
+
errorRequired: "\u064A\u0631\u062C\u0649 \u0627\u0644\u0625\u062C\u0627\u0628\u0629 \u0639\u0644\u0649 \u0627\u0644\u0633\u0624\u0627\u0644 \u0627\u0644\u0645\u0637\u0644\u0648\u0628 \u0644\u0644\u0645\u062A\u0627\u0628\u0639\u0629.",
|
|
382
|
+
errorSubmit: "\u062D\u062F\u062B \u062E\u0637\u0623 \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0625\u0631\u0633\u0627\u0644. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649 \u0623\u0648 \u0625\u063A\u0644\u0627\u0642 \u0627\u0644\u0646\u0627\u0641\u0630\u0629."
|
|
383
|
+
};
|
|
384
|
+
BN = {
|
|
385
|
+
accept: "\u09AA\u09BE\u09A0\u09BE\u09A8",
|
|
386
|
+
decline: "\u09AC\u09BE\u09A4\u09BF\u09B2",
|
|
387
|
+
start: "\u099C\u09B0\u09BF\u09AA \u09B6\u09C1\u09B0\u09C1 \u0995\u09B0\u09C1\u09A8",
|
|
388
|
+
complete: "\u099C\u09B0\u09BF\u09AA \u09B8\u09AE\u09CD\u09AA\u09C2\u09B0\u09CD\u09A3 \u0995\u09B0\u09C1\u09A8",
|
|
389
|
+
back: "\u09AA\u09BF\u099B\u09A8\u09C7",
|
|
390
|
+
question: "\u09AA\u09CD\u09B0\u09B6\u09CD\u09A8",
|
|
391
|
+
of: "/",
|
|
392
|
+
followUp: "\u09AB\u09B2\u09CB-\u0986\u09AA",
|
|
393
|
+
closeAria: "\u09AA\u09AA\u0986\u09AA \u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C1\u09A8",
|
|
394
|
+
loadingAria: "\u099C\u09B0\u09BF\u09AA \u09B2\u09CB\u09A1 \u09B9\u099A\u09CD\u099B\u09C7",
|
|
395
|
+
errorRequired: "\u099A\u09BE\u09B2\u09BF\u09AF\u09BC\u09C7 \u09AF\u09C7\u09A4\u09C7 \u0986\u09AC\u09B6\u09CD\u09AF\u0995 \u09AA\u09CD\u09B0\u09B6\u09CD\u09A8\u09C7\u09B0 \u0989\u09A4\u09CD\u09A4\u09B0 \u09A6\u09BF\u09A8\u0964",
|
|
396
|
+
errorSubmit: "\u099C\u09AE\u09BE \u09A6\u09C7\u0993\u09AF\u09BC\u09BE\u09B0 \u09B8\u09AE\u09AF\u09BC \u098F\u0995\u099F\u09BF \u09A4\u09CD\u09B0\u09C1\u099F\u09BF \u0998\u099F\u09C7\u099B\u09C7\u0964 \u0986\u09AC\u09BE\u09B0 \u099A\u09C7\u09B7\u09CD\u099F\u09BE \u0995\u09B0\u09C1\u09A8 \u09AC\u09BE \u09AA\u09AA\u0986\u09AA \u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C1\u09A8\u0964"
|
|
397
|
+
};
|
|
398
|
+
ZH_CN = {
|
|
399
|
+
accept: "\u53D1\u9001",
|
|
400
|
+
decline: "\u53D6\u6D88",
|
|
401
|
+
start: "\u5F00\u59CB\u95EE\u5377",
|
|
402
|
+
complete: "\u5B8C\u6210\u95EE\u5377",
|
|
403
|
+
back: "\u8FD4\u56DE",
|
|
404
|
+
question: "\u95EE\u9898",
|
|
405
|
+
of: "/",
|
|
406
|
+
followUp: "\u8FFD\u95EE",
|
|
407
|
+
closeAria: "\u5173\u95ED\u5F39\u7A97",
|
|
408
|
+
loadingAria: "\u6B63\u5728\u52A0\u8F7D\u95EE\u5377",
|
|
409
|
+
errorRequired: "\u8BF7\u56DE\u7B54\u5FC5\u7B54\u9898\u540E\u7EE7\u7EED\u3002",
|
|
410
|
+
errorSubmit: "\u63D0\u4EA4\u65F6\u51FA\u9519\u3002\u8BF7\u91CD\u8BD5\u6216\u5173\u95ED\u5F39\u7A97\u3002"
|
|
411
|
+
};
|
|
412
|
+
LABELS = {
|
|
413
|
+
en: EN,
|
|
414
|
+
es: ES,
|
|
415
|
+
da: DA,
|
|
416
|
+
no: NO,
|
|
417
|
+
sv: SV,
|
|
418
|
+
fi: FI,
|
|
419
|
+
de: DE,
|
|
420
|
+
fr: FR,
|
|
421
|
+
pt: PT,
|
|
422
|
+
ar: AR,
|
|
423
|
+
bn: BN,
|
|
424
|
+
"zh-CN": ZH_CN
|
|
425
|
+
};
|
|
426
|
+
RTL_LOCALES = ["ar"];
|
|
427
|
+
RESOLVE_LOCALE_JS = `function ddResolveLocale(lang){
|
|
428
|
+
if(typeof lang!=='string') return 'en';
|
|
429
|
+
var n=lang.trim().toLowerCase().replace(/_/g,'-');
|
|
430
|
+
if(!n) return 'en';
|
|
431
|
+
if(n==='zh'||n.indexOf('zh-')===0) return 'zh-CN';
|
|
432
|
+
var p=n.split('-')[0];
|
|
433
|
+
if(p==='en') return 'en';
|
|
434
|
+
if(p==='es') return 'es';
|
|
435
|
+
if(p==='da') return 'da';
|
|
436
|
+
if(p==='no'||p==='nb'||p==='nn') return 'no';
|
|
437
|
+
if(p==='sv') return 'sv';
|
|
438
|
+
if(p==='fi') return 'fi';
|
|
439
|
+
if(p==='de') return 'de';
|
|
440
|
+
if(p==='fr') return 'fr';
|
|
441
|
+
if(p==='pt') return 'pt';
|
|
442
|
+
if(p==='ar') return 'ar';
|
|
443
|
+
if(p==='bn') return 'bn';
|
|
444
|
+
return 'en';
|
|
445
|
+
}`;
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
181
449
|
// src/assets/style.css
|
|
182
450
|
var style_default;
|
|
183
451
|
var init_style = __esm({
|
|
@@ -185,7 +453,7 @@ var init_style = __esm({
|
|
|
185
453
|
style_default = `/**
|
|
186
454
|
* NO EDITAR A MANO \u2014 generado por scripts/vendor-survey-css.mjs
|
|
187
455
|
*
|
|
188
|
-
* Copia de @magicfeedback/native@2.2.
|
|
456
|
+
* Copia de @magicfeedback/native@2.2.22 \u2192 dist/styles/magicfeedback-default.css
|
|
189
457
|
* (la hoja can\xF3nica del paquete, la que apunta su campo "style"), con estos cambios locales:
|
|
190
458
|
*
|
|
191
459
|
* 1. Sin el @import de Google Fonts (Nunito): no queremos una petici\xF3n externa desde la
|
|
@@ -405,7 +673,7 @@ var init_style = __esm({
|
|
|
405
673
|
font-weight: var(--mf-font-weight-bold);
|
|
406
674
|
line-height: 1.3;
|
|
407
675
|
margin: var(--mf-space-lg) 0 var(--mf-space-sm);
|
|
408
|
-
text-align:
|
|
676
|
+
text-align: start;
|
|
409
677
|
}
|
|
410
678
|
|
|
411
679
|
.magicfeedback-info-message h1, .magicfeedback-start-message h1 { font-size: var(--mf-font-size-xl); }
|
|
@@ -444,7 +712,7 @@ var init_style = __esm({
|
|
|
444
712
|
.magicfeedback-start-message ul,
|
|
445
713
|
.magicfeedback-start-message ol {
|
|
446
714
|
margin: 0 0 var(--mf-space-md);
|
|
447
|
-
padding-
|
|
715
|
+
padding-inline-start: var(--mf-space-xl);
|
|
448
716
|
color: var(--mf-text-secondary);
|
|
449
717
|
line-height: var(--mf-line-height);
|
|
450
718
|
}
|
|
@@ -458,7 +726,7 @@ var init_style = __esm({
|
|
|
458
726
|
.magicfeedback-start-message blockquote {
|
|
459
727
|
margin: 0 0 var(--mf-space-md);
|
|
460
728
|
padding: var(--mf-space-sm) var(--mf-space-md);
|
|
461
|
-
border-
|
|
729
|
+
border-inline-start: 3px solid var(--mf-primary-border);
|
|
462
730
|
color: var(--mf-text-secondary);
|
|
463
731
|
font-style: italic;
|
|
464
732
|
}
|
|
@@ -547,7 +815,7 @@ var init_style = __esm({
|
|
|
547
815
|
font-weight: var(--mf-font-weight-bold);
|
|
548
816
|
color: var(--mf-text-primary);
|
|
549
817
|
line-height: var(--mf-line-height);
|
|
550
|
-
text-align:
|
|
818
|
+
text-align: start;
|
|
551
819
|
letter-spacing: -0.01em;
|
|
552
820
|
}
|
|
553
821
|
|
|
@@ -623,7 +891,7 @@ var init_style = __esm({
|
|
|
623
891
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
|
|
624
892
|
background-repeat: no-repeat;
|
|
625
893
|
background-position: right var(--mf-space-md) center;
|
|
626
|
-
padding-
|
|
894
|
+
padding-inline-end: var(--mf-space-xl);
|
|
627
895
|
}
|
|
628
896
|
|
|
629
897
|
/* Error State */
|
|
@@ -687,7 +955,7 @@ div.magicfeedback-radio {
|
|
|
687
955
|
.magicfeedback-checkbox label,
|
|
688
956
|
.magicfeedback-radio-container label {
|
|
689
957
|
font-size: var(--mf-font-size-base);
|
|
690
|
-
text-align:
|
|
958
|
+
text-align: start;
|
|
691
959
|
color: var(--mf-text-primary);
|
|
692
960
|
cursor: pointer;
|
|
693
961
|
margin: 0;
|
|
@@ -785,7 +1053,7 @@ div.magicfeedback-radio {
|
|
|
785
1053
|
}
|
|
786
1054
|
|
|
787
1055
|
.magicfeedback-rating-placeholder-value:last-child {
|
|
788
|
-
text-align:
|
|
1056
|
+
text-align: end;
|
|
789
1057
|
}
|
|
790
1058
|
|
|
791
1059
|
/* Rating with Images */
|
|
@@ -868,7 +1136,7 @@ div.magicfeedback-radio {
|
|
|
868
1136
|
}
|
|
869
1137
|
|
|
870
1138
|
.magicfeedback-rating-number-scale-label:last-child {
|
|
871
|
-
text-align:
|
|
1139
|
+
text-align: end;
|
|
872
1140
|
}
|
|
873
1141
|
|
|
874
1142
|
/* Column, no per-option text: each row is its own separated chip, so
|
|
@@ -1186,7 +1454,7 @@ div.magicfeedback-radio {
|
|
|
1186
1454
|
}
|
|
1187
1455
|
|
|
1188
1456
|
.magicfeedback-multi-question-matrix-label {
|
|
1189
|
-
text-align:
|
|
1457
|
+
text-align: start;
|
|
1190
1458
|
font-size: var(--mf-font-size-base);
|
|
1191
1459
|
color: var(--mf-text-primary);
|
|
1192
1460
|
}
|
|
@@ -1221,7 +1489,7 @@ div.magicfeedback-radio {
|
|
|
1221
1489
|
.magicfeedback-priority-list-item-label {
|
|
1222
1490
|
flex: 1;
|
|
1223
1491
|
font-size: var(--mf-font-size-base);
|
|
1224
|
-
text-align:
|
|
1492
|
+
text-align: start;
|
|
1225
1493
|
color: var(--mf-text-primary);
|
|
1226
1494
|
margin: 0;
|
|
1227
1495
|
}
|
|
@@ -1313,7 +1581,7 @@ div.magicfeedback-radio {
|
|
|
1313
1581
|
.magicfeedback-consent-container label {
|
|
1314
1582
|
flex: 1;
|
|
1315
1583
|
font-size: var(--mf-font-size-sm);
|
|
1316
|
-
text-align:
|
|
1584
|
+
text-align: start;
|
|
1317
1585
|
color: var(--mf-text-secondary);
|
|
1318
1586
|
line-height: var(--mf-line-height);
|
|
1319
1587
|
cursor: pointer;
|
|
@@ -1465,7 +1733,7 @@ div.magicfeedback-radio {
|
|
|
1465
1733
|
}
|
|
1466
1734
|
|
|
1467
1735
|
.magicfeedback-modal-counter {
|
|
1468
|
-
margin-
|
|
1736
|
+
margin-inline-end: auto;
|
|
1469
1737
|
display: flex;
|
|
1470
1738
|
align-items: center;
|
|
1471
1739
|
font-size: 14px;
|
|
@@ -1710,7 +1978,7 @@ div.magicfeedback-radio {
|
|
|
1710
1978
|
.magicfeedback-modal-close {
|
|
1711
1979
|
position: absolute;
|
|
1712
1980
|
top: 8px;
|
|
1713
|
-
|
|
1981
|
+
inset-inline-end: 8px;
|
|
1714
1982
|
background: transparent;
|
|
1715
1983
|
border: none;
|
|
1716
1984
|
font-size: 20px;
|
|
@@ -1931,6 +2199,55 @@ div.magicfeedback-radio {
|
|
|
1931
2199
|
display: block;
|
|
1932
2200
|
}
|
|
1933
2201
|
|
|
2202
|
+
/* ========================================
|
|
2203
|
+
RTL (Arabic)
|
|
2204
|
+
========================================
|
|
2205
|
+
The SDK stamps dir="rtl" (and .magicfeedback-rtl) on the survey container
|
|
2206
|
+
for right-to-left languages. Everything else in this stylesheet uses logical
|
|
2207
|
+
properties (text-align: start, padding-inline-*, inset-inline-*), so it
|
|
2208
|
+
mirrors on its own; only the handful of rules that cannot be expressed
|
|
2209
|
+
logically live here.
|
|
2210
|
+
|
|
2211
|
+
Rules are scoped to [dir="rtl"] inside our own subtree so a host page that is
|
|
2212
|
+
itself RTL, or one that embeds an Arabic survey in an LTR page, both render
|
|
2213
|
+
correctly. */
|
|
2214
|
+
|
|
2215
|
+
/* background-position has no logical form: move the select caret to the
|
|
2216
|
+
left edge, opposite the padding that inset-inline-end already mirrored. */
|
|
2217
|
+
[dir="rtl"] select {
|
|
2218
|
+
background-position: left var(--mf-space-md) center;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
/* Emails, URLs, numbers, dates and phone numbers are latin/numeric content
|
|
2222
|
+
even in an Arabic survey: keep their own direction LTR so punctuation
|
|
2223
|
+
(@, ., +, /) lands where the user expects, but align them to the start of
|
|
2224
|
+
the RTL line so they still read as part of the form. */
|
|
2225
|
+
[dir="rtl"] input[type="email"],
|
|
2226
|
+
[dir="rtl"] input[type="url"],
|
|
2227
|
+
[dir="rtl"] input[type="number"],
|
|
2228
|
+
[dir="rtl"] input[type="tel"],
|
|
2229
|
+
[dir="rtl"] input[type="date"],
|
|
2230
|
+
[dir="rtl"] input[type="time"] {
|
|
2231
|
+
direction: ltr;
|
|
2232
|
+
text-align: right;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
/* Mirror of mf-slide-in: questions enter from the reading edge. */
|
|
2236
|
+
@keyframes mf-slide-in-rtl {
|
|
2237
|
+
from {
|
|
2238
|
+
opacity: 0;
|
|
2239
|
+
transform: translateX(16px);
|
|
2240
|
+
}
|
|
2241
|
+
to {
|
|
2242
|
+
opacity: 1;
|
|
2243
|
+
transform: translateX(0);
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
[dir="rtl"] .magicfeedback-div {
|
|
2248
|
+
animation-name: mf-slide-in-rtl;
|
|
2249
|
+
}
|
|
2250
|
+
|
|
1934
2251
|
/* ========================================
|
|
1935
2252
|
LOCAL \u2014 reglas del popup, no vienen del paquete
|
|
1936
2253
|
======================================== */
|
|
@@ -1989,12 +2306,14 @@ function insertPopupLogo(parent, anchor, style, id) {
|
|
|
1989
2306
|
}
|
|
1990
2307
|
switch (style.logoPosition) {
|
|
1991
2308
|
case "left":
|
|
1992
|
-
img.style.margin = "12px
|
|
1993
|
-
img.style.
|
|
2309
|
+
img.style.margin = "12px 0 0 0";
|
|
2310
|
+
img.style.setProperty("margin-inline-start", "0");
|
|
2311
|
+
img.style.setProperty("margin-inline-end", "16px");
|
|
1994
2312
|
break;
|
|
1995
2313
|
case "right":
|
|
1996
|
-
img.style.margin = "12px 0 0
|
|
1997
|
-
img.style.
|
|
2314
|
+
img.style.margin = "12px 0 0 0";
|
|
2315
|
+
img.style.setProperty("margin-inline-start", "auto");
|
|
2316
|
+
img.style.setProperty("margin-inline-end", "0");
|
|
1998
2317
|
break;
|
|
1999
2318
|
case "center":
|
|
2000
2319
|
img.style.margin = "12px auto 0 auto";
|
|
@@ -2113,6 +2432,9 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2113
2432
|
let stylesInjected = false;
|
|
2114
2433
|
let pageDepth = 0;
|
|
2115
2434
|
let onStartPage = false;
|
|
2435
|
+
let labels = getLabels(options?.language);
|
|
2436
|
+
let actionLabels = resolveActionLabels(actions, options?.language);
|
|
2437
|
+
let direction = directionFor(options?.language);
|
|
2116
2438
|
const isDark = style?.theme === "dark";
|
|
2117
2439
|
const theme = {
|
|
2118
2440
|
popupBg: isDark ? "#1e1e1e" : "#fff",
|
|
@@ -2139,6 +2461,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2139
2461
|
const popup = document.createElement("div");
|
|
2140
2462
|
popup.id = "dd-popup";
|
|
2141
2463
|
popup.className = "deepdots-popup";
|
|
2464
|
+
popup.setAttribute("dir", direction);
|
|
2142
2465
|
popup.style.cssText = `
|
|
2143
2466
|
position: relative;
|
|
2144
2467
|
display: flex;
|
|
@@ -2168,7 +2491,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2168
2491
|
const titleEl = document.createElement("h2");
|
|
2169
2492
|
titleEl.id = "dd-title";
|
|
2170
2493
|
titleEl.className = "deepdots-popup-title";
|
|
2171
|
-
titleEl.style.cssText = `margin:0; font-size:17px; font-weight:600; line-height:1.3; color:${theme.textPrimary}; text-transform:none; text-align:
|
|
2494
|
+
titleEl.style.cssText = `margin:0; font-size:17px; font-weight:600; line-height:1.3; color:${theme.textPrimary}; text-transform:none; text-align:start; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;`;
|
|
2172
2495
|
titleEl.hidden = true;
|
|
2173
2496
|
const setTitle = (value) => {
|
|
2174
2497
|
if (!value) return;
|
|
@@ -2180,7 +2503,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2180
2503
|
const closeBtn = document.createElement("button");
|
|
2181
2504
|
closeBtn.id = "dd-close";
|
|
2182
2505
|
closeBtn.type = "button";
|
|
2183
|
-
closeBtn.setAttribute("aria-label",
|
|
2506
|
+
closeBtn.setAttribute("aria-label", labels.closeAria);
|
|
2184
2507
|
closeBtn.innerHTML = `
|
|
2185
2508
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2186
2509
|
<path d="M5 5L19 19M5 19L19 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="butt"/>
|
|
@@ -2239,7 +2562,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2239
2562
|
progressLabel.appendChild(progressTotal);
|
|
2240
2563
|
const progressFollowUp = document.createElement("span");
|
|
2241
2564
|
progressFollowUp.id = "dd-progress-followup";
|
|
2242
|
-
progressFollowUp.textContent =
|
|
2565
|
+
progressFollowUp.textContent = labels.followUp;
|
|
2243
2566
|
progressFollowUp.style.cssText = "display:none; font-size:12px; font-weight:600; color:#fff; background:rgba(59,130,246,0.44); border-radius:999px; padding:2px 10px;";
|
|
2244
2567
|
progressHead.appendChild(progressLabel);
|
|
2245
2568
|
progressHead.appendChild(progressFollowUp);
|
|
@@ -2271,8 +2594,8 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2271
2594
|
progressCurrent.textContent = `${Math.round(pct)}%`;
|
|
2272
2595
|
progressTotal.textContent = "";
|
|
2273
2596
|
} else {
|
|
2274
|
-
progressCurrent.textContent =
|
|
2275
|
-
progressTotal.textContent = ` of ${total}`;
|
|
2597
|
+
progressCurrent.textContent = `${labels.question} ${label}`;
|
|
2598
|
+
progressTotal.textContent = ` ${labels.of} ${total}`;
|
|
2276
2599
|
}
|
|
2277
2600
|
progressFollowUp.style.display = p.followup ? "inline-block" : "none";
|
|
2278
2601
|
}
|
|
@@ -2309,7 +2632,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2309
2632
|
const spinnerEl = document.createElement("div");
|
|
2310
2633
|
spinnerEl.className = "mf-spinner";
|
|
2311
2634
|
spinnerEl.setAttribute("role", "status");
|
|
2312
|
-
spinnerEl.setAttribute("aria-label",
|
|
2635
|
+
spinnerEl.setAttribute("aria-label", labels.loadingAria);
|
|
2313
2636
|
spinnerEl.innerHTML = '<div class="mf-spinner-circle"></div>';
|
|
2314
2637
|
spinnerEl.style.cssText = "position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);";
|
|
2315
2638
|
const formDivId = `magicfeedback-form-${surveyId}`;
|
|
@@ -2328,7 +2651,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2328
2651
|
const backButton = document.createElement("button");
|
|
2329
2652
|
backButton.id = "dd-back";
|
|
2330
2653
|
backButton.className = "dd-nav-btn";
|
|
2331
|
-
backButton.textContent =
|
|
2654
|
+
backButton.textContent = actionLabels.back;
|
|
2332
2655
|
backButton.style.cssText = `
|
|
2333
2656
|
background: transparent;
|
|
2334
2657
|
color: ${theme.textMuted};
|
|
@@ -2358,7 +2681,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2358
2681
|
const startButton = document.createElement("button");
|
|
2359
2682
|
startButton.id = "dd-start";
|
|
2360
2683
|
startButton.className = "dd-nav-btn";
|
|
2361
|
-
startButton.textContent =
|
|
2684
|
+
startButton.textContent = actionLabels.start;
|
|
2362
2685
|
startButton.style.cssText = `
|
|
2363
2686
|
background: #1E293B;
|
|
2364
2687
|
color: #fff;
|
|
@@ -2385,7 +2708,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2385
2708
|
const closeButton = document.createElement("button");
|
|
2386
2709
|
closeButton.id = "dd-complete";
|
|
2387
2710
|
closeButton.className = "dd-nav-btn";
|
|
2388
|
-
closeButton.textContent =
|
|
2711
|
+
closeButton.textContent = actionLabels.complete;
|
|
2389
2712
|
closeButton.style.cssText = `
|
|
2390
2713
|
background: #1E293B;
|
|
2391
2714
|
color: #fff;
|
|
@@ -2416,7 +2739,7 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2416
2739
|
const submitButton = document.createElement("button");
|
|
2417
2740
|
submitButton.id = "dd-submit";
|
|
2418
2741
|
submitButton.className = "dd-nav-btn";
|
|
2419
|
-
submitButton.textContent =
|
|
2742
|
+
submitButton.textContent = actionLabels.accept;
|
|
2420
2743
|
submitButton.style.cssText = `
|
|
2421
2744
|
background: #1E293B;
|
|
2422
2745
|
color: #fff;
|
|
@@ -2440,6 +2763,19 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2440
2763
|
formInstance?.send?.();
|
|
2441
2764
|
}
|
|
2442
2765
|
};
|
|
2766
|
+
function applyLabels(lang) {
|
|
2767
|
+
labels = getLabels(lang);
|
|
2768
|
+
actionLabels = resolveActionLabels(actions, lang);
|
|
2769
|
+
backButton.textContent = actionLabels.back;
|
|
2770
|
+
startButton.textContent = actionLabels.start;
|
|
2771
|
+
closeButton.textContent = actionLabels.complete;
|
|
2772
|
+
submitButton.textContent = actionLabels.accept;
|
|
2773
|
+
closeBtn.setAttribute("aria-label", labels.closeAria);
|
|
2774
|
+
spinnerEl.setAttribute("aria-label", labels.loadingAria);
|
|
2775
|
+
progressFollowUp.textContent = labels.followUp;
|
|
2776
|
+
direction = directionFor(lang);
|
|
2777
|
+
popup.setAttribute("dir", direction);
|
|
2778
|
+
}
|
|
2443
2779
|
backButton.style.display = "none";
|
|
2444
2780
|
startButton.style.display = "none";
|
|
2445
2781
|
submitButton.style.display = "none";
|
|
@@ -2560,6 +2896,8 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2560
2896
|
addSuccessScreen: false
|
|
2561
2897
|
};
|
|
2562
2898
|
generateOptions.onLoadedEvent = ({ formData }) => {
|
|
2899
|
+
const surveyLang = Array.isArray(formData?.lang) ? formData.lang.find((l) => typeof l === "string" && l.trim().length > 0) : void 0;
|
|
2900
|
+
if (surveyLang) applyLabels(surveyLang);
|
|
2563
2901
|
try {
|
|
2564
2902
|
} catch {
|
|
2565
2903
|
}
|
|
@@ -2620,13 +2958,13 @@ async function renderPopup(container, surveyId, productId, actions, emit, onClos
|
|
|
2620
2958
|
if (errText) {
|
|
2621
2959
|
setLoading(false);
|
|
2622
2960
|
if (errText.toLowerCase().includes("no response")) {
|
|
2623
|
-
errorHint.textContent =
|
|
2961
|
+
errorHint.textContent = labels.errorRequired;
|
|
2624
2962
|
errorHint.style.display = "block";
|
|
2625
2963
|
emit("popup_clicked", surveyId, { action: "validation_error_required" });
|
|
2626
2964
|
updateNavButtons();
|
|
2627
2965
|
return;
|
|
2628
2966
|
}
|
|
2629
|
-
errorHint.textContent =
|
|
2967
|
+
errorHint.textContent = labels.errorSubmit;
|
|
2630
2968
|
errorHint.style.display = "block";
|
|
2631
2969
|
emit("popup_clicked", surveyId, { action: "submit_error", error: errText });
|
|
2632
2970
|
return;
|
|
@@ -2669,6 +3007,7 @@ var init_renderPopup = __esm({
|
|
|
2669
3007
|
init_font();
|
|
2670
3008
|
init_logo();
|
|
2671
3009
|
init_logger();
|
|
3010
|
+
init_labels();
|
|
2672
3011
|
import_native = __toESM(require("@magicfeedback/native"));
|
|
2673
3012
|
init_style();
|
|
2674
3013
|
}
|
|
@@ -2880,6 +3219,7 @@ init_tracking_manager();
|
|
|
2880
3219
|
|
|
2881
3220
|
// src/ui/surveyHtml.ts
|
|
2882
3221
|
init_font();
|
|
3222
|
+
init_labels();
|
|
2883
3223
|
init_style();
|
|
2884
3224
|
var POSITION_MAP = {
|
|
2885
3225
|
center: { justifyContent: "center", alignItems: "center", padding: "0", background: "rgba(0,0,0,0.5)" },
|
|
@@ -2893,9 +3233,13 @@ var POSITION_MAP = {
|
|
|
2893
3233
|
function jsonForScript(value) {
|
|
2894
3234
|
return JSON.stringify(value ?? null).replace(/</g, "\\u003C").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
2895
3235
|
}
|
|
3236
|
+
function trimmedOrNull(value) {
|
|
3237
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
3238
|
+
return trimmed ? value : null;
|
|
3239
|
+
}
|
|
2896
3240
|
function buildSurveyHtml(opts) {
|
|
2897
3241
|
const env = opts.env === "development" ? "dev" : "prod";
|
|
2898
|
-
const version = opts.version ?? "2.2.
|
|
3242
|
+
const version = opts.version ?? "2.2.22";
|
|
2899
3243
|
const cdn = `https://cdn.jsdelivr.net/npm/@magicfeedback/native@${version}/dist/magicfeedback-sdk.browser.js`;
|
|
2900
3244
|
const sid = jsonForScript(opts.surveyId);
|
|
2901
3245
|
const pid = jsonForScript(opts.productId);
|
|
@@ -2927,10 +3271,22 @@ function buildSurveyHtml(opts) {
|
|
|
2927
3271
|
const titleJson = jsonForScript(opts.title ?? "");
|
|
2928
3272
|
const customCss = (opts.surveyCss ?? "").replace(/<\/\s*style/gi, "<\\/style");
|
|
2929
3273
|
const progressPref = opts.showProgressBar === void 0 ? "null" : String(opts.showProgressBar);
|
|
2930
|
-
const
|
|
2931
|
-
const
|
|
2932
|
-
const
|
|
2933
|
-
const
|
|
3274
|
+
const initLabels = getLabels(opts.language);
|
|
3275
|
+
const initActionLabels = resolveActionLabels(opts.actions, opts.language);
|
|
3276
|
+
const backLabel = jsonForScript(initActionLabels.back);
|
|
3277
|
+
const startLabel = jsonForScript(initActionLabels.start);
|
|
3278
|
+
const completeLabel = jsonForScript(initActionLabels.complete);
|
|
3279
|
+
const submitLabel = jsonForScript(initActionLabels.accept);
|
|
3280
|
+
const labelsTableJson = jsonForScript(LABELS);
|
|
3281
|
+
const actionOverridesJson = jsonForScript({
|
|
3282
|
+
accept: trimmedOrNull(opts.actions?.accept?.label),
|
|
3283
|
+
start: trimmedOrNull(opts.actions?.start?.label),
|
|
3284
|
+
complete: trimmedOrNull(opts.actions?.complete?.label),
|
|
3285
|
+
back: trimmedOrNull(opts.actions?.back?.label)
|
|
3286
|
+
});
|
|
3287
|
+
const initLangJson = jsonForScript(opts.language ?? "");
|
|
3288
|
+
const initDirection = directionFor(opts.language);
|
|
3289
|
+
const rtlLocalesJson = jsonForScript(RTL_LOCALES);
|
|
2934
3290
|
return `<!DOCTYPE html><html><head>
|
|
2935
3291
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
2936
3292
|
<meta name="color-scheme" content="${colorScheme}"/>
|
|
@@ -2943,8 +3299,8 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
2943
3299
|
.deepdots-popup-header{display:flex;justify-content:space-between;align-items:center;gap:12px;width:100%;flex:0 0 auto}
|
|
2944
3300
|
/* Neutraliza la regla \`.deepdots-popup h2\` del CSS del survey (uppercase, centrado y
|
|
2945
3301
|
margin-bottom 40px), pensada para los enunciados y no para el t\xEDtulo de la cabecera. */
|
|
2946
|
-
#dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:
|
|
2947
|
-
#dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px;flex:0 0 auto;margin-
|
|
3302
|
+
#dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:start;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
3303
|
+
#dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px;flex:0 0 auto;margin-inline-start:auto}
|
|
2948
3304
|
/* Progreso alineado con la cabecera: sin padding horizontal propio, lo marca la tarjeta.
|
|
2949
3305
|
El vertical es el mismo arriba y abajo, y del mismo valor que el padding de la tarjeta. */
|
|
2950
3306
|
.deepdots-progress{display:none;flex-direction:column;gap:8px;width:100%;flex:0 0 auto;padding:16px 0;box-sizing:border-box}
|
|
@@ -3001,10 +3357,10 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
3001
3357
|
${customCss}
|
|
3002
3358
|
</style>
|
|
3003
3359
|
</head><body>
|
|
3004
|
-
<div class="${popupClass}" id="dd-popup">
|
|
3360
|
+
<div class="${popupClass}" id="dd-popup" dir="${initDirection}">
|
|
3005
3361
|
<div class="deepdots-popup-header">
|
|
3006
3362
|
<h2 id="dd-title" class="deepdots-popup-title" hidden></h2>
|
|
3007
|
-
<button type="button" id="dd-close" aria-label="
|
|
3363
|
+
<button type="button" id="dd-close" aria-label="${initLabels.closeAria}">
|
|
3008
3364
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3009
3365
|
<path d="M5 5L19 19M5 19L19 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="butt"/>
|
|
3010
3366
|
</svg>
|
|
@@ -3013,23 +3369,23 @@ ${customCss}
|
|
|
3013
3369
|
<div class="deepdots-progress" id="dd-progress">
|
|
3014
3370
|
<div class="deepdots-progress-head">
|
|
3015
3371
|
<span id="dd-progress-label"><span id="dd-progress-current"></span><span id="dd-progress-total"></span></span>
|
|
3016
|
-
<span id="dd-progress-followup"
|
|
3372
|
+
<span id="dd-progress-followup">${initLabels.followUp}</span>
|
|
3017
3373
|
</div>
|
|
3018
3374
|
<div class="deepdots-progress-track"><div id="dd-progress-bar"></div></div>
|
|
3019
3375
|
</div>
|
|
3020
3376
|
<div class="deepdots-popup-container-content" id="dd-content">
|
|
3021
3377
|
<div class="deepdots-popup-main" id="dd-main">
|
|
3022
3378
|
<div id="dd-form-wrapper">
|
|
3023
|
-
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="
|
|
3379
|
+
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="${initLabels.loadingAria}"><div class="mf-spinner-circle"></div></div>
|
|
3024
3380
|
<div id="mf"></div>
|
|
3025
3381
|
</div>
|
|
3026
3382
|
<div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
|
|
3027
3383
|
</div>
|
|
3028
3384
|
<div class="deepdots-popup-footer" id="dd-footer">
|
|
3029
|
-
<button type="button" class="dd-nav-btn" id="dd-submit"
|
|
3030
|
-
<button type="button" class="dd-nav-btn" id="dd-back"
|
|
3031
|
-
<button type="button" class="dd-nav-btn" id="dd-complete"
|
|
3032
|
-
<button type="button" class="dd-nav-btn" id="dd-start"
|
|
3385
|
+
<button type="button" class="dd-nav-btn" id="dd-submit"></button>
|
|
3386
|
+
<button type="button" class="dd-nav-btn" id="dd-back"></button>
|
|
3387
|
+
<button type="button" class="dd-nav-btn" id="dd-complete"></button>
|
|
3388
|
+
<button type="button" class="dd-nav-btn" id="dd-start"></button>
|
|
3033
3389
|
</div>
|
|
3034
3390
|
</div>
|
|
3035
3391
|
</div>
|
|
@@ -3058,6 +3414,32 @@ ${customCss}
|
|
|
3058
3414
|
var progressTotal=document.getElementById('dd-progress-total');
|
|
3059
3415
|
var progressFollowUp=document.getElementById('dd-progress-followup');
|
|
3060
3416
|
var progressBar=document.getElementById('dd-progress-bar');
|
|
3417
|
+
var closeEl=document.getElementById('dd-close');
|
|
3418
|
+
|
|
3419
|
+
// --- i18n del chrome -------------------------------------------------------------------
|
|
3420
|
+
// La tabla completa viaja embebida porque el idioma del survey (\`formData.lang[0]\`) solo se
|
|
3421
|
+
// conoce ya dentro del WebView. \`ddResolveLocale\` es el espejo del \`resolveLocale\` de TS
|
|
3422
|
+
// (paridad cubierta por test).
|
|
3423
|
+
var DD_LABELS=${labelsTableJson};
|
|
3424
|
+
var DD_ACTION_OVERRIDES=${actionOverridesJson};
|
|
3425
|
+
${RESOLVE_LOCALE_JS}
|
|
3426
|
+
var DD_LABELS_ACTIVE=DD_LABELS[ddResolveLocale(${initLangJson})];
|
|
3427
|
+
var DD_RTL=${rtlLocalesJson};
|
|
3428
|
+
function ddIsRtl(lang){ return DD_RTL.indexOf(ddResolveLocale(lang))!==-1; }
|
|
3429
|
+
function ddApplyLabels(lang){
|
|
3430
|
+
var next=DD_LABELS[ddResolveLocale(lang)];
|
|
3431
|
+
if(!next) return;
|
|
3432
|
+
DD_LABELS_ACTIVE=next;
|
|
3433
|
+
// El survey ya se ha volteado a s\xED mismo: el chrome tiene que acompa\xF1arlo.
|
|
3434
|
+
popup.setAttribute('dir', ddIsRtl(lang) ? 'rtl' : 'ltr');
|
|
3435
|
+
backBtn.textContent=DD_ACTION_OVERRIDES.back||next.back;
|
|
3436
|
+
startBtn.textContent=DD_ACTION_OVERRIDES.start||next.start;
|
|
3437
|
+
completeBtn.textContent=DD_ACTION_OVERRIDES.complete||next.complete;
|
|
3438
|
+
submitBtn.textContent=DD_ACTION_OVERRIDES.accept||next.accept;
|
|
3439
|
+
if(closeEl){ closeEl.setAttribute('aria-label',next.closeAria); }
|
|
3440
|
+
if(spinner){ spinner.setAttribute('aria-label',next.loadingAria); }
|
|
3441
|
+
progressFollowUp.textContent=next.followUp;
|
|
3442
|
+
}
|
|
3061
3443
|
|
|
3062
3444
|
function setTitle(t){
|
|
3063
3445
|
if(!t) return;
|
|
@@ -3098,8 +3480,8 @@ ${customCss}
|
|
|
3098
3480
|
progressCurrent.textContent=Math.round(pct)+'%';
|
|
3099
3481
|
progressTotal.textContent='';
|
|
3100
3482
|
} else {
|
|
3101
|
-
progressCurrent.textContent='
|
|
3102
|
-
progressTotal.textContent=' of '+total;
|
|
3483
|
+
progressCurrent.textContent=DD_LABELS_ACTIVE.question+' '+label;
|
|
3484
|
+
progressTotal.textContent=' '+DD_LABELS_ACTIVE.of+' '+total;
|
|
3103
3485
|
}
|
|
3104
3486
|
progressFollowUp.style.display=p&&p.followup?'inline-block':'none';
|
|
3105
3487
|
}
|
|
@@ -3109,7 +3491,7 @@ ${customCss}
|
|
|
3109
3491
|
completeBtn.textContent=${completeLabel};
|
|
3110
3492
|
submitBtn.textContent=${submitLabel};
|
|
3111
3493
|
|
|
3112
|
-
|
|
3494
|
+
closeEl.onclick=function(){ emitJSON('popup_close'); };
|
|
3113
3495
|
backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
|
|
3114
3496
|
startBtn.onclick=function(){
|
|
3115
3497
|
if(window.DeepdotsForm && window.DeepdotsForm.startForm){
|
|
@@ -3204,6 +3586,14 @@ ${customCss}
|
|
|
3204
3586
|
// fallback es un literal gen\xE9rico que ignora style.successMessage.
|
|
3205
3587
|
addSuccessScreen:false,
|
|
3206
3588
|
onLoadedEvent:function(args){
|
|
3589
|
+
// Idioma del survey: manda sobre el del init para que el chrome no se quede en
|
|
3590
|
+
// ingl\xE9s delante de un survey traducido.
|
|
3591
|
+
var langs=args && args.formData ? args.formData.lang : null;
|
|
3592
|
+
if(langs && langs.length){
|
|
3593
|
+
for(var li=0;li<langs.length;li++){
|
|
3594
|
+
if(typeof langs[li]==='string' && langs[li].trim()){ ddApplyLabels(langs[li]); break; }
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3207
3597
|
var s=args && args.formData ? args.formData.style : null;
|
|
3208
3598
|
if(s && !stylesInjected){
|
|
3209
3599
|
stylesInjected=true;
|
|
@@ -3230,8 +3620,10 @@ ${customCss}
|
|
|
3230
3620
|
if(s.logoSize==='small'){ logoImg.style.maxHeight='30px'; }
|
|
3231
3621
|
else if(s.logoSize==='medium'){ logoImg.style.maxHeight='50px'; }
|
|
3232
3622
|
else if(s.logoSize==='large'){ logoImg.style.maxHeight='70px'; }
|
|
3233
|
-
|
|
3234
|
-
|
|
3623
|
+
// M\xE1rgenes l\xF3gicos: con un survey RTL el popup va con dir="rtl" y el logo
|
|
3624
|
+
// tiene que acompa\xF1ar al chrome. En LTR el resultado es el mismo de antes.
|
|
3625
|
+
if(s.logoPosition==='left'){ logoImg.style.margin='12px 0 0 0'; logoImg.style.setProperty('margin-inline-start','0'); logoImg.style.setProperty('margin-inline-end','16px'); }
|
|
3626
|
+
else if(s.logoPosition==='right'){ logoImg.style.margin='12px 0 0 0'; logoImg.style.setProperty('margin-inline-start','auto'); logoImg.style.setProperty('margin-inline-end','0'); }
|
|
3235
3627
|
else if(s.logoPosition==='center'){ logoImg.style.margin='12px auto 0 auto'; }
|
|
3236
3628
|
// Encima de la barra de progreso, como hermano del header (espejo de ui/logo.ts en
|
|
3237
3629
|
// web). Fuera de #dd-main, as\xED el logo no se va con el scroll del formulario.
|
|
@@ -3257,12 +3649,12 @@ ${customCss}
|
|
|
3257
3649
|
setLoading(false);
|
|
3258
3650
|
if(error.toLowerCase().indexOf('no response')!==-1){
|
|
3259
3651
|
// La p\xE1gina no ha cambiado: el estado de navegaci\xF3n se queda como estaba.
|
|
3260
|
-
errorHint.textContent=
|
|
3652
|
+
errorHint.textContent=DD_LABELS_ACTIVE.errorRequired;
|
|
3261
3653
|
errorHint.style.display='block';
|
|
3262
3654
|
updateNavButtons();
|
|
3263
3655
|
return;
|
|
3264
3656
|
}
|
|
3265
|
-
errorHint.textContent=
|
|
3657
|
+
errorHint.textContent=DD_LABELS_ACTIVE.errorSubmit;
|
|
3266
3658
|
errorHint.style.display='block';
|
|
3267
3659
|
return;
|
|
3268
3660
|
}
|
|
@@ -3335,7 +3727,8 @@ var ReactNativePopupRenderer = class {
|
|
|
3335
3727
|
chrome: renderChrome,
|
|
3336
3728
|
title: options?.title,
|
|
3337
3729
|
showProgressBar: options?.showProgressBar,
|
|
3338
|
-
surveyCss: options?.surveyCss
|
|
3730
|
+
surveyCss: options?.surveyCss,
|
|
3731
|
+
language: options?.language
|
|
3339
3732
|
});
|
|
3340
3733
|
if (this.options.onShow) {
|
|
3341
3734
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -4187,6 +4580,75 @@ var CrashReporter = class {
|
|
|
4187
4580
|
}
|
|
4188
4581
|
};
|
|
4189
4582
|
|
|
4583
|
+
// src/core/popup-state-store.ts
|
|
4584
|
+
var POPUP_STATE_STORAGE_KEY = "deepdots.popups.state";
|
|
4585
|
+
var MAX_TRACKED_POPUP_ENTRIES = 200;
|
|
4586
|
+
function emptyState() {
|
|
4587
|
+
return { lastShown: {}, progress: {} };
|
|
4588
|
+
}
|
|
4589
|
+
function isValidTimestamp(value) {
|
|
4590
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
4591
|
+
}
|
|
4592
|
+
function capEntries(entries, timestampOf) {
|
|
4593
|
+
if (entries.length <= MAX_TRACKED_POPUP_ENTRIES) return entries;
|
|
4594
|
+
return [...entries].sort((a, b) => timestampOf(b[1]) - timestampOf(a[1])).slice(0, MAX_TRACKED_POPUP_ENTRIES);
|
|
4595
|
+
}
|
|
4596
|
+
function readPopupState(storage) {
|
|
4597
|
+
let raw = null;
|
|
4598
|
+
try {
|
|
4599
|
+
raw = storage.getItem(POPUP_STATE_STORAGE_KEY);
|
|
4600
|
+
} catch {
|
|
4601
|
+
return emptyState();
|
|
4602
|
+
}
|
|
4603
|
+
if (!raw) return emptyState();
|
|
4604
|
+
let parsed;
|
|
4605
|
+
try {
|
|
4606
|
+
parsed = JSON.parse(raw);
|
|
4607
|
+
} catch {
|
|
4608
|
+
return emptyState();
|
|
4609
|
+
}
|
|
4610
|
+
if (typeof parsed !== "object" || parsed === null) return emptyState();
|
|
4611
|
+
const source = parsed;
|
|
4612
|
+
const state = emptyState();
|
|
4613
|
+
if (typeof source.lastShown === "object" && source.lastShown !== null) {
|
|
4614
|
+
const valid = Object.entries(source.lastShown).filter((entry) => isValidTimestamp(entry[1]));
|
|
4615
|
+
capEntries(valid, (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
4616
|
+
state.lastShown[popupId] = timestamp;
|
|
4617
|
+
});
|
|
4618
|
+
}
|
|
4619
|
+
if (typeof source.progress === "object" && source.progress !== null) {
|
|
4620
|
+
const valid = Object.entries(source.progress).filter((entry) => {
|
|
4621
|
+
const value = entry[1];
|
|
4622
|
+
if (typeof value !== "object" || value === null) return false;
|
|
4623
|
+
const candidate = value;
|
|
4624
|
+
return POPUP_TRIGGER_CONDITION_STATUSES.includes(candidate.status) && isValidTimestamp(candidate.timestamp);
|
|
4625
|
+
});
|
|
4626
|
+
capEntries(valid, (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
4627
|
+
state.progress[surveyId] = { status: entry.status, timestamp: entry.timestamp };
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4630
|
+
return state;
|
|
4631
|
+
}
|
|
4632
|
+
function writePopupState(storage, state) {
|
|
4633
|
+
const capped = emptyState();
|
|
4634
|
+
capEntries(Object.entries(state.lastShown), (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
4635
|
+
capped.lastShown[popupId] = timestamp;
|
|
4636
|
+
});
|
|
4637
|
+
capEntries(Object.entries(state.progress), (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
4638
|
+
capped.progress[surveyId] = entry;
|
|
4639
|
+
});
|
|
4640
|
+
try {
|
|
4641
|
+
storage.setItem(POPUP_STATE_STORAGE_KEY, JSON.stringify(capped));
|
|
4642
|
+
} catch {
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
function clearPopupState(storage) {
|
|
4646
|
+
try {
|
|
4647
|
+
storage.removeItem(POPUP_STATE_STORAGE_KEY);
|
|
4648
|
+
} catch {
|
|
4649
|
+
}
|
|
4650
|
+
}
|
|
4651
|
+
|
|
4190
4652
|
// src/core/deepdots-popups.ts
|
|
4191
4653
|
init_logger();
|
|
4192
4654
|
|
|
@@ -4277,6 +4739,10 @@ var DeepdotsPopups = class {
|
|
|
4277
4739
|
this.popupDefinitions = [];
|
|
4278
4740
|
this.popupsLoaded = false;
|
|
4279
4741
|
this.pendingAutoLaunch = false;
|
|
4742
|
+
// Estado que alimenta las reglas de redisplay. Copia de trabajo en memoria; la fuente
|
|
4743
|
+
// duradera es el storage (`popup-state-store`), rehidratada en `init()` — sin eso, una
|
|
4744
|
+
// recarga reiniciaba el cooldown y el popup volvía a salir. `answeredSurveys` se deriva
|
|
4745
|
+
// de las entradas COMPLETED de `surveyProgress` (los dos los escribe `markSurveyAnswered`).
|
|
4280
4746
|
this.answeredSurveys = /* @__PURE__ */ new Set();
|
|
4281
4747
|
this.surveyProgress = /* @__PURE__ */ new Map();
|
|
4282
4748
|
this.lastShown = /* @__PURE__ */ new Map();
|
|
@@ -4352,6 +4818,7 @@ var DeepdotsPopups = class {
|
|
|
4352
4818
|
};
|
|
4353
4819
|
const storage = config.storage ?? createDefaultStorage();
|
|
4354
4820
|
this.storage = storage;
|
|
4821
|
+
this.loadPopupState(storage);
|
|
4355
4822
|
this.tracking = new TrackingManager({
|
|
4356
4823
|
storage,
|
|
4357
4824
|
clientUserId: this.config.userId,
|
|
@@ -4619,6 +5086,10 @@ var DeepdotsPopups = class {
|
|
|
4619
5086
|
}) : null;
|
|
4620
5087
|
this.analytics?.resetUserScope();
|
|
4621
5088
|
this.messageGuard.reset();
|
|
5089
|
+
this.lastShown.clear();
|
|
5090
|
+
this.surveyProgress.clear();
|
|
5091
|
+
this.answeredSurveys.clear();
|
|
5092
|
+
clearPopupState(storage);
|
|
4622
5093
|
this.log("tracking \xB7 user_change \xB7 user_id:", this.tracking.getUserId());
|
|
4623
5094
|
this.openSession();
|
|
4624
5095
|
}
|
|
@@ -4790,6 +5261,7 @@ var DeepdotsPopups = class {
|
|
|
4790
5261
|
this.log("Showing popup (definition)", def);
|
|
4791
5262
|
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
4792
5263
|
this.lastShown.set(def.id, Date.now());
|
|
5264
|
+
this.persistPopupState();
|
|
4793
5265
|
this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
|
|
4794
5266
|
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
4795
5267
|
}
|
|
@@ -5148,7 +5620,7 @@ var DeepdotsPopups = class {
|
|
|
5148
5620
|
miniService,
|
|
5149
5621
|
analyticsFeedbackSessionId,
|
|
5150
5622
|
this.renderChrome,
|
|
5151
|
-
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
5623
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss, language: this.language }
|
|
5152
5624
|
);
|
|
5153
5625
|
return;
|
|
5154
5626
|
}
|
|
@@ -5168,7 +5640,7 @@ var DeepdotsPopups = class {
|
|
|
5168
5640
|
sessionId,
|
|
5169
5641
|
miniService,
|
|
5170
5642
|
analyticsFeedbackSessionId,
|
|
5171
|
-
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
5643
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss, language: this.language }
|
|
5172
5644
|
);
|
|
5173
5645
|
});
|
|
5174
5646
|
}
|
|
@@ -5269,6 +5741,29 @@ var DeepdotsPopups = class {
|
|
|
5269
5741
|
return;
|
|
5270
5742
|
}
|
|
5271
5743
|
this.surveyProgress.set(surveyId, { status, timestamp: Date.now() });
|
|
5744
|
+
this.persistPopupState();
|
|
5745
|
+
}
|
|
5746
|
+
/**
|
|
5747
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
5748
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
5749
|
+
*/
|
|
5750
|
+
loadPopupState(storage) {
|
|
5751
|
+
const state = readPopupState(storage);
|
|
5752
|
+
Object.entries(state.lastShown).forEach(([popupId, timestamp]) => {
|
|
5753
|
+
this.lastShown.set(popupId, timestamp);
|
|
5754
|
+
});
|
|
5755
|
+
Object.entries(state.progress).forEach(([surveyId, entry]) => {
|
|
5756
|
+
this.surveyProgress.set(surveyId, { status: entry.status, timestamp: entry.timestamp });
|
|
5757
|
+
if (entry.status === "COMPLETED") this.answeredSurveys.add(surveyId);
|
|
5758
|
+
});
|
|
5759
|
+
}
|
|
5760
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
5761
|
+
persistPopupState() {
|
|
5762
|
+
if (!this.storage) return;
|
|
5763
|
+
writePopupState(this.storage, {
|
|
5764
|
+
lastShown: Object.fromEntries(this.lastShown),
|
|
5765
|
+
progress: Object.fromEntries(this.surveyProgress)
|
|
5766
|
+
});
|
|
5272
5767
|
}
|
|
5273
5768
|
isPopupDefinition(value) {
|
|
5274
5769
|
if (typeof value !== "object" || value === null) return false;
|