@inappstory/slide-api 0.0.22 → 0.0.23
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/index.cjs +1111 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -5
- package/dist/index.d.ts +101 -5
- package/dist/index.js +1111 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -575,8 +575,8 @@ const getWinWidth = function (env) {
|
|
|
575
575
|
const getWinHeight = function (env) {
|
|
576
576
|
return env.innerHeight || env.document.documentElement.clientHeight || env.document.body.clientHeight;
|
|
577
577
|
};
|
|
578
|
-
const sendStatisticEventToApp = function (sdkApi, name, data, devPayload) {
|
|
579
|
-
sdkApi.sendStatisticEvent(name, data, devPayload);
|
|
578
|
+
const sendStatisticEventToApp = function (sdkApi, name, data, devPayload, options) {
|
|
579
|
+
sdkApi.sendStatisticEvent(name, data, devPayload, options?.forceEnableStatisticV2 ?? false);
|
|
580
580
|
};
|
|
581
581
|
const getValueOrException = function (value, message) {
|
|
582
582
|
if (value == null) {
|
|
@@ -672,6 +672,37 @@ const Clipboard = (function (window, document, navigator) {
|
|
|
672
672
|
copy,
|
|
673
673
|
};
|
|
674
674
|
})(window, document, navigator);
|
|
675
|
+
function FilterNumber(x) {
|
|
676
|
+
return typeof x === "number";
|
|
677
|
+
}
|
|
678
|
+
function determineLocale() {
|
|
679
|
+
// All modern browsers support this. Should match what's used by localeCompare() etc.
|
|
680
|
+
const intl = window.Intl;
|
|
681
|
+
if (intl !== undefined) {
|
|
682
|
+
return intl.NumberFormat().resolvedOptions().locale;
|
|
683
|
+
}
|
|
684
|
+
// Fall back to ranked choice locales, which are configured in the browser but aren't necessarily
|
|
685
|
+
// what's used in functions like localeCompare().
|
|
686
|
+
const languages = navigator.languages;
|
|
687
|
+
if (languages !== undefined && languages.length > 0) {
|
|
688
|
+
return languages[0];
|
|
689
|
+
}
|
|
690
|
+
// Old standard.
|
|
691
|
+
return navigator.language ?? "en-US";
|
|
692
|
+
}
|
|
693
|
+
function isScreenSupportsTouch(env) {
|
|
694
|
+
let supportsTouch = false;
|
|
695
|
+
if ("ontouchstart" in env) {
|
|
696
|
+
supportsTouch = true;
|
|
697
|
+
}
|
|
698
|
+
else if (env.navigator.msPointerEnabled) {
|
|
699
|
+
supportsTouch = true;
|
|
700
|
+
}
|
|
701
|
+
else if ("ontouchstart" in env.document.documentElement) {
|
|
702
|
+
supportsTouch = true;
|
|
703
|
+
}
|
|
704
|
+
return supportsTouch;
|
|
705
|
+
}
|
|
675
706
|
|
|
676
707
|
var supportAnimate = document.documentElement.animate !== undefined;
|
|
677
708
|
supportAnimate = false; // tmp off
|
|
@@ -1069,8 +1100,8 @@ class EsModuleSdkApi {
|
|
|
1069
1100
|
showNextSlide(duration) {
|
|
1070
1101
|
this.sdkBinding().showNextSlide(duration);
|
|
1071
1102
|
}
|
|
1072
|
-
sendStatisticEvent(name, data, devPayload) {
|
|
1073
|
-
this.sdkBinding().sendStatisticEvent(name, data, devPayload);
|
|
1103
|
+
sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2) {
|
|
1104
|
+
this.sdkBinding().sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2);
|
|
1074
1105
|
}
|
|
1075
1106
|
getCardLocalData() {
|
|
1076
1107
|
return this.sdkBinding().getCardLocalData();
|
|
@@ -1171,6 +1202,14 @@ class EsModuleSdkApi {
|
|
|
1171
1202
|
getCardFonts() {
|
|
1172
1203
|
return this.sdkBinding().getCardFonts();
|
|
1173
1204
|
}
|
|
1205
|
+
disableVerticalSwipeGesture() {
|
|
1206
|
+
this.sdkBinding().disableVerticalSwipeGesture();
|
|
1207
|
+
}
|
|
1208
|
+
enableVerticalSwipeGesture() {
|
|
1209
|
+
this.sdkBinding().enableVerticalSwipeGesture();
|
|
1210
|
+
}
|
|
1211
|
+
disableBackpress() { }
|
|
1212
|
+
enableBackpress() { }
|
|
1174
1213
|
static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
|
|
1175
1214
|
}
|
|
1176
1215
|
|
|
@@ -1425,11 +1464,11 @@ class WidgetBase {
|
|
|
1425
1464
|
}
|
|
1426
1465
|
return data;
|
|
1427
1466
|
}
|
|
1428
|
-
static sendStatisticEventToApp(name, data, devPayload) {
|
|
1429
|
-
sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload);
|
|
1467
|
+
static sendStatisticEventToApp(name, data, devPayload, options) {
|
|
1468
|
+
sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload, options);
|
|
1430
1469
|
}
|
|
1431
|
-
sendStatisticEventToApp(name, data, devPayload) {
|
|
1432
|
-
this.constructor.sendStatisticEventToApp(name, data, devPayload);
|
|
1470
|
+
sendStatisticEventToApp(name, data, devPayload, options) {
|
|
1471
|
+
this.constructor.sendStatisticEventToApp(name, data, devPayload, options);
|
|
1433
1472
|
}
|
|
1434
1473
|
startDisabledTimeline() {
|
|
1435
1474
|
this.sdkApi.startDisabledTimeline(this.cardId, this.slideIndex);
|
|
@@ -2041,7 +2080,9 @@ class WidgetDateCountdown extends WidgetBase {
|
|
|
2041
2080
|
this._showLayer(this.layers, 0);
|
|
2042
2081
|
}
|
|
2043
2082
|
else {
|
|
2044
|
-
|
|
2083
|
+
if (this.layers[1] != null) {
|
|
2084
|
+
this._showLayer(this.layers, 1);
|
|
2085
|
+
}
|
|
2045
2086
|
}
|
|
2046
2087
|
}
|
|
2047
2088
|
onPause() {
|
|
@@ -2124,7 +2165,9 @@ class WidgetDateCountdown extends WidgetBase {
|
|
|
2124
2165
|
}
|
|
2125
2166
|
else {
|
|
2126
2167
|
this.pendingUpdate = false;
|
|
2127
|
-
|
|
2168
|
+
if (this.layers[1] != null) {
|
|
2169
|
+
this._showLayer(this.layers, 1);
|
|
2170
|
+
}
|
|
2128
2171
|
}
|
|
2129
2172
|
if (this.pendingUpdate) {
|
|
2130
2173
|
this.env.requestAnimationFrame(() => this.updateTimer());
|
|
@@ -3084,6 +3127,7 @@ class WidgetQuest extends WidgetBase {
|
|
|
3084
3127
|
isWidget;
|
|
3085
3128
|
slideCount;
|
|
3086
3129
|
nonFinalSlide;
|
|
3130
|
+
slideDisabledNavigation;
|
|
3087
3131
|
finalSlide;
|
|
3088
3132
|
constructor(element, options) {
|
|
3089
3133
|
const isWidget = !hasClass(element, "narrative-slide");
|
|
@@ -3096,6 +3140,7 @@ class WidgetQuest extends WidgetBase {
|
|
|
3096
3140
|
this.finalSlide = !this.isWidget && !this.nonFinalSlide;
|
|
3097
3141
|
this.label = this.element.querySelector(".label-view .label");
|
|
3098
3142
|
this.variants = slice.call(this.element.querySelectorAll(".variants-box .variant-view"));
|
|
3143
|
+
this.slideDisabledNavigation = Boolean(getTagDataAsNumber(this.slide, "disableNavigation") ?? 0);
|
|
3099
3144
|
this.selectedAnswer = undefined;
|
|
3100
3145
|
}
|
|
3101
3146
|
/**
|
|
@@ -3240,6 +3285,10 @@ class WidgetQuest extends WidgetBase {
|
|
|
3240
3285
|
const directionForward = event.direction === "forward";
|
|
3241
3286
|
event.direction === "backward";
|
|
3242
3287
|
if (this.isWidget) {
|
|
3288
|
+
// like in web-sdk - simple block tap navigation at all
|
|
3289
|
+
if (this.slideDisabledNavigation) {
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3243
3292
|
if (directionForward) {
|
|
3244
3293
|
return;
|
|
3245
3294
|
}
|
|
@@ -3263,6 +3312,10 @@ class WidgetQuest extends WidgetBase {
|
|
|
3263
3312
|
}
|
|
3264
3313
|
}
|
|
3265
3314
|
else {
|
|
3315
|
+
// like in web-sdk - simple block tap navigation at all
|
|
3316
|
+
if (this.slideDisabledNavigation) {
|
|
3317
|
+
return;
|
|
3318
|
+
}
|
|
3266
3319
|
// slides without quest form
|
|
3267
3320
|
// simple slide case
|
|
3268
3321
|
if (this.nonFinalSlide || event.slideIndex < this.firstSlideWithQuestIndex()) {
|
|
@@ -4221,10 +4274,10 @@ class WidgetRangeSlider extends WidgetBase {
|
|
|
4221
4274
|
if (!this.maxHandlePos) {
|
|
4222
4275
|
this.update(true, false);
|
|
4223
4276
|
}
|
|
4224
|
-
document.addEventListener("touchmove", this.handleMove);
|
|
4225
|
-
document.addEventListener("touchend", this.handleEnd);
|
|
4226
|
-
document.addEventListener("mousemove", this.handleMove);
|
|
4227
|
-
document.addEventListener("mouseup", this.handleEnd);
|
|
4277
|
+
this.env.document.addEventListener("touchmove", this.handleMove);
|
|
4278
|
+
this.env.document.addEventListener("touchend", this.handleEnd);
|
|
4279
|
+
this.env.document.addEventListener("mousemove", this.handleMove);
|
|
4280
|
+
this.env.document.addEventListener("mouseup", this.handleEnd);
|
|
4228
4281
|
// add active class because Firefox is ignoring
|
|
4229
4282
|
// the handle:active pseudo selector because of `e.preventDefault();`
|
|
4230
4283
|
this.range.classList.add(this.options.activeClass);
|
|
@@ -4249,10 +4302,10 @@ class WidgetRangeSlider extends WidgetBase {
|
|
|
4249
4302
|
this.isClickCapturedBySlider = false;
|
|
4250
4303
|
});
|
|
4251
4304
|
// e.preventDefault();
|
|
4252
|
-
document.removeEventListener("touchmove", this.handleMove);
|
|
4253
|
-
document.removeEventListener("touchend", this.handleEnd);
|
|
4254
|
-
document.removeEventListener("mousemove", this.handleMove);
|
|
4255
|
-
document.removeEventListener("mouseup", this.handleEnd);
|
|
4305
|
+
this.env.document.removeEventListener("touchmove", this.handleMove);
|
|
4306
|
+
this.env.document.removeEventListener("touchend", this.handleEnd);
|
|
4307
|
+
this.env.document.removeEventListener("mousemove", this.handleMove);
|
|
4308
|
+
this.env.document.removeEventListener("mouseup", this.handleEnd);
|
|
4256
4309
|
this.range.classList.remove(this.options.activeClass);
|
|
4257
4310
|
this.element.classList.add("input-done");
|
|
4258
4311
|
if (!this.hasSubmitButton) {
|
|
@@ -15282,6 +15335,1045 @@ class WidgetBarcode extends WidgetBase {
|
|
|
15282
15335
|
static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
|
|
15283
15336
|
}
|
|
15284
15337
|
|
|
15338
|
+
class Formatter {
|
|
15339
|
+
intlSupport = false;
|
|
15340
|
+
defaultTimeFormat = "medium";
|
|
15341
|
+
defaultDatetimeFormat = "medium";
|
|
15342
|
+
defaultDateFormat = "medium";
|
|
15343
|
+
decimalSeparator = ".";
|
|
15344
|
+
thousandSeparator = " ";
|
|
15345
|
+
spaceSeparator = " ";
|
|
15346
|
+
static Second = 1000;
|
|
15347
|
+
static Minute = 60 * Formatter.Second;
|
|
15348
|
+
static Hour = 60 * Formatter.Minute;
|
|
15349
|
+
static Day = 24 * Formatter.Hour;
|
|
15350
|
+
datetimeFormatOptions = {
|
|
15351
|
+
short: {
|
|
15352
|
+
year: "numeric",
|
|
15353
|
+
month: "2-digit",
|
|
15354
|
+
day: "2-digit",
|
|
15355
|
+
hour: "2-digit",
|
|
15356
|
+
minute: "2-digit",
|
|
15357
|
+
},
|
|
15358
|
+
medium: {
|
|
15359
|
+
year: "numeric",
|
|
15360
|
+
month: "2-digit",
|
|
15361
|
+
day: "2-digit",
|
|
15362
|
+
hour: "2-digit",
|
|
15363
|
+
minute: "2-digit",
|
|
15364
|
+
second: "2-digit",
|
|
15365
|
+
},
|
|
15366
|
+
long: {
|
|
15367
|
+
year: "numeric",
|
|
15368
|
+
month: "long",
|
|
15369
|
+
day: "2-digit",
|
|
15370
|
+
hour: "2-digit",
|
|
15371
|
+
minute: "2-digit",
|
|
15372
|
+
second: "2-digit",
|
|
15373
|
+
timeZoneName: "short",
|
|
15374
|
+
},
|
|
15375
|
+
full: {
|
|
15376
|
+
weekday: "long",
|
|
15377
|
+
year: "numeric",
|
|
15378
|
+
month: "long",
|
|
15379
|
+
day: "2-digit",
|
|
15380
|
+
hour: "2-digit",
|
|
15381
|
+
minute: "2-digit",
|
|
15382
|
+
second: "2-digit",
|
|
15383
|
+
timeZoneName: "long",
|
|
15384
|
+
},
|
|
15385
|
+
};
|
|
15386
|
+
dateFormatOptions = {
|
|
15387
|
+
short: {
|
|
15388
|
+
year: "2-digit",
|
|
15389
|
+
month: "2-digit",
|
|
15390
|
+
day: "2-digit",
|
|
15391
|
+
},
|
|
15392
|
+
medium: {
|
|
15393
|
+
year: "numeric",
|
|
15394
|
+
month: "2-digit",
|
|
15395
|
+
day: "2-digit",
|
|
15396
|
+
},
|
|
15397
|
+
long: {
|
|
15398
|
+
year: "numeric",
|
|
15399
|
+
month: "long",
|
|
15400
|
+
day: "2-digit",
|
|
15401
|
+
},
|
|
15402
|
+
full: {
|
|
15403
|
+
weekday: "long",
|
|
15404
|
+
year: "numeric",
|
|
15405
|
+
month: "long",
|
|
15406
|
+
day: "2-digit",
|
|
15407
|
+
},
|
|
15408
|
+
};
|
|
15409
|
+
timeFormatOptions = {
|
|
15410
|
+
short: {
|
|
15411
|
+
hour: "2-digit",
|
|
15412
|
+
minute: "2-digit",
|
|
15413
|
+
},
|
|
15414
|
+
medium: {
|
|
15415
|
+
hour: "2-digit",
|
|
15416
|
+
minute: "2-digit",
|
|
15417
|
+
second: "2-digit",
|
|
15418
|
+
},
|
|
15419
|
+
long: {
|
|
15420
|
+
hour: "2-digit",
|
|
15421
|
+
minute: "2-digit",
|
|
15422
|
+
second: "2-digit",
|
|
15423
|
+
timeZoneName: "short",
|
|
15424
|
+
},
|
|
15425
|
+
full: {
|
|
15426
|
+
hour: "2-digit",
|
|
15427
|
+
minute: "2-digit",
|
|
15428
|
+
second: "2-digit",
|
|
15429
|
+
timeZoneName: "long",
|
|
15430
|
+
},
|
|
15431
|
+
};
|
|
15432
|
+
context;
|
|
15433
|
+
constructor(context) {
|
|
15434
|
+
this.intlSupport = typeof Intl === "object" && Intl !== null;
|
|
15435
|
+
this.context = context;
|
|
15436
|
+
}
|
|
15437
|
+
asDate(value, format = undefined, options = {}) {
|
|
15438
|
+
if (!format) {
|
|
15439
|
+
format = this.defaultDateFormat;
|
|
15440
|
+
}
|
|
15441
|
+
return this.formatDateTimeValue(value, format, "date", options);
|
|
15442
|
+
}
|
|
15443
|
+
asTime(value, format = undefined, options = {}) {
|
|
15444
|
+
if (!format) {
|
|
15445
|
+
format = this.defaultTimeFormat;
|
|
15446
|
+
}
|
|
15447
|
+
return this.formatDateTimeValue(value, format, "time", options);
|
|
15448
|
+
}
|
|
15449
|
+
asDatetime(value, format = undefined, options = {}) {
|
|
15450
|
+
if (!format) {
|
|
15451
|
+
format = this.defaultTimeFormat;
|
|
15452
|
+
}
|
|
15453
|
+
return this.formatDateTimeValue(value, format, "datetime", options);
|
|
15454
|
+
}
|
|
15455
|
+
formatDateTimeValue(value, format = undefined, type = undefined, options = {}) {
|
|
15456
|
+
const normalizedValue = Formatter.normalizeDatetimeValue(value);
|
|
15457
|
+
if (normalizedValue === null) {
|
|
15458
|
+
return "";
|
|
15459
|
+
}
|
|
15460
|
+
if (this.intlSupport) {
|
|
15461
|
+
let formatterOptions = {};
|
|
15462
|
+
if (type === "date") {
|
|
15463
|
+
if (typeof format === "undefined") {
|
|
15464
|
+
format = this.defaultDateFormat;
|
|
15465
|
+
}
|
|
15466
|
+
if (typeof format === "object") {
|
|
15467
|
+
formatterOptions = format;
|
|
15468
|
+
}
|
|
15469
|
+
else {
|
|
15470
|
+
if (format in this.dateFormatOptions) {
|
|
15471
|
+
formatterOptions = this.dateFormatOptions[format];
|
|
15472
|
+
}
|
|
15473
|
+
else {
|
|
15474
|
+
return this.momentFallback(normalizedValue, format, options);
|
|
15475
|
+
}
|
|
15476
|
+
}
|
|
15477
|
+
}
|
|
15478
|
+
else if (type === "time") {
|
|
15479
|
+
if (typeof format === "undefined") {
|
|
15480
|
+
format = this.defaultTimeFormat;
|
|
15481
|
+
}
|
|
15482
|
+
if (typeof format === "object") {
|
|
15483
|
+
formatterOptions = format;
|
|
15484
|
+
}
|
|
15485
|
+
else {
|
|
15486
|
+
if (format in this.timeFormatOptions) {
|
|
15487
|
+
formatterOptions = this.timeFormatOptions[format];
|
|
15488
|
+
}
|
|
15489
|
+
else {
|
|
15490
|
+
return this.momentFallback(normalizedValue, format, options);
|
|
15491
|
+
}
|
|
15492
|
+
}
|
|
15493
|
+
}
|
|
15494
|
+
else if (type === "datetime") {
|
|
15495
|
+
if (typeof format === "undefined") {
|
|
15496
|
+
format = this.defaultDatetimeFormat;
|
|
15497
|
+
}
|
|
15498
|
+
if (typeof format === "object") {
|
|
15499
|
+
formatterOptions = format;
|
|
15500
|
+
}
|
|
15501
|
+
else {
|
|
15502
|
+
if (format in this.datetimeFormatOptions) {
|
|
15503
|
+
formatterOptions = this.datetimeFormatOptions[format];
|
|
15504
|
+
}
|
|
15505
|
+
else {
|
|
15506
|
+
return this.momentFallback(normalizedValue, format, options);
|
|
15507
|
+
}
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
if (options.timezone) {
|
|
15511
|
+
formatterOptions.timeZone = options.timezone;
|
|
15512
|
+
}
|
|
15513
|
+
Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
|
|
15514
|
+
return Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
|
|
15515
|
+
}
|
|
15516
|
+
return "";
|
|
15517
|
+
}
|
|
15518
|
+
momentFallback(value, format, options = {}) {
|
|
15519
|
+
return value.toLocaleString(this.locale);
|
|
15520
|
+
// return this.context.$moment(value).format(format);
|
|
15521
|
+
}
|
|
15522
|
+
asInteger(value) {
|
|
15523
|
+
if (value === undefined || value === null) {
|
|
15524
|
+
return this.nullDisplay;
|
|
15525
|
+
}
|
|
15526
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15527
|
+
if (this.intlSupport) {
|
|
15528
|
+
return Intl.NumberFormat(this.locale, {
|
|
15529
|
+
maximumFractionDigits: 0,
|
|
15530
|
+
useGrouping: true,
|
|
15531
|
+
}).format(normalizedValue);
|
|
15532
|
+
}
|
|
15533
|
+
return Formatter.numberFormat(normalizedValue, 0, this.decimalSeparator, this.thousandSeparator);
|
|
15534
|
+
}
|
|
15535
|
+
asDecimal(value, decimals = 2) {
|
|
15536
|
+
if (value == null) {
|
|
15537
|
+
return this.nullDisplay;
|
|
15538
|
+
}
|
|
15539
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15540
|
+
if (this.intlSupport) {
|
|
15541
|
+
return Intl.NumberFormat(this.locale, {
|
|
15542
|
+
maximumFractionDigits: decimals,
|
|
15543
|
+
minimumFractionDigits: decimals,
|
|
15544
|
+
useGrouping: true,
|
|
15545
|
+
}).format(normalizedValue);
|
|
15546
|
+
}
|
|
15547
|
+
return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
|
|
15548
|
+
}
|
|
15549
|
+
asDecimalMax(value, decimals = 2) {
|
|
15550
|
+
if (value === undefined || value === null) {
|
|
15551
|
+
return this.nullDisplay;
|
|
15552
|
+
}
|
|
15553
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15554
|
+
if (this.intlSupport) {
|
|
15555
|
+
return Intl.NumberFormat(this.locale, {
|
|
15556
|
+
maximumFractionDigits: decimals,
|
|
15557
|
+
minimumFractionDigits: 0,
|
|
15558
|
+
useGrouping: true,
|
|
15559
|
+
}).format(normalizedValue);
|
|
15560
|
+
}
|
|
15561
|
+
return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
|
|
15562
|
+
}
|
|
15563
|
+
asPercent(value, decimals = 0) {
|
|
15564
|
+
if (value === undefined || value === null) {
|
|
15565
|
+
return this.nullDisplay;
|
|
15566
|
+
}
|
|
15567
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15568
|
+
if (this.intlSupport) {
|
|
15569
|
+
return Intl.NumberFormat(this.locale, {
|
|
15570
|
+
style: "percent",
|
|
15571
|
+
maximumFractionDigits: decimals,
|
|
15572
|
+
minimumFractionDigits: decimals,
|
|
15573
|
+
}).format(normalizedValue);
|
|
15574
|
+
}
|
|
15575
|
+
return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
|
|
15576
|
+
}
|
|
15577
|
+
asPercentMax(value, decimals = 0) {
|
|
15578
|
+
if (value === undefined || value === null) {
|
|
15579
|
+
return this.nullDisplay;
|
|
15580
|
+
}
|
|
15581
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15582
|
+
if (this.intlSupport) {
|
|
15583
|
+
return Intl.NumberFormat(this.locale, {
|
|
15584
|
+
style: "percent",
|
|
15585
|
+
maximumFractionDigits: decimals,
|
|
15586
|
+
minimumFractionDigits: 0,
|
|
15587
|
+
}).format(normalizedValue);
|
|
15588
|
+
}
|
|
15589
|
+
return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
|
|
15590
|
+
}
|
|
15591
|
+
asRelativeTime(value, referenceTime = undefined) {
|
|
15592
|
+
if (value === undefined || value === null) {
|
|
15593
|
+
return this.nullDisplay;
|
|
15594
|
+
}
|
|
15595
|
+
const normalizedValue = Formatter.normalizeDatetimeValue(value);
|
|
15596
|
+
if (normalizedValue == null) {
|
|
15597
|
+
return this.nullDisplay;
|
|
15598
|
+
}
|
|
15599
|
+
if (referenceTime === undefined || referenceTime === null) {
|
|
15600
|
+
referenceTime = new Date();
|
|
15601
|
+
}
|
|
15602
|
+
else {
|
|
15603
|
+
referenceTime = Formatter.normalizeDatetimeValue(value);
|
|
15604
|
+
}
|
|
15605
|
+
const dt = referenceTime.getTime() - normalizedValue.getTime();
|
|
15606
|
+
const absDt = Math.abs(dt);
|
|
15607
|
+
const invert = dt < 0;
|
|
15608
|
+
if (absDt < Formatter.Second) {
|
|
15609
|
+
return this.context.i18n?.t("format.relativeTime.justNow").toString() ?? "";
|
|
15610
|
+
}
|
|
15611
|
+
const seconds = absDt / 1000;
|
|
15612
|
+
let interval = seconds / 31536000;
|
|
15613
|
+
if (interval > 1) {
|
|
15614
|
+
return this.context.i18n?.tc("format.relativeTime.year" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
|
|
15615
|
+
}
|
|
15616
|
+
interval = seconds / 2592000;
|
|
15617
|
+
if (interval > 1) {
|
|
15618
|
+
return this.context.i18n?.tc("format.relativeTime.month" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
|
|
15619
|
+
}
|
|
15620
|
+
interval = seconds / 86400;
|
|
15621
|
+
if (interval > 1) {
|
|
15622
|
+
return this.context.i18n?.tc("format.relativeTime.day" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
|
|
15623
|
+
}
|
|
15624
|
+
interval = seconds / 3600;
|
|
15625
|
+
if (interval > 1) {
|
|
15626
|
+
return this.context.i18n?.tc("format.relativeTime.hour" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
|
|
15627
|
+
}
|
|
15628
|
+
interval = seconds / 60;
|
|
15629
|
+
if (interval > 1) {
|
|
15630
|
+
return this.context.i18n?.tc("format.relativeTime.minute" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
|
|
15631
|
+
}
|
|
15632
|
+
return this.context.i18n?.tc("format.relativeTime.second" + (invert ? "In" : "Ago"), Math.floor(seconds)).toString() ?? "";
|
|
15633
|
+
}
|
|
15634
|
+
asDuration(value) {
|
|
15635
|
+
if (value === undefined || value === null) {
|
|
15636
|
+
return "00:00";
|
|
15637
|
+
}
|
|
15638
|
+
const normalizedValue = Formatter.normalizeDatetimeValue(value);
|
|
15639
|
+
if (normalizedValue === undefined || normalizedValue === null) {
|
|
15640
|
+
return "00:00";
|
|
15641
|
+
}
|
|
15642
|
+
const hours = Math.floor(value / 3600);
|
|
15643
|
+
const minutes = Math.floor((value / 60) % 60);
|
|
15644
|
+
const seconds = value % 60;
|
|
15645
|
+
if (hours > 0) {
|
|
15646
|
+
return `${hours}:${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
|
|
15647
|
+
}
|
|
15648
|
+
else {
|
|
15649
|
+
return `${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
|
|
15650
|
+
}
|
|
15651
|
+
}
|
|
15652
|
+
asCurrency(value, currency = undefined) {
|
|
15653
|
+
if (value === undefined || value === null) {
|
|
15654
|
+
return this.nullDisplay;
|
|
15655
|
+
}
|
|
15656
|
+
if (currency === undefined || currency === null) {
|
|
15657
|
+
currency = "USD";
|
|
15658
|
+
}
|
|
15659
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15660
|
+
if (normalizedValue == null) {
|
|
15661
|
+
return this.nullDisplay;
|
|
15662
|
+
}
|
|
15663
|
+
let decimals = 2;
|
|
15664
|
+
if (Number.isInteger(normalizedValue)) {
|
|
15665
|
+
decimals = 0;
|
|
15666
|
+
}
|
|
15667
|
+
if (currency === "RUR" || currency === "RUB") {
|
|
15668
|
+
return `${this.asDecimal(normalizedValue, decimals)}${this.spaceSeparator}₽`;
|
|
15669
|
+
}
|
|
15670
|
+
if (this.intlSupport) {
|
|
15671
|
+
try {
|
|
15672
|
+
return Intl.NumberFormat(this.locale, {
|
|
15673
|
+
style: "currency",
|
|
15674
|
+
currency,
|
|
15675
|
+
currencyDisplay: "symbol",
|
|
15676
|
+
maximumFractionDigits: decimals,
|
|
15677
|
+
minimumFractionDigits: decimals,
|
|
15678
|
+
}).format(normalizedValue);
|
|
15679
|
+
}
|
|
15680
|
+
catch (e) {
|
|
15681
|
+
console.error(e);
|
|
15682
|
+
return String(normalizedValue);
|
|
15683
|
+
}
|
|
15684
|
+
}
|
|
15685
|
+
return currency + " " + this.asDecimal(normalizedValue, 2);
|
|
15686
|
+
}
|
|
15687
|
+
asShortSizeCasual(value, dp = 1) {
|
|
15688
|
+
if (value === undefined || value === null) {
|
|
15689
|
+
return this.nullDisplay;
|
|
15690
|
+
}
|
|
15691
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15692
|
+
if (normalizedValue === undefined || normalizedValue === null) {
|
|
15693
|
+
return this.nullDisplay;
|
|
15694
|
+
}
|
|
15695
|
+
const thresh = 1024;
|
|
15696
|
+
if (Math.abs(value) < thresh) {
|
|
15697
|
+
return value + " B";
|
|
15698
|
+
}
|
|
15699
|
+
const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
15700
|
+
let u = -1;
|
|
15701
|
+
const r = 10 ** dp;
|
|
15702
|
+
do {
|
|
15703
|
+
value /= thresh;
|
|
15704
|
+
++u;
|
|
15705
|
+
} while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
|
|
15706
|
+
return value.toFixed(dp) + " " + units[u];
|
|
15707
|
+
}
|
|
15708
|
+
asShortSize(value, si = false, dp = 1) {
|
|
15709
|
+
if (value === undefined || value === null) {
|
|
15710
|
+
return this.nullDisplay;
|
|
15711
|
+
}
|
|
15712
|
+
const normalizedValue = Formatter.normalizeNumericValue(value);
|
|
15713
|
+
if (normalizedValue === undefined || normalizedValue === null) {
|
|
15714
|
+
return this.nullDisplay;
|
|
15715
|
+
}
|
|
15716
|
+
const thresh = si ? 1000 : 1024;
|
|
15717
|
+
if (Math.abs(value) < thresh) {
|
|
15718
|
+
return value + " B";
|
|
15719
|
+
}
|
|
15720
|
+
const units = si ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
|
|
15721
|
+
let u = -1;
|
|
15722
|
+
const r = 10 ** dp;
|
|
15723
|
+
do {
|
|
15724
|
+
value /= thresh;
|
|
15725
|
+
++u;
|
|
15726
|
+
} while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
|
|
15727
|
+
return value.toFixed(dp) + " " + units[u];
|
|
15728
|
+
}
|
|
15729
|
+
static numberFormat(value, decimals = 0, decimalSeparator = ".", thousandsSeparator) {
|
|
15730
|
+
const sign = value < 0 ? "-" : "";
|
|
15731
|
+
const sNumber = Math.abs(parseInt((+value || 0).toFixed(decimals))) + "";
|
|
15732
|
+
const len = sNumber.length;
|
|
15733
|
+
const tchunk = len > 3 ? len % 3 : 0;
|
|
15734
|
+
const chFirst = tchunk ? sNumber.substr(0, tchunk) + thousandsSeparator : "";
|
|
15735
|
+
const chRest = sNumber.substr(tchunk).replace(/(\d\d\d)(?=\d)/g, "$1" + thousandsSeparator);
|
|
15736
|
+
const chLast = decimals ? decimalSeparator + (Math.abs(value) - parseFloat(sNumber)).toFixed(decimals).slice(2) : "";
|
|
15737
|
+
return sign + chFirst + chRest + chLast;
|
|
15738
|
+
}
|
|
15739
|
+
get nullDisplay() {
|
|
15740
|
+
return "";
|
|
15741
|
+
// if (this.context && this.context.i18n) {
|
|
15742
|
+
// return this.context.i18n.t("notSet").toString();
|
|
15743
|
+
// }
|
|
15744
|
+
//
|
|
15745
|
+
// return "not set";
|
|
15746
|
+
}
|
|
15747
|
+
static normalizeDatetimeValue(value) {
|
|
15748
|
+
const type = typeof value;
|
|
15749
|
+
if (type === "object" && value instanceof Date) {
|
|
15750
|
+
return value;
|
|
15751
|
+
}
|
|
15752
|
+
else if (type === "number") {
|
|
15753
|
+
return new Date(value);
|
|
15754
|
+
}
|
|
15755
|
+
else if (type === "string") {
|
|
15756
|
+
if (isNaN(value)) {
|
|
15757
|
+
return new Date(parseInt(value));
|
|
15758
|
+
}
|
|
15759
|
+
else {
|
|
15760
|
+
const d = Date.parse(value);
|
|
15761
|
+
if (isNaN(d)) {
|
|
15762
|
+
return null;
|
|
15763
|
+
}
|
|
15764
|
+
return new Date(d);
|
|
15765
|
+
}
|
|
15766
|
+
}
|
|
15767
|
+
return null;
|
|
15768
|
+
}
|
|
15769
|
+
static normalizeNumericValue(value) {
|
|
15770
|
+
const type = typeof value;
|
|
15771
|
+
if ((type === "object" && value === null) || type === "undefined") {
|
|
15772
|
+
return 0;
|
|
15773
|
+
}
|
|
15774
|
+
else if (type === "number") {
|
|
15775
|
+
return value;
|
|
15776
|
+
}
|
|
15777
|
+
return parseFloat(value);
|
|
15778
|
+
}
|
|
15779
|
+
get locale() {
|
|
15780
|
+
return this.context.determineLocale();
|
|
15781
|
+
}
|
|
15782
|
+
static get [Symbol.for("___CTOR_ARGS___")]() { return [`{\n determineLocale: () => string;\n i18n: { t: (key: string) => string; tc: (key: string, value: string | number) => string } | undefined;\n }`]; }
|
|
15783
|
+
}
|
|
15784
|
+
const formatter = new Formatter({ determineLocale, i18n: undefined });
|
|
15785
|
+
|
|
15786
|
+
class SwipeGestureDetector {
|
|
15787
|
+
env;
|
|
15788
|
+
isScreenSupportsTouch;
|
|
15789
|
+
canContinueHandleDown;
|
|
15790
|
+
onStart;
|
|
15791
|
+
onUpdate;
|
|
15792
|
+
onEnd;
|
|
15793
|
+
constructor(env, isScreenSupportsTouch, canContinueHandleDown, onStart, onUpdate, onEnd) {
|
|
15794
|
+
this.env = env;
|
|
15795
|
+
this.isScreenSupportsTouch = isScreenSupportsTouch;
|
|
15796
|
+
this.canContinueHandleDown = canContinueHandleDown;
|
|
15797
|
+
this.onStart = onStart;
|
|
15798
|
+
this.onUpdate = onUpdate;
|
|
15799
|
+
this.onEnd = onEnd;
|
|
15800
|
+
// Store context
|
|
15801
|
+
this.handleDown = this.handleDown.bind(this);
|
|
15802
|
+
this.handleMove = this.handleMove.bind(this);
|
|
15803
|
+
this.handleEnd = this.handleEnd.bind(this);
|
|
15804
|
+
this.supportsTouch = false;
|
|
15805
|
+
if (this.isScreenSupportsTouch) {
|
|
15806
|
+
this.env.document.addEventListener("touchstart", this.handleDown, false);
|
|
15807
|
+
}
|
|
15808
|
+
else {
|
|
15809
|
+
this.env.document.addEventListener("mousedown", this.handleDown, false);
|
|
15810
|
+
}
|
|
15811
|
+
}
|
|
15812
|
+
startPageCoordinate = [0, 0];
|
|
15813
|
+
limit = Math.tan(((45 * 1.5) / 180) * Math.PI);
|
|
15814
|
+
pageWidth = window.innerWidth || document.body.clientWidth;
|
|
15815
|
+
threshold = Math.max(1, Math.floor(0.01 * this.pageWidth));
|
|
15816
|
+
supportsTouch = false;
|
|
15817
|
+
handleDown(e) {
|
|
15818
|
+
if (!this.canContinueHandleDown(e)) {
|
|
15819
|
+
return;
|
|
15820
|
+
}
|
|
15821
|
+
this.startPageCoordinate = this.getPageCoordinate(e);
|
|
15822
|
+
if (this.isScreenSupportsTouch) {
|
|
15823
|
+
this.env.document.addEventListener("touchmove", this.handleMove, false);
|
|
15824
|
+
this.env.document.addEventListener("touchend", this.handleEnd, false);
|
|
15825
|
+
}
|
|
15826
|
+
else {
|
|
15827
|
+
this.env.document.addEventListener("mousemove", this.handleMove, false);
|
|
15828
|
+
this.env.document.addEventListener("mouseup", this.handleEnd, false);
|
|
15829
|
+
}
|
|
15830
|
+
this.onStart(e);
|
|
15831
|
+
}
|
|
15832
|
+
handleMove(e) {
|
|
15833
|
+
// console.log("handleMove", { startPageCoordinate: this.startPageCoordinate})
|
|
15834
|
+
// this.currentPageCoordinate = this.getPageCoordinate(e);
|
|
15835
|
+
this.onUpdate(e);
|
|
15836
|
+
}
|
|
15837
|
+
handleEnd(e) {
|
|
15838
|
+
if (this.isScreenSupportsTouch) {
|
|
15839
|
+
this.env.document.removeEventListener("touchmove", this.handleMove);
|
|
15840
|
+
this.env.document.removeEventListener("touchend", this.handleEnd);
|
|
15841
|
+
}
|
|
15842
|
+
else {
|
|
15843
|
+
this.env.document.removeEventListener("mousemove", this.handleMove);
|
|
15844
|
+
this.env.document.removeEventListener("mouseup", this.handleEnd);
|
|
15845
|
+
}
|
|
15846
|
+
const currentPageCoordinate = this.getPageCoordinate(e);
|
|
15847
|
+
let gesture = 0 /* SwipeGesture.undefined */;
|
|
15848
|
+
const x = currentPageCoordinate[0] - this.startPageCoordinate[0];
|
|
15849
|
+
const y = currentPageCoordinate[1] - this.startPageCoordinate[1];
|
|
15850
|
+
// console.log("handleEnd", {currentPageCoordinate, startPageCoordinate: this.startPageCoordinate})
|
|
15851
|
+
let xy = Math.abs(x / y);
|
|
15852
|
+
let yx = Math.abs(y / x);
|
|
15853
|
+
if (Math.abs(x) > this.threshold || Math.abs(y) > this.threshold) {
|
|
15854
|
+
if (yx <= this.limit) {
|
|
15855
|
+
if (x < 0) {
|
|
15856
|
+
gesture = 4 /* SwipeGesture.SwipeLeft */;
|
|
15857
|
+
// @ts-ignore
|
|
15858
|
+
// _log(JSON.stringify({t: "SwipeLeft", yx, x, threshold: this.threshold}), true);
|
|
15859
|
+
}
|
|
15860
|
+
else {
|
|
15861
|
+
// @ts-ignore
|
|
15862
|
+
// _log(JSON.stringify({t: "SwipeRight", yx, x, threshold: this.threshold}), true);
|
|
15863
|
+
gesture = 5 /* SwipeGesture.SwipeRight */;
|
|
15864
|
+
}
|
|
15865
|
+
}
|
|
15866
|
+
if (xy <= this.limit) {
|
|
15867
|
+
if (y < 0) {
|
|
15868
|
+
// @ts-ignore
|
|
15869
|
+
// _log(JSON.stringify({t: "SwipeUp", xy, y, threshold: this.threshold}), true);
|
|
15870
|
+
gesture = 2 /* SwipeGesture.SwipeUp */;
|
|
15871
|
+
}
|
|
15872
|
+
else {
|
|
15873
|
+
// @ts-ignore
|
|
15874
|
+
// _log(JSON.stringify({t: "SwipeDown", xy, y, threshold: this.threshold}), true);
|
|
15875
|
+
gesture = 3 /* SwipeGesture.SwipeDown */;
|
|
15876
|
+
}
|
|
15877
|
+
}
|
|
15878
|
+
}
|
|
15879
|
+
else {
|
|
15880
|
+
// @ts-ignore
|
|
15881
|
+
// _log(JSON.stringify({t: "Tap", x, y, threshold: this.threshold}), true);
|
|
15882
|
+
gesture = 1 /* SwipeGesture.Tap */;
|
|
15883
|
+
}
|
|
15884
|
+
this.onEnd(e, gesture);
|
|
15885
|
+
}
|
|
15886
|
+
destroy() {
|
|
15887
|
+
if (this.isScreenSupportsTouch) {
|
|
15888
|
+
this.env.document.removeEventListener("touchstart", this.handleDown);
|
|
15889
|
+
}
|
|
15890
|
+
else {
|
|
15891
|
+
this.env.document.removeEventListener("mousedown", this.handleDown);
|
|
15892
|
+
}
|
|
15893
|
+
}
|
|
15894
|
+
getPageCoordinate(e) {
|
|
15895
|
+
let x = 0;
|
|
15896
|
+
let y = 0;
|
|
15897
|
+
if (e["clientX"] != null && e["clientY"] != null) {
|
|
15898
|
+
x = e["clientX"];
|
|
15899
|
+
y = e["clientY"];
|
|
15900
|
+
}
|
|
15901
|
+
else if (e.touches &&
|
|
15902
|
+
e.touches[0] &&
|
|
15903
|
+
e.touches[0]["clientX"] != null &&
|
|
15904
|
+
e.touches[0]["clientY"] != null) {
|
|
15905
|
+
x = e.touches[0]["clientX"];
|
|
15906
|
+
y = e.touches[0]["clientY"];
|
|
15907
|
+
}
|
|
15908
|
+
else if (e.changedTouches &&
|
|
15909
|
+
e.changedTouches[0] &&
|
|
15910
|
+
e.changedTouches[0]["clientX"] != null &&
|
|
15911
|
+
e.changedTouches[0]["clientY"] != null) {
|
|
15912
|
+
x = e.changedTouches[0]["clientX"];
|
|
15913
|
+
y = e.changedTouches[0]["clientY"];
|
|
15914
|
+
}
|
|
15915
|
+
// @ts-ignore
|
|
15916
|
+
else if (e.currentPoint && e.currentPoint["x"] != null && e.currentPoint["y"] != null) {
|
|
15917
|
+
// @ts-ignore
|
|
15918
|
+
x = e.currentPoint["x"];
|
|
15919
|
+
// @ts-ignore
|
|
15920
|
+
y = e.currentPoint["y"];
|
|
15921
|
+
}
|
|
15922
|
+
return [x, y];
|
|
15923
|
+
}
|
|
15924
|
+
static get [Symbol.for("___CTOR_ARGS___")]() { return [`Window`, `boolean`, `(e: MouseEvent | TouchEvent) => boolean`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent, gesture: SwipeGesture) => void`]; }
|
|
15925
|
+
}
|
|
15926
|
+
|
|
15927
|
+
/**
|
|
15928
|
+
* adult: null
|
|
15929
|
+
* availability: 1
|
|
15930
|
+
* coverUrl: "https://cdn.test.inappstory.com/np/file/cf/wb/wc/vcaji5clqon3nkwdwle3cjz63x.jpg?k=KgAAAAAAAAACAQ"
|
|
15931
|
+
* currency: "RUR"
|
|
15932
|
+
* description: "Непромокаемый комбинезон - дождевик детский Муссон"
|
|
15933
|
+
* id: 204
|
|
15934
|
+
* name: "Непромокаемый комбинезон - дождевик детский \"Муссон\""
|
|
15935
|
+
* offerId: "10125"
|
|
15936
|
+
* oldPrice: null
|
|
15937
|
+
* price: "2690.0000"
|
|
15938
|
+
* url: "http://www.songnomik.ru/products/detskaya-odezhda-optom-dlya-novorozhdennyh/detskie-kombinezony-optom/2166483.html"
|
|
15939
|
+
*/
|
|
15940
|
+
class WidgetProducts extends WidgetBase {
|
|
15941
|
+
static DEFAULTS = {
|
|
15942
|
+
slide: null,
|
|
15943
|
+
activateAfterCreate: false,
|
|
15944
|
+
create: false,
|
|
15945
|
+
localData: {},
|
|
15946
|
+
};
|
|
15947
|
+
static widgetClassName = "narrative-element-products";
|
|
15948
|
+
captionView;
|
|
15949
|
+
linkTarget = [];
|
|
15950
|
+
msgNetworkError;
|
|
15951
|
+
msgServiceError;
|
|
15952
|
+
swipeGestureDetector = null;
|
|
15953
|
+
isClickCapturedByWidget = false;
|
|
15954
|
+
isScreenSupportsTouch = false;
|
|
15955
|
+
constructor(element, options) {
|
|
15956
|
+
super(element, options);
|
|
15957
|
+
this.captionView = this.element.querySelector(".narrative-element-text-lines");
|
|
15958
|
+
const linkTarget = decodeURIComponent(getTagData(element, "linkTarget") ?? "[]");
|
|
15959
|
+
try {
|
|
15960
|
+
let parsed = JSON.parse(linkTarget);
|
|
15961
|
+
if (Array.isArray(parsed)) {
|
|
15962
|
+
this.linkTarget = parsed.filter(FilterNumber);
|
|
15963
|
+
}
|
|
15964
|
+
}
|
|
15965
|
+
catch (e) {
|
|
15966
|
+
console.error(e);
|
|
15967
|
+
}
|
|
15968
|
+
this.isScreenSupportsTouch = isScreenSupportsTouch(this.env);
|
|
15969
|
+
this.msgNetworkError = getTagData(this.element, "msgNetworkError");
|
|
15970
|
+
this.msgServiceError = getTagData(this.element, "msgServiceError");
|
|
15971
|
+
}
|
|
15972
|
+
/**
|
|
15973
|
+
* Start or restart widget
|
|
15974
|
+
* @param localData
|
|
15975
|
+
*/
|
|
15976
|
+
onRefreshUserData(localData) {
|
|
15977
|
+
super.onRefreshUserData(localData);
|
|
15978
|
+
}
|
|
15979
|
+
onStart() {
|
|
15980
|
+
super.onStart();
|
|
15981
|
+
// reinit for case when we returned to slide from other slide and onStop destroyed SwipeGestureDetector
|
|
15982
|
+
this.initSwipeGestureDetector();
|
|
15983
|
+
}
|
|
15984
|
+
isTransparentElement() {
|
|
15985
|
+
if (this.element) {
|
|
15986
|
+
try {
|
|
15987
|
+
const color = window.getComputedStyle(this.element).color;
|
|
15988
|
+
if (color === "transparent" || color === "rgba(0, 0, 0, 0)" || color === "rgba(0,0,0,0)") {
|
|
15989
|
+
return true;
|
|
15990
|
+
}
|
|
15991
|
+
}
|
|
15992
|
+
catch (err) {
|
|
15993
|
+
console.error(err);
|
|
15994
|
+
}
|
|
15995
|
+
}
|
|
15996
|
+
return false;
|
|
15997
|
+
}
|
|
15998
|
+
_statEventWidgetClick() {
|
|
15999
|
+
try {
|
|
16000
|
+
const captionViewText = this.captionView?.textContent ?? "";
|
|
16001
|
+
this.sendStatisticEventToApp("w-products-click", {
|
|
16002
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16003
|
+
wi: this.elementId,
|
|
16004
|
+
wl: captionViewText,
|
|
16005
|
+
wv: this.linkTarget,
|
|
16006
|
+
}, {
|
|
16007
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16008
|
+
widget_id: this.elementId,
|
|
16009
|
+
widget_label: captionViewText,
|
|
16010
|
+
widget_value: this.linkTarget,
|
|
16011
|
+
}, {
|
|
16012
|
+
forceEnableStatisticV2: true,
|
|
16013
|
+
});
|
|
16014
|
+
}
|
|
16015
|
+
catch (error) {
|
|
16016
|
+
console.error(error);
|
|
16017
|
+
}
|
|
16018
|
+
}
|
|
16019
|
+
_statEventWidgetOpen(offers) {
|
|
16020
|
+
try {
|
|
16021
|
+
const captionViewText = this.captionView?.textContent ?? "";
|
|
16022
|
+
this.sendStatisticEventToApp("w-products-open", {
|
|
16023
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16024
|
+
wi: this.elementId,
|
|
16025
|
+
wl: captionViewText,
|
|
16026
|
+
wv: this.linkTarget,
|
|
16027
|
+
wit: offers.map(item => item.offerId),
|
|
16028
|
+
}, {
|
|
16029
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16030
|
+
widget_id: this.elementId,
|
|
16031
|
+
widget_label: captionViewText,
|
|
16032
|
+
widget_value: this.linkTarget,
|
|
16033
|
+
widget_items: offers.map(item => item.offerId),
|
|
16034
|
+
}, {
|
|
16035
|
+
forceEnableStatisticV2: true,
|
|
16036
|
+
});
|
|
16037
|
+
}
|
|
16038
|
+
catch (error) {
|
|
16039
|
+
console.error(error);
|
|
16040
|
+
}
|
|
16041
|
+
}
|
|
16042
|
+
_statEventWidgetCardClick(offer) {
|
|
16043
|
+
try {
|
|
16044
|
+
const captionViewText = this.captionView?.textContent ?? "";
|
|
16045
|
+
this.sendStatisticEventToApp("w-products-card-click", {
|
|
16046
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16047
|
+
wi: this.elementId,
|
|
16048
|
+
wl: captionViewText,
|
|
16049
|
+
wv: offer.offerId,
|
|
16050
|
+
wvi: offer.id,
|
|
16051
|
+
}, {
|
|
16052
|
+
...this.statisticEventBaseFieldsShortForm,
|
|
16053
|
+
widget_id: this.elementId,
|
|
16054
|
+
widget_label: captionViewText,
|
|
16055
|
+
widget_value: offer.offerId,
|
|
16056
|
+
widget_value_id: offer.id,
|
|
16057
|
+
}, {
|
|
16058
|
+
forceEnableStatisticV2: true,
|
|
16059
|
+
});
|
|
16060
|
+
}
|
|
16061
|
+
catch (error) {
|
|
16062
|
+
console.error(error);
|
|
16063
|
+
}
|
|
16064
|
+
}
|
|
16065
|
+
async fetchProducts() {
|
|
16066
|
+
const fetchAndCacheMedia = async () => {
|
|
16067
|
+
if (!this.linkTarget.length) {
|
|
16068
|
+
return { message: this.msgServiceError ?? "", models: [] };
|
|
16069
|
+
}
|
|
16070
|
+
const path = `product/offer?id=${this.linkTarget.join(",")}`;
|
|
16071
|
+
const headers = {
|
|
16072
|
+
accept: "application/json",
|
|
16073
|
+
"Content-Type": "application/json",
|
|
16074
|
+
};
|
|
16075
|
+
const profileKey = "fetch-products";
|
|
16076
|
+
try {
|
|
16077
|
+
const response = await this.sdkApi.sendApiRequest(path, "GET", null, headers, null, profileKey);
|
|
16078
|
+
// console.log({response});
|
|
16079
|
+
const status = response.status;
|
|
16080
|
+
if (status === 200 || status === 201) {
|
|
16081
|
+
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
|
16082
|
+
try {
|
|
16083
|
+
await this.cacheOffersMediaResources(response.data);
|
|
16084
|
+
}
|
|
16085
|
+
catch (error) {
|
|
16086
|
+
console.error(error);
|
|
16087
|
+
}
|
|
16088
|
+
return { message: "", models: response.data };
|
|
16089
|
+
}
|
|
16090
|
+
else {
|
|
16091
|
+
return { message: this.msgServiceError ?? "", models: [] };
|
|
16092
|
+
}
|
|
16093
|
+
}
|
|
16094
|
+
else if (status === 12163 || status === 12002) {
|
|
16095
|
+
return { message: this.msgNetworkError ?? "", models: [] };
|
|
16096
|
+
}
|
|
16097
|
+
else {
|
|
16098
|
+
return { message: this.msgServiceError ?? "", models: [] };
|
|
16099
|
+
}
|
|
16100
|
+
}
|
|
16101
|
+
catch (error) {
|
|
16102
|
+
console.error(error);
|
|
16103
|
+
return { message: this.msgServiceError ?? "", models: [] };
|
|
16104
|
+
}
|
|
16105
|
+
};
|
|
16106
|
+
return Promise.all([
|
|
16107
|
+
fetchAndCacheMedia(),
|
|
16108
|
+
new Promise(t => {
|
|
16109
|
+
return setTimeout(t, 200);
|
|
16110
|
+
}),
|
|
16111
|
+
]).then(([result]) => result);
|
|
16112
|
+
}
|
|
16113
|
+
cacheOffersMediaResources(offers) {
|
|
16114
|
+
const cacheItem = (offer) => {
|
|
16115
|
+
return new Promise(resolve => {
|
|
16116
|
+
if (offer.coverUrl != null) {
|
|
16117
|
+
this.env
|
|
16118
|
+
.fetch(offer.coverUrl)
|
|
16119
|
+
.then(response => {
|
|
16120
|
+
if (response != null && response.ok) {
|
|
16121
|
+
response
|
|
16122
|
+
.blob()
|
|
16123
|
+
.then(blob => {
|
|
16124
|
+
offer.coverUrl = URL.createObjectURL(blob);
|
|
16125
|
+
resolve();
|
|
16126
|
+
})
|
|
16127
|
+
.catch(resolve);
|
|
16128
|
+
}
|
|
16129
|
+
else {
|
|
16130
|
+
resolve();
|
|
16131
|
+
}
|
|
16132
|
+
})
|
|
16133
|
+
.catch(resolve);
|
|
16134
|
+
}
|
|
16135
|
+
else {
|
|
16136
|
+
resolve();
|
|
16137
|
+
}
|
|
16138
|
+
});
|
|
16139
|
+
};
|
|
16140
|
+
const promises = offers.map(cacheItem);
|
|
16141
|
+
return Promise.all(promises);
|
|
16142
|
+
}
|
|
16143
|
+
revokeOffersMediaResources(offers) {
|
|
16144
|
+
offers.forEach(offer => {
|
|
16145
|
+
if (offer.coverUrl != null) {
|
|
16146
|
+
// todo check if coverUrl really is object URL
|
|
16147
|
+
URL.revokeObjectURL(offer.coverUrl);
|
|
16148
|
+
}
|
|
16149
|
+
});
|
|
16150
|
+
}
|
|
16151
|
+
initSwipeGestureDetector() {
|
|
16152
|
+
if (this.isOpen) {
|
|
16153
|
+
this.swipeGestureDetector = new SwipeGestureDetector(this.env, this.isScreenSupportsTouch, () => true, e => {
|
|
16154
|
+
// this.isClickCapturedByWidget = true;
|
|
16155
|
+
return;
|
|
16156
|
+
}, e => {
|
|
16157
|
+
return;
|
|
16158
|
+
}, (e, gesture) => {
|
|
16159
|
+
if (gesture === 3 /* SwipeGesture.SwipeDown */) {
|
|
16160
|
+
this.closeProductsView();
|
|
16161
|
+
}
|
|
16162
|
+
// this.env.requestAnimationFrame(() => {
|
|
16163
|
+
// this.isClickCapturedByWidget = false;
|
|
16164
|
+
// });
|
|
16165
|
+
});
|
|
16166
|
+
}
|
|
16167
|
+
}
|
|
16168
|
+
productsView = null;
|
|
16169
|
+
isOpen = false;
|
|
16170
|
+
currentModels = [];
|
|
16171
|
+
async openProductsView() {
|
|
16172
|
+
if (this.isOpen) {
|
|
16173
|
+
return;
|
|
16174
|
+
}
|
|
16175
|
+
this._statEventWidgetClick();
|
|
16176
|
+
if (!this.disableTimer) {
|
|
16177
|
+
this.sdkApi.pauseUI();
|
|
16178
|
+
}
|
|
16179
|
+
if (!this.isTransparentElement()) {
|
|
16180
|
+
this.element.classList.add("loader");
|
|
16181
|
+
}
|
|
16182
|
+
// const start = window.performance.now();
|
|
16183
|
+
const result = await this.fetchProducts();
|
|
16184
|
+
// @ts-ignore
|
|
16185
|
+
// _log(`fetched for ${window.performance.now() - start}ms`, true);
|
|
16186
|
+
// console.log({result})
|
|
16187
|
+
if (result.models.length > 0) {
|
|
16188
|
+
this.currentModels = result.models;
|
|
16189
|
+
this.productsView = this.createProductsView(this.currentModels, this.closeProductsView.bind(this));
|
|
16190
|
+
this.productsView.classList.add("ias-products-container-view--visible");
|
|
16191
|
+
this.slide.appendChild(this.productsView);
|
|
16192
|
+
this.element.classList.add("hidden");
|
|
16193
|
+
this.isOpen = true;
|
|
16194
|
+
// prevent next slide navigation gesture
|
|
16195
|
+
this.isClickCapturedByWidget = true;
|
|
16196
|
+
this.sdkApi.disableVerticalSwipeGesture();
|
|
16197
|
+
this.sdkApi.disableBackpress();
|
|
16198
|
+
this._statEventWidgetOpen(this.currentModels);
|
|
16199
|
+
this.initSwipeGestureDetector();
|
|
16200
|
+
}
|
|
16201
|
+
else {
|
|
16202
|
+
if (result.message) {
|
|
16203
|
+
this.sdkApi.showToast(result.message);
|
|
16204
|
+
}
|
|
16205
|
+
}
|
|
16206
|
+
this.element.classList.remove("loader");
|
|
16207
|
+
}
|
|
16208
|
+
closeProductsView() {
|
|
16209
|
+
if (!this.isOpen) {
|
|
16210
|
+
return;
|
|
16211
|
+
}
|
|
16212
|
+
this.productsView?.classList.add("ias-products-container-view--hidden");
|
|
16213
|
+
this.element.classList.remove("hidden");
|
|
16214
|
+
this.isClickCapturedByWidget = false;
|
|
16215
|
+
if (this.swipeGestureDetector != null) {
|
|
16216
|
+
this.swipeGestureDetector.destroy();
|
|
16217
|
+
}
|
|
16218
|
+
this.sdkApi.enableVerticalSwipeGesture();
|
|
16219
|
+
this.sdkApi.enableBackpress();
|
|
16220
|
+
const onClosed = () => {
|
|
16221
|
+
this.productsView?.removeEventListener("animationend", onClosed);
|
|
16222
|
+
this.productsView?.parentElement?.removeChild(this.productsView);
|
|
16223
|
+
this.revokeOffersMediaResources(this.currentModels);
|
|
16224
|
+
if (!this.disableTimer) {
|
|
16225
|
+
this.sdkApi.resumeUI();
|
|
16226
|
+
}
|
|
16227
|
+
this.isOpen = false;
|
|
16228
|
+
this.currentModels = [];
|
|
16229
|
+
};
|
|
16230
|
+
this.productsView?.addEventListener("animationend", onClosed);
|
|
16231
|
+
}
|
|
16232
|
+
createCardView(offer) {
|
|
16233
|
+
const figure = document.createElement("div");
|
|
16234
|
+
figure.classList.add("ias-products-card-figure");
|
|
16235
|
+
if (offer.coverUrl) {
|
|
16236
|
+
// todo preload coverImage by fetch, save to offer.coverUrl via createUrl (add revoke)
|
|
16237
|
+
// if cannot fetch - skip caching
|
|
16238
|
+
const image = document.createElement("img");
|
|
16239
|
+
image.classList.add("ias-products-card-figure-image");
|
|
16240
|
+
image.alt = offer.name ?? "";
|
|
16241
|
+
image.src = offer.coverUrl;
|
|
16242
|
+
figure.appendChild(image);
|
|
16243
|
+
}
|
|
16244
|
+
// const subTitle = document.createElement("div");
|
|
16245
|
+
// subTitle.classList.add("ias-products-card-subtitle");
|
|
16246
|
+
// subTitle.innerText = offer.description ?? "";
|
|
16247
|
+
const title = document.createElement("div");
|
|
16248
|
+
title.classList.add("ias-products-card-title");
|
|
16249
|
+
title.innerText = offer.name ?? "";
|
|
16250
|
+
let price = null;
|
|
16251
|
+
if (offer.price) {
|
|
16252
|
+
price = document.createElement("div");
|
|
16253
|
+
price.classList.add("ias-products-card-price");
|
|
16254
|
+
price.innerHTML = formatter.asCurrency(offer.price, offer.currency);
|
|
16255
|
+
}
|
|
16256
|
+
let oldPrice = null;
|
|
16257
|
+
if (offer.oldPrice) {
|
|
16258
|
+
oldPrice = document.createElement("div");
|
|
16259
|
+
oldPrice.classList.add("ias-products-card-old-price");
|
|
16260
|
+
oldPrice.innerHTML = formatter.asCurrency(offer.oldPrice, offer.currency);
|
|
16261
|
+
}
|
|
16262
|
+
const prices = document.createElement("div");
|
|
16263
|
+
prices.classList.add("ias-products-card-prices");
|
|
16264
|
+
if (price) {
|
|
16265
|
+
prices.appendChild(price);
|
|
16266
|
+
}
|
|
16267
|
+
if (oldPrice) {
|
|
16268
|
+
prices.appendChild(oldPrice);
|
|
16269
|
+
}
|
|
16270
|
+
const card = document.createElement("div");
|
|
16271
|
+
card.classList.add("ias-products-card");
|
|
16272
|
+
card.onclick = () => {
|
|
16273
|
+
this._statEventWidgetCardClick(offer);
|
|
16274
|
+
if (offer.url) {
|
|
16275
|
+
this.sdkApi.openUrl(offer.url);
|
|
16276
|
+
}
|
|
16277
|
+
};
|
|
16278
|
+
card.appendChild(figure);
|
|
16279
|
+
// card.appendChild(subTitle);
|
|
16280
|
+
card.appendChild(prices);
|
|
16281
|
+
card.appendChild(title);
|
|
16282
|
+
return card;
|
|
16283
|
+
}
|
|
16284
|
+
createScrollView(offers) {
|
|
16285
|
+
const scrollView = document.createElement("div");
|
|
16286
|
+
scrollView.classList.add("ias-products-scroll-view");
|
|
16287
|
+
offers.forEach(offer => scrollView.appendChild(this.createCardView(offer)));
|
|
16288
|
+
return scrollView;
|
|
16289
|
+
}
|
|
16290
|
+
createProductsView(offers, onClose) {
|
|
16291
|
+
const containerView = document.createElement("div");
|
|
16292
|
+
containerView.classList.add("ias-products-container-view");
|
|
16293
|
+
const backdropView = document.createElement("div");
|
|
16294
|
+
backdropView.classList.add("ias-products-container-backdrop-view");
|
|
16295
|
+
backdropView.onclick = e => {
|
|
16296
|
+
e.preventDefault();
|
|
16297
|
+
e.stopPropagation();
|
|
16298
|
+
onClose();
|
|
16299
|
+
};
|
|
16300
|
+
const backgroundView = document.createElement("div");
|
|
16301
|
+
backgroundView.classList.add("ias-products-container-background-view");
|
|
16302
|
+
const scrollView = this.createScrollView(offers);
|
|
16303
|
+
const closeButton = document.createElement("div");
|
|
16304
|
+
closeButton.classList.add("ias-products-container-close-button");
|
|
16305
|
+
// fill=${ProductsWidgetOptionsDefault.productsList.closeBackgroundColor}
|
|
16306
|
+
closeButton.innerHTML = `<svg width="32" height="12.5" viewBox="0 0 64 25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M56.293 1.23375C58.054 -0.41125 60.846 -0.41125 62.607 1.23375C64.464 2.96775 64.464 5.85675 62.607 7.59075L35.157 23.2288C33.396 24.8738 30.604 24.8738 28.843 23.2288L1.393 7.59075C0.494002 6.75175 0 5.62775 0 4.41275C0 3.19775 0.494002 2.07375 1.393 1.23475C3.154 -0.410251 5.946 -0.410251 7.707 1.23475L32 13.9237L56.293 1.23375Z" fill="currentColor" /></svg>`;
|
|
16307
|
+
closeButton.onclick = e => {
|
|
16308
|
+
e.preventDefault();
|
|
16309
|
+
e.stopPropagation();
|
|
16310
|
+
onClose();
|
|
16311
|
+
};
|
|
16312
|
+
backgroundView.appendChild(scrollView);
|
|
16313
|
+
backgroundView.appendChild(closeButton);
|
|
16314
|
+
containerView.appendChild(backdropView);
|
|
16315
|
+
containerView.appendChild(backgroundView);
|
|
16316
|
+
return containerView;
|
|
16317
|
+
}
|
|
16318
|
+
getIsClickCapturedByWidget() {
|
|
16319
|
+
return this.isClickCapturedByWidget;
|
|
16320
|
+
}
|
|
16321
|
+
destroy() {
|
|
16322
|
+
if (this.swipeGestureDetector != null) {
|
|
16323
|
+
this.swipeGestureDetector.destroy();
|
|
16324
|
+
this.swipeGestureDetector = null;
|
|
16325
|
+
}
|
|
16326
|
+
}
|
|
16327
|
+
onStop() {
|
|
16328
|
+
super.onStop();
|
|
16329
|
+
this.destroy();
|
|
16330
|
+
}
|
|
16331
|
+
static api = {
|
|
16332
|
+
widgetClassName: WidgetProducts.widgetClassName,
|
|
16333
|
+
onRefreshUserData: WidgetProducts.onRefreshUserData,
|
|
16334
|
+
init: function (element, localData) {
|
|
16335
|
+
WidgetProducts.initWidget(element, localData, (element, options) => new WidgetProducts(element, options));
|
|
16336
|
+
},
|
|
16337
|
+
onStart: function (element) {
|
|
16338
|
+
WidgetProducts.getInstance(element)?.onStart();
|
|
16339
|
+
},
|
|
16340
|
+
onStop: function (element) {
|
|
16341
|
+
WidgetProducts.getInstance(element)?.onStop();
|
|
16342
|
+
},
|
|
16343
|
+
click: function (element) {
|
|
16344
|
+
const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
|
|
16345
|
+
if (widgetElement) {
|
|
16346
|
+
const widget = WidgetProducts.getInstance(widgetElement);
|
|
16347
|
+
if (widget) {
|
|
16348
|
+
widget.openProductsView();
|
|
16349
|
+
}
|
|
16350
|
+
}
|
|
16351
|
+
return false;
|
|
16352
|
+
},
|
|
16353
|
+
isClickCapturedByWidget: function (element) {
|
|
16354
|
+
const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
|
|
16355
|
+
if (widgetElement) {
|
|
16356
|
+
const widget = WidgetProducts.getInstance(widgetElement);
|
|
16357
|
+
if (widget) {
|
|
16358
|
+
return widget.getIsClickCapturedByWidget();
|
|
16359
|
+
}
|
|
16360
|
+
}
|
|
16361
|
+
return false;
|
|
16362
|
+
},
|
|
16363
|
+
onHandleBackpress: function (element) {
|
|
16364
|
+
const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
|
|
16365
|
+
if (widgetElement) {
|
|
16366
|
+
const widget = WidgetProducts.getInstance(widgetElement);
|
|
16367
|
+
if (widget) {
|
|
16368
|
+
widget.closeProductsView();
|
|
16369
|
+
}
|
|
16370
|
+
}
|
|
16371
|
+
return false;
|
|
16372
|
+
},
|
|
16373
|
+
};
|
|
16374
|
+
static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
|
|
16375
|
+
}
|
|
16376
|
+
|
|
15285
16377
|
let sdkInterface;
|
|
15286
16378
|
const getSlideApi = (_sdkInterface) => {
|
|
15287
16379
|
sdkInterface = _sdkInterface;
|
|
@@ -15302,6 +16394,7 @@ const getSlideApi = (_sdkInterface) => {
|
|
|
15302
16394
|
WidgetTest: WidgetTest.api,
|
|
15303
16395
|
WidgetVote: WidgetVote.api,
|
|
15304
16396
|
WidgetBarcode: WidgetBarcode.api,
|
|
16397
|
+
WidgetProducts: WidgetProducts.api,
|
|
15305
16398
|
};
|
|
15306
16399
|
};
|
|
15307
16400
|
|