@inappstory/slide-api 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -283,6 +283,19 @@ const expando = function () {
283
283
  const camelCase = function (string) {
284
284
  return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
285
285
  };
286
+ const proxy = function (func, obj) {
287
+ if (typeof func != "function") {
288
+ return func;
289
+ }
290
+ // If obj is empty or another set another object
291
+ if (!obj) {
292
+ // @ts-ignore
293
+ obj = this;
294
+ }
295
+ return function () {
296
+ return func.apply(obj, arguments);
297
+ };
298
+ };
286
299
  var rnotwhite = /\S+/g;
287
300
  class Data {
288
301
  static uid = 1;
@@ -991,13 +1004,3418 @@ class EsModuleSdkApi {
991
1004
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
992
1005
  }
993
1006
 
994
- var TimelineDisabledState;
995
- (function (TimelineDisabledState) {
996
- TimelineDisabledState[TimelineDisabledState["disabled"] = 0] = "disabled";
997
- TimelineDisabledState[TimelineDisabledState["enabled"] = 1] = "enabled";
998
- })(TimelineDisabledState || (TimelineDisabledState = {}));
1007
+ class DataInput {
1008
+ _elementNodeRef;
1009
+ _layer;
1010
+ _widgetApi;
1011
+ static _className = "narrative-element-data-input";
1012
+ static className() {
1013
+ return DataInput._className;
1014
+ }
1015
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1016
+ this._elementNodeRef = _elementNodeRef;
1017
+ this._layer = _layer;
1018
+ this._widgetApi = _widgetApi;
1019
+ }
1020
+ static isTypeOf(element) {
1021
+ return element instanceof DataInput;
1022
+ }
1023
+ mediaElementsLoadingPromises = [];
1024
+ init(localData) {
1025
+ try {
1026
+ this._widgetApi.init(this._elementNodeRef, localData);
1027
+ }
1028
+ catch (e) {
1029
+ console.error(e);
1030
+ }
1031
+ return Promise.resolve(true);
1032
+ }
1033
+ onPause() { }
1034
+ onResume() { }
1035
+ onStart() {
1036
+ this._widgetApi.onStart(this._elementNodeRef);
1037
+ }
1038
+ onStop() {
1039
+ this._widgetApi.onStop(this._elementNodeRef);
1040
+ }
1041
+ handleClick() {
1042
+ return false;
1043
+ }
1044
+ setUserData(id, text) {
1045
+ this._widgetApi.setUserData(id, text);
1046
+ }
1047
+ get isLayerForcePaused() {
1048
+ return false;
1049
+ }
1050
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetDataInput.api`]; }
1051
+ }
999
1052
 
1000
- let sdkInterface;
1053
+ class Barcode {
1054
+ _elementNodeRef;
1055
+ _layer;
1056
+ _widgetApi;
1057
+ static _className = "narrative-element-barcode";
1058
+ static className() {
1059
+ return Barcode._className;
1060
+ }
1061
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1062
+ this._elementNodeRef = _elementNodeRef;
1063
+ this._layer = _layer;
1064
+ this._widgetApi = _widgetApi;
1065
+ }
1066
+ mediaElementsLoadingPromises = [];
1067
+ init(localData) {
1068
+ try {
1069
+ this._widgetApi.init(this._elementNodeRef, localData);
1070
+ }
1071
+ catch (e) {
1072
+ console.error(e);
1073
+ }
1074
+ return Promise.resolve(true);
1075
+ }
1076
+ onPause() { }
1077
+ onResume() { }
1078
+ onStart() {
1079
+ this._widgetApi.onStart(this._elementNodeRef);
1080
+ }
1081
+ onStop() {
1082
+ this._widgetApi.onStop(this._elementNodeRef);
1083
+ }
1084
+ handleClick() {
1085
+ return false;
1086
+ }
1087
+ get isLayerForcePaused() {
1088
+ return false;
1089
+ }
1090
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetBarcode.api`]; }
1091
+ }
1001
1092
 
1002
- container.registerSingleton(() => new EsModuleSdkApi(() => sdkInterface), { identifier: `SDKApi` });
1093
+ class ClickableBase {
1094
+ _element;
1095
+ constructor(_element) {
1096
+ this._element = _element;
1097
+ }
1098
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`]; }
1099
+ }
1100
+
1101
+ class Button extends ClickableBase {
1102
+ _elementNodeRef;
1103
+ _layer;
1104
+ static _className = "narrative-element-link";
1105
+ static className() {
1106
+ return Button._className;
1107
+ }
1108
+ constructor(_elementNodeRef, _layer) {
1109
+ super(_elementNodeRef);
1110
+ this._elementNodeRef = _elementNodeRef;
1111
+ this._layer = _layer;
1112
+ }
1113
+ mediaElementsLoadingPromises = [];
1114
+ init(localData) {
1115
+ return Promise.resolve(true);
1116
+ }
1117
+ onPause() { }
1118
+ onResume() { }
1119
+ onStart() { }
1120
+ onStop() { }
1121
+ handleClick() {
1122
+ return false;
1123
+ }
1124
+ get isLayerForcePaused() {
1125
+ return false;
1126
+ }
1127
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`]; }
1128
+ }
1129
+
1130
+ class Copy {
1131
+ _elementNodeRef;
1132
+ _layer;
1133
+ _widgetApi;
1134
+ static _className = "narrative-element-copy";
1135
+ static className() {
1136
+ return Copy._className;
1137
+ }
1138
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1139
+ this._elementNodeRef = _elementNodeRef;
1140
+ this._layer = _layer;
1141
+ this._widgetApi = _widgetApi;
1142
+ }
1143
+ mediaElementsLoadingPromises = [];
1144
+ init(localData) {
1145
+ try {
1146
+ this._widgetApi.init(this._elementNodeRef, localData);
1147
+ }
1148
+ catch (e) {
1149
+ console.error(e);
1150
+ }
1151
+ return Promise.resolve(true);
1152
+ }
1153
+ onPause() { }
1154
+ onResume() { }
1155
+ onStart() {
1156
+ this._widgetApi.onStart(this._elementNodeRef);
1157
+ }
1158
+ onStop() {
1159
+ this._widgetApi.onStop(this._elementNodeRef);
1160
+ }
1161
+ handleClick() {
1162
+ return false;
1163
+ }
1164
+ get isLayerForcePaused() {
1165
+ return false;
1166
+ }
1167
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetCopy.api`]; }
1168
+ }
1169
+
1170
+ class DateCountdown {
1171
+ _elementNodeRef;
1172
+ _layer;
1173
+ _layersNodesRefs;
1174
+ _widgetApi;
1175
+ static _className = "narrative-element-date-countdown";
1176
+ static className() {
1177
+ return DateCountdown._className;
1178
+ }
1179
+ constructor(_elementNodeRef, _layer, _layersNodesRefs, _widgetApi) {
1180
+ this._elementNodeRef = _elementNodeRef;
1181
+ this._layer = _layer;
1182
+ this._layersNodesRefs = _layersNodesRefs;
1183
+ this._widgetApi = _widgetApi;
1184
+ }
1185
+ mediaElementsLoadingPromises = [];
1186
+ init(localData) {
1187
+ try {
1188
+ this._widgetApi.init(this._elementNodeRef, this._layersNodesRefs, localData);
1189
+ }
1190
+ catch (e) {
1191
+ console.error(e);
1192
+ }
1193
+ return Promise.resolve(true);
1194
+ }
1195
+ onPause() {
1196
+ this._widgetApi.onPause(this._elementNodeRef);
1197
+ }
1198
+ onResume() {
1199
+ this._widgetApi.onResume(this._elementNodeRef);
1200
+ }
1201
+ onStart() {
1202
+ this._widgetApi.onStart(this._elementNodeRef);
1203
+ }
1204
+ onStop() {
1205
+ this._widgetApi.onStop(this._elementNodeRef);
1206
+ }
1207
+ handleClick() {
1208
+ return false;
1209
+ }
1210
+ get isLayerForcePaused() {
1211
+ return false;
1212
+ }
1213
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `Array`, `typeof WidgetDateCountdown.api`]; }
1214
+ }
1215
+
1216
+ class Poll {
1217
+ _elementNodeRef;
1218
+ _layer;
1219
+ _widgetApi;
1220
+ static _className = "narrative-element-poll";
1221
+ static className() {
1222
+ return Poll._className;
1223
+ }
1224
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1225
+ this._elementNodeRef = _elementNodeRef;
1226
+ this._layer = _layer;
1227
+ this._widgetApi = _widgetApi;
1228
+ }
1229
+ static isTypeOf(element) {
1230
+ return element instanceof Poll;
1231
+ }
1232
+ mediaElementsLoadingPromises = [];
1233
+ init(localData) {
1234
+ try {
1235
+ this._widgetApi.init(this._elementNodeRef, localData);
1236
+ }
1237
+ catch (e) {
1238
+ console.error(e);
1239
+ }
1240
+ return Promise.resolve(true);
1241
+ }
1242
+ onPause() { }
1243
+ onResume() { }
1244
+ onStart() {
1245
+ this._widgetApi.onStart(this._elementNodeRef);
1246
+ }
1247
+ onStop() {
1248
+ this._widgetApi.onStop(this._elementNodeRef);
1249
+ }
1250
+ handleClick() {
1251
+ return false;
1252
+ }
1253
+ setUserData(id, text) {
1254
+ this._widgetApi.setUserData(id, text);
1255
+ }
1256
+ get isLayerForcePaused() {
1257
+ return false;
1258
+ }
1259
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetPoll.api`]; }
1260
+ }
1261
+
1262
+ class PollLayers {
1263
+ _elementNodeRef;
1264
+ _layer;
1265
+ _layersNodesRefs;
1266
+ _widgetApi;
1267
+ static _className = "narrative-element-poll-layers";
1268
+ static className() {
1269
+ return PollLayers._className;
1270
+ }
1271
+ constructor(_elementNodeRef, _layer, _layersNodesRefs, _widgetApi) {
1272
+ this._elementNodeRef = _elementNodeRef;
1273
+ this._layer = _layer;
1274
+ this._layersNodesRefs = _layersNodesRefs;
1275
+ this._widgetApi = _widgetApi;
1276
+ }
1277
+ static isTypeOf(element) {
1278
+ return element instanceof PollLayers;
1279
+ }
1280
+ mediaElementsLoadingPromises = [];
1281
+ init(localData) {
1282
+ try {
1283
+ this._widgetApi.init(this._elementNodeRef, this._layersNodesRefs, localData);
1284
+ }
1285
+ catch (e) {
1286
+ console.error(e);
1287
+ }
1288
+ return Promise.resolve(true);
1289
+ }
1290
+ onPause() { }
1291
+ onResume() { }
1292
+ onStart() {
1293
+ this._widgetApi.onStart(this._elementNodeRef);
1294
+ }
1295
+ onStop() {
1296
+ this._widgetApi.onStop(this._elementNodeRef);
1297
+ }
1298
+ handleClick() {
1299
+ return false;
1300
+ }
1301
+ get isLayerForcePaused() {
1302
+ return false;
1303
+ }
1304
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `Array`, `typeof WidgetPollLayers.api`]; }
1305
+ }
1306
+
1307
+ class Products {
1308
+ _elementNodeRef;
1309
+ _layer;
1310
+ _widgetApi;
1311
+ static _className = "narrative-element-products";
1312
+ static className() {
1313
+ return Products._className;
1314
+ }
1315
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1316
+ this._elementNodeRef = _elementNodeRef;
1317
+ this._layer = _layer;
1318
+ this._widgetApi = _widgetApi;
1319
+ }
1320
+ static isTypeOf(element) {
1321
+ return element instanceof Products;
1322
+ }
1323
+ mediaElementsLoadingPromises = [];
1324
+ init(localData) {
1325
+ try {
1326
+ this._widgetApi.init(this._elementNodeRef, localData);
1327
+ }
1328
+ catch (e) {
1329
+ console.error(e);
1330
+ }
1331
+ return Promise.resolve(true);
1332
+ }
1333
+ onPause() { }
1334
+ onResume() { }
1335
+ onStart() {
1336
+ this._widgetApi.onStart(this._elementNodeRef);
1337
+ }
1338
+ onStop() {
1339
+ this._widgetApi.onStop(this._elementNodeRef);
1340
+ }
1341
+ handleClick() {
1342
+ return false;
1343
+ }
1344
+ handleBackpress() {
1345
+ this._widgetApi.onHandleBackpress(this._elementNodeRef);
1346
+ }
1347
+ get elementNodeRef() {
1348
+ return this._elementNodeRef;
1349
+ }
1350
+ get isClickCapturedByWidget() {
1351
+ return this._widgetApi.isClickCapturedByWidget(this._elementNodeRef);
1352
+ }
1353
+ get isLayerForcePaused() {
1354
+ return this._widgetApi.isForcePaused(this._elementNodeRef);
1355
+ }
1356
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetProducts.api`]; }
1357
+ }
1358
+
1359
+ class Quest {
1360
+ _elementNodeRef;
1361
+ _layer;
1362
+ _widgetApi;
1363
+ static _className = "narrative-element-quest";
1364
+ static className() {
1365
+ return Quest._className;
1366
+ }
1367
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1368
+ this._elementNodeRef = _elementNodeRef;
1369
+ this._layer = _layer;
1370
+ this._widgetApi = _widgetApi;
1371
+ }
1372
+ static isTypeOf(element) {
1373
+ return element instanceof Quest;
1374
+ }
1375
+ mediaElementsLoadingPromises = [];
1376
+ init(localData) {
1377
+ return this._widgetApi.init(this._elementNodeRef, localData);
1378
+ }
1379
+ onPause() { }
1380
+ onResume() { }
1381
+ onStart() {
1382
+ this._widgetApi.onStart(this._elementNodeRef);
1383
+ }
1384
+ onStop() {
1385
+ this._widgetApi.onStop(this._elementNodeRef);
1386
+ }
1387
+ handleClick() {
1388
+ return false;
1389
+ }
1390
+ handleRouteClick(options) {
1391
+ return this._widgetApi.handleRouteClick(this._elementNodeRef, options);
1392
+ }
1393
+ get isLayerForcePaused() {
1394
+ return false;
1395
+ }
1396
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetQuest.api`]; }
1397
+ }
1398
+
1399
+ class Quiz {
1400
+ _elementNodeRef;
1401
+ _layer;
1402
+ _widgetApi;
1403
+ static _className = "narrative-element-quiz";
1404
+ static className() {
1405
+ return Quiz._className;
1406
+ }
1407
+ // widgetApi in ctor
1408
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1409
+ this._elementNodeRef = _elementNodeRef;
1410
+ this._layer = _layer;
1411
+ this._widgetApi = _widgetApi;
1412
+ }
1413
+ static isTypeOf(element) {
1414
+ return element instanceof Quiz;
1415
+ }
1416
+ mediaElementsLoadingPromises = [];
1417
+ init(localData) {
1418
+ try {
1419
+ this._widgetApi.init(this._elementNodeRef, localData);
1420
+ }
1421
+ catch (e) {
1422
+ console.error(e);
1423
+ }
1424
+ return Promise.resolve(true);
1425
+ }
1426
+ onPause() { }
1427
+ onResume() { }
1428
+ onStart() {
1429
+ this._widgetApi.onStart(this._elementNodeRef);
1430
+ }
1431
+ onStop() {
1432
+ this._widgetApi.onStop(this._elementNodeRef);
1433
+ }
1434
+ handleClick() {
1435
+ return false;
1436
+ }
1437
+ get slideQuizIsDone() {
1438
+ return this._widgetApi.slideQuizIsDone(this._elementNodeRef);
1439
+ }
1440
+ get isLayerForcePaused() {
1441
+ return false;
1442
+ }
1443
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetQuiz.api`]; }
1444
+ }
1445
+
1446
+ class QuizGrouped {
1447
+ _elementNodeRef;
1448
+ _layer;
1449
+ _widgetApi;
1450
+ static _className = "narrative-element-quiz-grouped";
1451
+ static className() {
1452
+ return QuizGrouped._className;
1453
+ }
1454
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1455
+ this._elementNodeRef = _elementNodeRef;
1456
+ this._layer = _layer;
1457
+ this._widgetApi = _widgetApi;
1458
+ }
1459
+ static isTypeOf(element) {
1460
+ return element instanceof QuizGrouped;
1461
+ }
1462
+ mediaElementsLoadingPromises = [];
1463
+ init(localData) {
1464
+ try {
1465
+ this._widgetApi.init(this._elementNodeRef, localData);
1466
+ }
1467
+ catch (e) {
1468
+ console.error(e);
1469
+ }
1470
+ return Promise.resolve(true);
1471
+ }
1472
+ onPause() { }
1473
+ onResume() { }
1474
+ onStart() {
1475
+ this._widgetApi.onStart(this._elementNodeRef);
1476
+ }
1477
+ onStop() {
1478
+ this._widgetApi.onStop(this._elementNodeRef);
1479
+ }
1480
+ handleClick() {
1481
+ return false;
1482
+ }
1483
+ get slideQuizGroupedIsDone() {
1484
+ return this._widgetApi.slideQuizIsDone(this._elementNodeRef);
1485
+ }
1486
+ get isLayerForcePaused() {
1487
+ return false;
1488
+ }
1489
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetQuizGrouped.api`]; }
1490
+ }
1491
+
1492
+ class RangeSlider {
1493
+ _elementNodeRef;
1494
+ _layer;
1495
+ _widgetApi;
1496
+ static _className = "narrative-element-range-slider";
1497
+ static className() {
1498
+ return RangeSlider._className;
1499
+ }
1500
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1501
+ this._elementNodeRef = _elementNodeRef;
1502
+ this._layer = _layer;
1503
+ this._widgetApi = _widgetApi;
1504
+ }
1505
+ static isTypeOf(element) {
1506
+ return element instanceof RangeSlider;
1507
+ }
1508
+ mediaElementsLoadingPromises = [];
1509
+ init(localData) {
1510
+ try {
1511
+ this._widgetApi.init(this._elementNodeRef, localData);
1512
+ }
1513
+ catch (e) {
1514
+ console.error(e);
1515
+ }
1516
+ return Promise.resolve(true);
1517
+ }
1518
+ onPause() { }
1519
+ onResume() { }
1520
+ onStart() {
1521
+ this._widgetApi.onStart(this._elementNodeRef);
1522
+ }
1523
+ onStop() {
1524
+ this._widgetApi.onStop(this._elementNodeRef);
1525
+ }
1526
+ get isClickCapturedBySlider() {
1527
+ return this._widgetApi.isClickCapturedBySlider(this._elementNodeRef);
1528
+ }
1529
+ handleClick() {
1530
+ return false;
1531
+ }
1532
+ get isLayerForcePaused() {
1533
+ return false;
1534
+ }
1535
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetRangeSlider.api`]; }
1536
+ }
1537
+
1538
+ class Rate {
1539
+ _elementNodeRef;
1540
+ _layer;
1541
+ _widgetApi;
1542
+ static _className = "narrative-element-rate";
1543
+ static className() {
1544
+ return Rate._className;
1545
+ }
1546
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1547
+ this._elementNodeRef = _elementNodeRef;
1548
+ this._layer = _layer;
1549
+ this._widgetApi = _widgetApi;
1550
+ }
1551
+ static isTypeOf(element) {
1552
+ return element instanceof Rate;
1553
+ }
1554
+ mediaElementsLoadingPromises = [];
1555
+ init(localData) {
1556
+ try {
1557
+ this._widgetApi.init(this._elementNodeRef, localData);
1558
+ }
1559
+ catch (e) {
1560
+ console.error(e);
1561
+ }
1562
+ return Promise.resolve(true);
1563
+ }
1564
+ onPause() { }
1565
+ onResume() { }
1566
+ onStart() {
1567
+ this._widgetApi.onStart(this._elementNodeRef);
1568
+ }
1569
+ onStop() {
1570
+ this._widgetApi.onStop(this._elementNodeRef);
1571
+ }
1572
+ handleClick() {
1573
+ return false;
1574
+ }
1575
+ setUserData(id, text) {
1576
+ this._widgetApi.setUserData(id, text);
1577
+ }
1578
+ get isLayerForcePaused() {
1579
+ return false;
1580
+ }
1581
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetRate.api`]; }
1582
+ }
1583
+
1584
+ class Share {
1585
+ _elementNodeRef;
1586
+ _layer;
1587
+ _layersNodesRefs;
1588
+ _widgetApi;
1589
+ static _className = "narrative-element-share";
1590
+ static _widgetApiName = "_narrative_share";
1591
+ static className() {
1592
+ return Share._className;
1593
+ }
1594
+ constructor(_elementNodeRef, _layer, _layersNodesRefs, _widgetApi) {
1595
+ this._elementNodeRef = _elementNodeRef;
1596
+ this._layer = _layer;
1597
+ this._layersNodesRefs = _layersNodesRefs;
1598
+ this._widgetApi = _widgetApi;
1599
+ }
1600
+ static isTypeOf(element) {
1601
+ return element instanceof Share;
1602
+ }
1603
+ mediaElementsLoadingPromises = [];
1604
+ init(localData) {
1605
+ try {
1606
+ this._widgetApi.init(this._elementNodeRef, this._layersNodesRefs, localData);
1607
+ }
1608
+ catch (e) {
1609
+ console.error(e);
1610
+ }
1611
+ return Promise.resolve(true);
1612
+ }
1613
+ onPause() { }
1614
+ onResume() { }
1615
+ onStart() {
1616
+ this._widgetApi.onStart(this._elementNodeRef);
1617
+ }
1618
+ onStop() {
1619
+ this._widgetApi.onStop(this._elementNodeRef);
1620
+ }
1621
+ handleClick() {
1622
+ return false;
1623
+ }
1624
+ complete(id, isSuccess) {
1625
+ this._widgetApi.complete(id, isSuccess);
1626
+ }
1627
+ get isLayerForcePaused() {
1628
+ return false;
1629
+ }
1630
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `Array`, `typeof WidgetShare.api`]; }
1631
+ }
1632
+
1633
+ class SwipeUpItems {
1634
+ _elementNodeRef;
1635
+ _layer;
1636
+ static _className = "narrative-element-swipe-up-items";
1637
+ static className() {
1638
+ return SwipeUpItems._className;
1639
+ }
1640
+ constructor(_elementNodeRef, _layer) {
1641
+ this._elementNodeRef = _elementNodeRef;
1642
+ this._layer = _layer;
1643
+ }
1644
+ static isTypeOf(element) {
1645
+ return element instanceof SwipeUpItems;
1646
+ }
1647
+ mediaElementsLoadingPromises = [];
1648
+ init(localData) {
1649
+ return Promise.resolve(true);
1650
+ }
1651
+ onPause() { }
1652
+ onResume() { }
1653
+ onStart() { }
1654
+ onStop() { }
1655
+ handleClick() {
1656
+ return false;
1657
+ }
1658
+ get elementNodeRef() {
1659
+ return this._elementNodeRef;
1660
+ }
1661
+ get isLayerForcePaused() {
1662
+ return false;
1663
+ }
1664
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`]; }
1665
+ }
1666
+
1667
+ class Test {
1668
+ _elementNodeRef;
1669
+ _layer;
1670
+ _widgetApi;
1671
+ static _className = "narrative-element-test";
1672
+ static className() {
1673
+ return Test._className;
1674
+ }
1675
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1676
+ this._elementNodeRef = _elementNodeRef;
1677
+ this._layer = _layer;
1678
+ this._widgetApi = _widgetApi;
1679
+ }
1680
+ static isTypeOf(element) {
1681
+ return element instanceof Test;
1682
+ }
1683
+ mediaElementsLoadingPromises = [];
1684
+ init(localData) {
1685
+ try {
1686
+ this._widgetApi.init(this._elementNodeRef, localData);
1687
+ }
1688
+ catch (e) {
1689
+ console.error(e);
1690
+ }
1691
+ return Promise.resolve(true);
1692
+ }
1693
+ onPause() { }
1694
+ onResume() { }
1695
+ onStart() {
1696
+ this._widgetApi.onStart(this._elementNodeRef);
1697
+ }
1698
+ onStop() {
1699
+ this._widgetApi.onStop(this._elementNodeRef);
1700
+ }
1701
+ handleClick() {
1702
+ return false;
1703
+ }
1704
+ get slideTestIsDone() {
1705
+ return this._widgetApi.slideTestIsDone(this._elementNodeRef);
1706
+ }
1707
+ get slideTestWithTimer() {
1708
+ return this._widgetApi.slideTestWithTimer(this._elementNodeRef);
1709
+ }
1710
+ get isLayerForcePaused() {
1711
+ return false;
1712
+ }
1713
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetTest.api`]; }
1714
+ }
1715
+
1716
+ class Vote {
1717
+ _elementNodeRef;
1718
+ _layer;
1719
+ _widgetApi;
1720
+ static _className = "narrative-element-vote";
1721
+ static className() {
1722
+ return Vote._className;
1723
+ }
1724
+ constructor(_elementNodeRef, _layer, _widgetApi) {
1725
+ this._elementNodeRef = _elementNodeRef;
1726
+ this._layer = _layer;
1727
+ this._widgetApi = _widgetApi;
1728
+ }
1729
+ mediaElementsLoadingPromises = [];
1730
+ init(localData) {
1731
+ try {
1732
+ this._widgetApi.init(this._elementNodeRef, localData);
1733
+ }
1734
+ catch (e) {
1735
+ console.error(e);
1736
+ }
1737
+ return Promise.resolve(true);
1738
+ }
1739
+ onPause() { }
1740
+ onResume() { }
1741
+ onStart() {
1742
+ this._widgetApi.onStart(this._elementNodeRef);
1743
+ }
1744
+ onStop() {
1745
+ this._widgetApi.onStop(this._elementNodeRef);
1746
+ }
1747
+ handleClick() {
1748
+ return false;
1749
+ }
1750
+ get isLayerForcePaused() {
1751
+ return false;
1752
+ }
1753
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof WidgetVote.api`]; }
1754
+ }
1755
+
1756
+ class Text {
1757
+ _elementNodeRef;
1758
+ _layer;
1759
+ static _className = "narrative-element-text";
1760
+ static className() {
1761
+ return Text._className;
1762
+ }
1763
+ constructor(_elementNodeRef, _layer) {
1764
+ this._elementNodeRef = _elementNodeRef;
1765
+ this._layer = _layer;
1766
+ }
1767
+ mediaElementsLoadingPromises = [];
1768
+ init(localData) {
1769
+ return Promise.resolve(true);
1770
+ }
1771
+ onPause() { }
1772
+ onResume() { }
1773
+ onStart() { }
1774
+ onStop() { }
1775
+ handleClick() {
1776
+ return false;
1777
+ }
1778
+ get isLayerForcePaused() {
1779
+ return false;
1780
+ }
1781
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`]; }
1782
+ }
1783
+
1784
+ const waitForImageHtmlElementLoad = async (nodeRef) => {
1785
+ return new Promise((resolve, reject) => {
1786
+ const onLoad = function () {
1787
+ requestAnimationFrame(() => requestAnimationFrame(() => {
1788
+ resolve(nodeRef);
1789
+ nodeRef.removeEventListener("load", onLoad);
1790
+ }));
1791
+ };
1792
+ nodeRef.addEventListener("load", onLoad);
1793
+ if (nodeRef.complete && 0 !== nodeRef.naturalHeight) {
1794
+ requestAnimationFrame(() => {
1795
+ requestAnimationFrame(() => {
1796
+ resolve(nodeRef);
1797
+ });
1798
+ });
1799
+ }
1800
+ nodeRef.addEventListener("error", err => reject(err));
1801
+ });
1802
+ };
1803
+ const waitForVideoHtmlElementLoad = async (nodeRef) => {
1804
+ return new Promise((resolve, reject) => {
1805
+ if (void 0 !== nodeRef.oncanplaythrough) {
1806
+ const onCanplaythrough = () => {
1807
+ requestAnimationFrame(() => {
1808
+ requestAnimationFrame(() => {
1809
+ resolve(nodeRef);
1810
+ nodeRef.removeEventListener("canplaythrough", onCanplaythrough);
1811
+ });
1812
+ });
1813
+ };
1814
+ nodeRef.addEventListener("canplaythrough", onCanplaythrough);
1815
+ nodeRef.load();
1816
+ }
1817
+ else {
1818
+ var onCanPlay = function () {
1819
+ requestAnimationFrame(() => {
1820
+ requestAnimationFrame(() => {
1821
+ resolve(nodeRef);
1822
+ nodeRef.removeEventListener("canplay", onCanPlay);
1823
+ });
1824
+ });
1825
+ };
1826
+ nodeRef.addEventListener("canplay", onCanPlay);
1827
+ nodeRef.load();
1828
+ }
1829
+ });
1830
+ };
1831
+ function isObject(value) {
1832
+ let type = typeof value;
1833
+ return value != null && (type === "object" || type === "function");
1834
+ }
1835
+ function isFunction(functionToCheck) {
1836
+ let getType = {};
1837
+ return functionToCheck && getType.toString.call(functionToCheck) === "[object Function]";
1838
+ }
1839
+
1840
+ class Image extends ClickableBase {
1841
+ _elementNodeRef;
1842
+ _layer;
1843
+ static _className = "narrative-element-image";
1844
+ static className() {
1845
+ return Image._className;
1846
+ }
1847
+ constructor(_elementNodeRef, _layer) {
1848
+ super(_elementNodeRef);
1849
+ this._elementNodeRef = _elementNodeRef;
1850
+ this._layer = _layer;
1851
+ const mediaElements = Array.from(this._elementNodeRef.querySelectorAll("img"));
1852
+ this.mediaElementsLoadingPromises = mediaElements.map(waitForImageHtmlElementLoad);
1853
+ }
1854
+ mediaElementsLoadingPromises = [];
1855
+ init(localData) {
1856
+ return Promise.resolve(true);
1857
+ }
1858
+ onPause() { }
1859
+ onResume() { }
1860
+ onStart() { }
1861
+ onStop() { }
1862
+ handleClick() {
1863
+ return false;
1864
+ }
1865
+ get isLayerForcePaused() {
1866
+ return false;
1867
+ }
1868
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`]; }
1869
+ }
1870
+
1871
+ class SwipeUp {
1872
+ _elementNodeRef;
1873
+ _layer;
1874
+ static _className = "narrative-element-swipe-up";
1875
+ static className() {
1876
+ return SwipeUp._className;
1877
+ }
1878
+ constructor(_elementNodeRef, _layer) {
1879
+ this._elementNodeRef = _elementNodeRef;
1880
+ this._layer = _layer;
1881
+ }
1882
+ static isTypeOf(element) {
1883
+ return element instanceof SwipeUp;
1884
+ }
1885
+ mediaElementsLoadingPromises = [];
1886
+ init(localData) {
1887
+ return Promise.resolve(true);
1888
+ }
1889
+ onPause() { }
1890
+ onResume() { }
1891
+ onStart() { }
1892
+ onStop() { }
1893
+ handleClick() {
1894
+ return false;
1895
+ }
1896
+ get elementNodeRef() {
1897
+ return this._elementNodeRef;
1898
+ }
1899
+ get isLayerForcePaused() {
1900
+ return false;
1901
+ }
1902
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`]; }
1903
+ }
1904
+
1905
+ class Video {
1906
+ _elementNodeRef;
1907
+ _layer;
1908
+ _VideoPlayer;
1909
+ _sdkApi;
1910
+ static _className = "narrative-element-video";
1911
+ static className() {
1912
+ return Video._className;
1913
+ }
1914
+ _video;
1915
+ _isVOD = false;
1916
+ _vodData;
1917
+ _vodPlayerInstance = null;
1918
+ _videoStateAdapter = null;
1919
+ constructor(_elementNodeRef, _layer, _VideoPlayer, _sdkApi) {
1920
+ this._elementNodeRef = _elementNodeRef;
1921
+ this._layer = _layer;
1922
+ this._VideoPlayer = _VideoPlayer;
1923
+ this._sdkApi = _sdkApi;
1924
+ const _video = this._elementNodeRef.querySelector("video");
1925
+ if (!_video) {
1926
+ return;
1927
+ }
1928
+ this._video = _video;
1929
+ // _video.addEventListener("canplay", () => console.log("canplay", true));
1930
+ // _video.addEventListener("complete", () => console.log("complete", true));
1931
+ // _video.addEventListener("emptied", () => console.log("emptied", true));
1932
+ // _video.addEventListener("ended", () => console.log("ended", true));
1933
+ // _video.addEventListener("pause", () => console.log("pause", true));
1934
+ // _video.addEventListener("play", () => console.log("play", true));
1935
+ // _video.addEventListener("playing", () => console.log("playing", true));
1936
+ // _video.addEventListener("progress", () => console.log("progress", true));
1937
+ // _video.addEventListener("seeked", () => console.log("seeked", true));
1938
+ // _video.addEventListener("seeking", () => console.log("seeking", true));
1939
+ // _video.addEventListener("stalled", () => console.log("stalled", true));
1940
+ // _video.addEventListener("suspend", () => console.log("suspend", true));
1941
+ // _video.addEventListener("waiting", () => console.log("waiting", true));
1942
+ // _video.addEventListener("timeupdate", (e) => console.log(`timeupdate: ${e.timeStamp}`, true));
1943
+ // _video.addEventListener("timeupdate", (e) =>_log(`timeupdate: ${e.timeStamp}`, true));
1944
+ const mediaImageElements = Array.from(this._elementNodeRef.querySelectorAll("img"));
1945
+ this.mediaElementsLoadingPromises = mediaImageElements.map(waitForImageHtmlElementLoad);
1946
+ this._elementNodeRef.classList.add("init");
1947
+ if (this._video.getAttribute("data-default-muted") == null) {
1948
+ this._video.setAttribute("data-default-muted", this._video.muted ? "1" : "0");
1949
+ }
1950
+ const vodData_ = this._video.getAttribute("data-vod");
1951
+ if (vodData_ != null) {
1952
+ try {
1953
+ this._vodData = this._convertMpdUrls(JSON.parse(vodData_));
1954
+ }
1955
+ catch (e) {
1956
+ console.error(e);
1957
+ }
1958
+ }
1959
+ this._isVOD = Boolean(this._vodData != null && this._VideoPlayer != null);
1960
+ if (this._isVOD) {
1961
+ this.mediaElementsLoadingPromises.push(this._initVOD(this._vodData));
1962
+ }
1963
+ else {
1964
+ this.mediaElementsLoadingPromises.push(waitForVideoHtmlElementLoad(this._video));
1965
+ }
1966
+ // console.log({mediaElementsLoadingPromises: this.mediaElementsLoadingPromises})
1967
+ }
1968
+ static isTypeOf(element) {
1969
+ return element instanceof Video;
1970
+ }
1971
+ mediaElementsLoadingPromises = [];
1972
+ init(localData) {
1973
+ return Promise.resolve(true);
1974
+ }
1975
+ _isScreenOnPause = false;
1976
+ onPause() {
1977
+ this._isScreenOnPause = true;
1978
+ }
1979
+ onResume() {
1980
+ this._isScreenOnPause = false;
1981
+ }
1982
+ onStart() { }
1983
+ onStop() { }
1984
+ _initVOD(vodData) {
1985
+ const onWaiting = () => {
1986
+ /**
1987
+ * When screen on pause - ignore onWaiting
1988
+ * (triggered when video paused, not only when canplay = false)
1989
+ */
1990
+ if (this._isScreenOnPause) {
1991
+ return;
1992
+ }
1993
+ // console.log("onWaiting")
1994
+ // @ts-ignore
1995
+ // _log("waiting", true);
1996
+ this._video.setAttribute("data-waiting", "1");
1997
+ // @ts-ignore
1998
+ // _log(`waiting: ${this._video.currentTime}`, true);
1999
+ this._layer.timeline.onSlideDataWaiting(this._video.currentTime * 1000);
2000
+ // window.synthErrorId = setTimeout(synthError, 15000);
2001
+ };
2002
+ // this._video.addEventListener("waiting", onWaiting);
2003
+ const onPlaying = () => {
2004
+ // console.log("onPlaying");
2005
+ // _log("playing", true);
2006
+ // TODO via class instead of data attr
2007
+ if (this._video.getAttribute("data-waiting") === "1") {
2008
+ this._video.setAttribute("data-waiting", "0");
2009
+ this._layer.timeline.slideResumed(this._video.currentTime * 1000);
2010
+ // @ts-ignore
2011
+ // _log(`playing: ${this._video.currentTime}`, true);
2012
+ // clearTimeout(window.synthErrorId);
2013
+ }
2014
+ };
2015
+ // this._video.addEventListener("playing", onPlaying);
2016
+ this._videoStateAdapter = new VideoStateAdapter(this._video, onWaiting, onPlaying);
2017
+ // @ts-ignore
2018
+ // this._video.addEventListener("timeupdate", (e) =>_log(`timeupdate: ${e.timeStamp}`, true));
2019
+ // this._video.addEventListener("timeupdate", (e) =>console.log(`timeupdate: ${e.timeStamp}: ${this._video.currentTime}`));
2020
+ return new Promise((resolve, reject) => {
2021
+ // console.log(`initVoD slide idx: ${this._layer.slideIndex}`);
2022
+ // console.log("_initVOD 1");
2023
+ // @ts-ignore
2024
+ if (this._VideoPlayer != null && this._VideoPlayer.isBrowserSupported() && ("MediaSource" in window || "ManagedMediaSource" in window)) {
2025
+ const player = new this._VideoPlayer();
2026
+ // console.log("_initVOD 2");
2027
+ // @ts-ignore
2028
+ const onErrorEvent = event => {
2029
+ // Extract the PlayerError object from the event.
2030
+ onError(event.detail);
2031
+ };
2032
+ // @ts-ignore
2033
+ player.addEventListener("error", onErrorEvent);
2034
+ // @ts-ignore
2035
+ const onError = error => {
2036
+ // Log the error.
2037
+ console.error("Error code", error.code, "object", error);
2038
+ // _log(`video error: ${video.currentTime} code: ${error.code}`, true);
2039
+ if (this._video.paused) {
2040
+ this._layer.stopInternal();
2041
+ this._layer.timeline.onSlideError(this._video.currentTime * 1000);
2042
+ }
2043
+ };
2044
+ // console.log("_initVOD 3");
2045
+ player.attach(this._video).then(() => {
2046
+ // console.log("_initVOD 4");
2047
+ try {
2048
+ player
2049
+ // @ts-ignore
2050
+ .load(this._VideoPlayer.convertJsonToUri(vodData), 0, "application/json")
2051
+ .then(() => {
2052
+ // console.log("_initVOD 5");
2053
+ this._vodPlayerInstance = player;
2054
+ // This runs if the asynchronous load is successful.
2055
+ resolve(this._video);
2056
+ })
2057
+ .catch(reason => {
2058
+ // console.log("_initVOD 6", reason);
2059
+ // onError is executed if the asynchronous load fails.
2060
+ reject(reason);
2061
+ onError(reason);
2062
+ });
2063
+ }
2064
+ catch (e) {
2065
+ // onError is executed if the asynchronous load fails.
2066
+ reject(e);
2067
+ onError(e);
2068
+ }
2069
+ });
2070
+ }
2071
+ else {
2072
+ // use default (not mpd) video stream
2073
+ // console.error("Browser not supported!");
2074
+ // get std video stream
2075
+ let src = "";
2076
+ if (vodData && vodData.formats != null && Array.isArray(vodData.formats) && vodData.formats.length > 0) {
2077
+ src = vodData.formats[0].url;
2078
+ this._video.src = src;
2079
+ resolve(this._video);
2080
+ }
2081
+ else {
2082
+ reject("Empty formats list");
2083
+ }
2084
+ }
2085
+ });
2086
+ }
2087
+ _convertMpdUrls(mpd_) {
2088
+ if (this._sdkApi.isWeb) {
2089
+ return mpd_;
2090
+ }
2091
+ if (isObject(mpd_) && mpd_.adaptiveFormats != null && Array.isArray(mpd_.adaptiveFormats)) {
2092
+ const mpd = { ...mpd_ };
2093
+ for (let i = 0; i < mpd.adaptiveFormats.length; ++i) {
2094
+ mpd.adaptiveFormats[i].url = `${this._sdkApi.isAndroid ? `http://vod-asset/` : `vod-asset://`}${mpd.adaptiveFormats[i].cacheName}`;
2095
+ }
2096
+ return mpd;
2097
+ }
2098
+ return mpd_;
2099
+ }
2100
+ handleClick() {
2101
+ return false;
2102
+ }
2103
+ get isLayerForcePaused() {
2104
+ return false;
2105
+ }
2106
+ _videoStartedPromise = null;
2107
+ get videoStartedPromise() {
2108
+ return this._videoStartedPromise;
2109
+ }
2110
+ start(muted = true) {
2111
+ this._videoStartedPromise = new Promise(async (resolve) => {
2112
+ // invariant - always wait for mediaElementsLoadingPromises
2113
+ // else call of _initVOD can start and onAllMediaLoaded failed
2114
+ // TODO - add for all Elements state invariant protection
2115
+ Promise.all(this.mediaElementsLoadingPromises).finally(async () => {
2116
+ if (this._video) {
2117
+ if (this._isVOD && this._vodPlayerInstance === null) {
2118
+ // console.log("_initVOD 5.1");
2119
+ await this._initVOD(this._vodData);
2120
+ }
2121
+ // console.log("Video:start => this._video.pause()");
2122
+ this._video.pause();
2123
+ this._video.currentTime = 0;
2124
+ // remove init class
2125
+ // if vod - create VoD player
2126
+ if (this._video.getAttribute("data-default-muted") !== "1") {
2127
+ this._video.muted = muted;
2128
+ }
2129
+ const playPromise = this._video.play();
2130
+ if (playPromise != null) {
2131
+ playPromise
2132
+ .then(() => {
2133
+ this._video.currentTime = 0;
2134
+ this._elementNodeRef.classList.remove("init");
2135
+ resolve({
2136
+ currentTime: this._video.currentTime,
2137
+ });
2138
+ })
2139
+ .catch(error => {
2140
+ console.error(error);
2141
+ resolve({
2142
+ currentTime: this._video.currentTime,
2143
+ });
2144
+ });
2145
+ }
2146
+ else {
2147
+ setTimeout(() => {
2148
+ this._video.currentTime = 0;
2149
+ this._elementNodeRef.classList.remove("init");
2150
+ resolve({
2151
+ currentTime: this._video.currentTime,
2152
+ });
2153
+ }, 0);
2154
+ }
2155
+ }
2156
+ else {
2157
+ resolve({
2158
+ currentTime: 0,
2159
+ });
2160
+ }
2161
+ });
2162
+ });
2163
+ return this._videoStartedPromise;
2164
+ }
2165
+ pause(resetVideoTime = false) {
2166
+ if (this._video) {
2167
+ // console.trace("Video pause");
2168
+ this._video.pause();
2169
+ if (resetVideoTime) {
2170
+ this._video.currentTime = 0;
2171
+ }
2172
+ return this._video.currentTime;
2173
+ }
2174
+ return null;
2175
+ }
2176
+ async resume() {
2177
+ this._videoStartedPromise = new Promise((resolve, reject) => {
2178
+ // _log("video before resume: " + video.currentTime);
2179
+ const ts = this._video.currentTime;
2180
+ if (!this._video.paused) {
2181
+ // console.log("Video:resume => this._video.pause()");
2182
+ this._video.pause();
2183
+ }
2184
+ const playPromise = this._video.play();
2185
+ // console.log({ playPromise });
2186
+ if (playPromise != null) {
2187
+ playPromise
2188
+ .then(() => {
2189
+ // console.log("resolve 1");
2190
+ if (this._video.currentTime < ts) {
2191
+ // console.log("resolve 1.1", { ts });
2192
+ this._video.currentTime = ts;
2193
+ }
2194
+ resolve({ currentTime: this._video.currentTime });
2195
+ })
2196
+ .catch(error => {
2197
+ console.error(error);
2198
+ // console.log("error 1");
2199
+ if (this._video.currentTime < ts) {
2200
+ this._video.currentTime = ts;
2201
+ }
2202
+ resolve({ currentTime: this._video.currentTime });
2203
+ });
2204
+ }
2205
+ else {
2206
+ setTimeout(() => {
2207
+ // console.log("resolve 2");
2208
+ if (this._video.currentTime < ts) {
2209
+ this._video.currentTime = ts;
2210
+ }
2211
+ resolve({ currentTime: this._video.currentTime });
2212
+ }, 0);
2213
+ }
2214
+ });
2215
+ return this._videoStartedPromise;
2216
+ }
2217
+ async stop() {
2218
+ if (this._video) {
2219
+ // console.log("Video:stop => this._video.pause()");
2220
+ this._video.pause();
2221
+ }
2222
+ if (this._vodPlayerInstance) {
2223
+ setTimeout(async () => {
2224
+ // destroy VOD on slideStop with timeout, bcz on Android flashes white screen on several frames (if destroy without timeout)
2225
+ if (this._vodPlayerInstance) {
2226
+ try {
2227
+ // show poster
2228
+ this._elementNodeRef.classList.add("init");
2229
+ if (this._videoStateAdapter) {
2230
+ this._videoStateAdapter.destroy();
2231
+ this._videoStateAdapter = null;
2232
+ }
2233
+ await this._vodPlayerInstance.detach();
2234
+ await this._vodPlayerInstance.destroy();
2235
+ // clean up - so we can reinit on slide start, id need it
2236
+ this._vodPlayerInstance = null;
2237
+ }
2238
+ catch (e) {
2239
+ console.error(e);
2240
+ }
2241
+ }
2242
+ }, 100);
2243
+ }
2244
+ }
2245
+ enableAudio() {
2246
+ if (this._video.getAttribute("data-default-muted") !== "1") {
2247
+ this._video.muted = false;
2248
+ }
2249
+ }
2250
+ disableAudio() {
2251
+ if (this._video.getAttribute("data-default-muted") !== "1") {
2252
+ this._video.muted = true;
2253
+ }
2254
+ }
2255
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Layer`, `typeof VideoPlayer | undefined`, `SDKApi`]; }
2256
+ }
2257
+ // class VideoStateAdapter {
2258
+ //
2259
+ // // все же следить по timeupdate
2260
+ //
2261
+ // constructor(private readonly _video: HTMLVideoElement, private readonly _onWaitingCb: () => void, private readonly _onPlayingCb: () => void) {
2262
+ // this._video.addEventListener("playing", () => this._onPlaying());
2263
+ // this._video.addEventListener("waiting", () => this._onWaiting());
2264
+ // }
2265
+ //
2266
+ // private _state = VIDEO_STATE.WAITING;
2267
+ //
2268
+ // private _onWaiting() {
2269
+ // if (this._playingCheckerId != null) {
2270
+ // window.clearTimeout(this._playingCheckerId);
2271
+ // }
2272
+ // this._state = VIDEO_STATE.WAITING;
2273
+ // this._triggerUpdate();
2274
+ // }
2275
+ //
2276
+ // // in ms
2277
+ // private _latestPlayingStamp: number = 0;
2278
+ // private _latestPlayingDateStamp: number = new Date().getTime();
2279
+ // private _playingCheckerId: number = null!;
2280
+ //
2281
+ // private _onPlaying() {
2282
+ // this._state = VIDEO_STATE.PLAYING;
2283
+ // if (this._playingCheckerId != null) {
2284
+ // window.clearTimeout(this._playingCheckerId);
2285
+ // }
2286
+ // this._latestPlayingStamp = this._video.currentTime * 1000;
2287
+ // this._latestPlayingDateStamp = new Date().getTime();
2288
+ // this._triggerUpdate();
2289
+ //
2290
+ // // если через 100ms не время не изменится - встаем на паузу
2291
+ // // если до исполнения таймера были другие события - то отменять таймер
2292
+ // this._playingCheckerId = window.setTimeout(() => {
2293
+ // const currentTime = this._video.currentTime * 1000;
2294
+ // const diff = currentTime - this._latestPlayingStamp;
2295
+ //
2296
+ // const timeSpent = new Date().getTime() - this._latestPlayingDateStamp;
2297
+ //
2298
+ // // @ts-ignore
2299
+ // _log(`check, currentTime: ${currentTime}, latestPlayingStamp: ${this._latestPlayingStamp}, diff: ${diff}, timeSpent: ${timeSpent}`, true);
2300
+ // if (diff <= (timeSpent / 2)) {
2301
+ // this._state = VIDEO_STATE.WAITING;
2302
+ // this._triggerUpdate();
2303
+ // }
2304
+ // }, 100);
2305
+ // }
2306
+ //
2307
+ // private _triggerUpdate() {
2308
+ // if (this._state === VIDEO_STATE.PLAYING) {
2309
+ // this._onPlayingCb();
2310
+ // } else if (this._state === VIDEO_STATE.WAITING) {
2311
+ // this._onWaitingCb();
2312
+ // }
2313
+ // }
2314
+ // }
2315
+ class VideoStateAdapter {
2316
+ _video;
2317
+ _onWaitingCb;
2318
+ _onPlayingCb;
2319
+ // все же следить по timeupdate
2320
+ constructor(_video, _onWaitingCb, _onPlayingCb) {
2321
+ this._video = _video;
2322
+ this._onWaitingCb = _onWaitingCb;
2323
+ this._onPlayingCb = _onPlayingCb;
2324
+ // this._video.addEventListener("playing", () => this._onPlaying());
2325
+ // this._video.addEventListener("waiting", () => this._onWaiting());
2326
+ this._video.addEventListener("timeupdate", this._onTimeupdateHandler);
2327
+ }
2328
+ destroy() {
2329
+ this._video.removeEventListener("timeupdate", this._onTimeupdateHandler);
2330
+ }
2331
+ _onTimeupdateHandler = this._onTimeupdate.bind(this);
2332
+ _timeupdate = Date.now();
2333
+ _state = 0 /* VIDEO_STATE.UNKNOWN */;
2334
+ // The event frequency is dependent on the system load, but will be thrown between about 4Hz and 66Hz (assuming the event handlers don't take longer than 250ms to run).
2335
+ _maxDiff = 300;
2336
+ _waitingCheckerId = null;
2337
+ _playingCheckerId = null;
2338
+ _onTimeupdate() {
2339
+ this._timeupdate = Date.now();
2340
+ if (this._playingCheckerId != null) {
2341
+ window.clearTimeout(this._playingCheckerId);
2342
+ }
2343
+ if (this._state !== 1 /* VIDEO_STATE.PLAYING */) {
2344
+ this._state = 1 /* VIDEO_STATE.PLAYING */;
2345
+ this._triggerUpdate();
2346
+ }
2347
+ // todo - add debounce
2348
+ this._playingCheckerId = window.setTimeout(() => {
2349
+ if (Date.now() - this._timeupdate >= this._maxDiff / 2) {
2350
+ this._state = 2 /* VIDEO_STATE.WAITING */;
2351
+ this._triggerUpdate();
2352
+ }
2353
+ }, this._maxDiff);
2354
+ // if (this._state !== VIDEO_STATE.PLAYING) {
2355
+ // this._onPlaying();
2356
+ // }
2357
+ }
2358
+ _onWaiting() {
2359
+ if (this._playingCheckerId != null) {
2360
+ window.clearTimeout(this._playingCheckerId);
2361
+ }
2362
+ // @ts-ignore
2363
+ // _log(`_onWaiting, _timeupdate: ${this._timeupdate}`, true);
2364
+ this._state = 2 /* VIDEO_STATE.WAITING */;
2365
+ this._triggerUpdate();
2366
+ }
2367
+ _onPlaying() {
2368
+ if (this._playingCheckerId != null) {
2369
+ window.clearTimeout(this._playingCheckerId);
2370
+ }
2371
+ // @ts-ignore
2372
+ // _log(`_onPlaying, _timeupdate: ${this._timeupdate}`, true);
2373
+ this._playingCheckerId = window.setTimeout(() => {
2374
+ // @ts-ignore
2375
+ _log(`_onPlaying cb, _timeupdate: ${this._timeupdate}, now: ${Date.now()}, diff: ${Date.now() - this._timeupdate}`, true);
2376
+ if (Date.now() - this._timeupdate <= this._maxDiff / 2) {
2377
+ // @ts-ignore
2378
+ // _log(`_onPlaying if`, true);
2379
+ this._state = 1 /* VIDEO_STATE.PLAYING */;
2380
+ this._triggerUpdate();
2381
+ }
2382
+ }, this._maxDiff);
2383
+ // this._state = VIDEO_STATE.PLAYING;
2384
+ // if (this._playingCheckerId != null) {
2385
+ // window.clearTimeout(this._playingCheckerId);
2386
+ // }
2387
+ // this._latestPlayingStamp = this._video.currentTime * 1000;
2388
+ // this._latestPlayingDateStamp = new Date().getTime();
2389
+ // this._triggerUpdate();
2390
+ //
2391
+ // // если через 100ms не время не изменится - встаем на паузу
2392
+ // // если до исполнения таймера были другие события - то отменять таймер
2393
+ // this._playingCheckerId = window.setTimeout(() => {
2394
+ // const currentTime = this._video.currentTime * 1000;
2395
+ // const diff = currentTime - this._latestPlayingStamp;
2396
+ //
2397
+ // const timeSpent = new Date().getTime() - this._latestPlayingDateStamp;
2398
+ //
2399
+ // // @ts-ignore
2400
+ // _log(`check, currentTime: ${currentTime}, latestPlayingStamp: ${this._latestPlayingStamp}, diff: ${diff}, timeSpent: ${timeSpent}`, true);
2401
+ // if (diff <= (timeSpent / 2)) {
2402
+ // this._state = VIDEO_STATE.WAITING;
2403
+ // this._triggerUpdate();
2404
+ // }
2405
+ // }, 100);
2406
+ }
2407
+ _triggerUpdate() {
2408
+ if (this._state === 1 /* VIDEO_STATE.PLAYING */) {
2409
+ this._onPlayingCb();
2410
+ }
2411
+ else if (this._state === 2 /* VIDEO_STATE.WAITING */) {
2412
+ this._onWaitingCb();
2413
+ }
2414
+ }
2415
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLVideoElement`, `() => void`, `() => void`]; }
2416
+ }
2417
+
2418
+ // export const tryCreateAtLayer = (layerNodeRef: HTMLElement): IElement {
2419
+ // const
2420
+ // }
2421
+ // args nodeRef, elementClassName
2422
+ const tryCreateFromHtmlElement = (nodeRef, layer) => {
2423
+ const layoutApi = layer.layoutService.layoutApi;
2424
+ const layersNodesRefs = layer.slide.layersNodesRefs;
2425
+ for (let elementClassName of nodeRef.classList.values()) {
2426
+ // console.log({ elementClassName });
2427
+ switch (elementClassName) {
2428
+ //////// base elements ///////
2429
+ case Text.className():
2430
+ return new Text(nodeRef, layer);
2431
+ case Button.className():
2432
+ return new Button(nodeRef, layer);
2433
+ case Image.className():
2434
+ return new Image(nodeRef, layer);
2435
+ case SwipeUp.className():
2436
+ return new SwipeUp(nodeRef, layer);
2437
+ case SwipeUpItems.className():
2438
+ return new SwipeUpItems(nodeRef, layer);
2439
+ case Video.className():
2440
+ return new Video(nodeRef, layer, layoutApi.VideoPlayer, layer.layoutService.sdkApi);
2441
+ //////// widgets ///////
2442
+ case Copy.className():
2443
+ return layoutApi.widgetCopyApi ? new Copy(nodeRef, layer, layoutApi.widgetCopyApi) : null;
2444
+ case Barcode.className():
2445
+ return layoutApi.widgetBarcodeApi ? new Barcode(nodeRef, layer, layoutApi.widgetBarcodeApi) : null;
2446
+ case DataInput.className():
2447
+ return layoutApi.widgetDataInputApi ? new DataInput(nodeRef, layer, layoutApi.widgetDataInputApi) : null;
2448
+ case DateCountdown.className():
2449
+ return layoutApi.widgetDateCountdownApi ? new DateCountdown(nodeRef, layer, layersNodesRefs, layoutApi.widgetDateCountdownApi) : null;
2450
+ case Poll.className():
2451
+ return layoutApi.widgetPollApi ? new Poll(nodeRef, layer, layoutApi.widgetPollApi) : null;
2452
+ case PollLayers.className():
2453
+ return layoutApi.widgetPollLayersApi ? new PollLayers(nodeRef, layer, layersNodesRefs, layoutApi.widgetPollLayersApi) : null;
2454
+ case Quest.className():
2455
+ return layoutApi.widgetQuestApi ? new Quest(nodeRef, layer, layoutApi.widgetQuestApi) : null;
2456
+ case Quiz.className():
2457
+ return layoutApi.widgetQuizApi ? new Quiz(nodeRef, layer, layoutApi.widgetQuizApi) : null;
2458
+ case QuizGrouped.className():
2459
+ return layoutApi.widgetQuizGroupedApi ? new QuizGrouped(nodeRef, layer, layoutApi.widgetQuizGroupedApi) : null;
2460
+ case RangeSlider.className():
2461
+ return layoutApi.widgetRangeSliderApi ? new RangeSlider(nodeRef, layer, layoutApi.widgetRangeSliderApi) : null;
2462
+ case Rate.className():
2463
+ return layoutApi.widgetRateApi ? new Rate(nodeRef, layer, layoutApi.widgetRateApi) : null;
2464
+ case Share.className():
2465
+ return layoutApi.widgetShareApi ? new Share(nodeRef, layer, layersNodesRefs, layoutApi.widgetShareApi) : null;
2466
+ case Test.className():
2467
+ return layoutApi.widgetTestApi ? new Test(nodeRef, layer, layoutApi.widgetTestApi) : null;
2468
+ case Vote.className():
2469
+ return layoutApi.widgetVoteApi ? new Vote(nodeRef, layer, layoutApi.widgetVoteApi) : null;
2470
+ case Products.className():
2471
+ return layoutApi.widgetProductsApi ? new Products(nodeRef, layer, layoutApi.widgetProductsApi) : null;
2472
+ }
2473
+ }
2474
+ return null;
2475
+ };
2476
+
2477
+ var TimelineDisabledState;
2478
+ (function (TimelineDisabledState) {
2479
+ TimelineDisabledState[TimelineDisabledState["disabled"] = 0] = "disabled";
2480
+ TimelineDisabledState[TimelineDisabledState["enabled"] = 1] = "enabled";
2481
+ })(TimelineDisabledState || (TimelineDisabledState = {}));
2482
+ class SlideTimeline {
2483
+ slideIndex;
2484
+ slideDuration;
2485
+ slideDisabledTimer;
2486
+ slideReady;
2487
+ _afterResumeQueuePush;
2488
+ constructor(slideIndex, slideDuration, slideDisabledTimer, slideReady, _afterResumeQueuePush) {
2489
+ this.slideIndex = slideIndex;
2490
+ this.slideDuration = slideDuration;
2491
+ this.slideDisabledTimer = slideDisabledTimer;
2492
+ this.slideReady = slideReady;
2493
+ this._afterResumeQueuePush = _afterResumeQueuePush;
2494
+ this.timelineDisabledState = this.slideDisabledTimer ? TimelineDisabledState.disabled : TimelineDisabledState.enabled;
2495
+ }
2496
+ resumedAt = new Date().getTime();
2497
+ timeSpent = 0;
2498
+ timelineDisabledState;
2499
+ currentState = "stop" /* TIMELINE_ACTION.STOP */;
2500
+ static get layoutService() {
2501
+ return container.get({ identifier: "LayoutService" });
2502
+ }
2503
+ get layoutService() {
2504
+ return SlideTimeline.layoutService;
2505
+ }
2506
+ get isSDKSupportUpdateTimeline() {
2507
+ if (SlideTimeline.layoutService.sdkApi.isAndroid) {
2508
+ return SlideTimeline.layoutService.env.Android && "updateTimeline" in SlideTimeline.layoutService.env.Android;
2509
+ }
2510
+ else if (SlideTimeline.layoutService.sdkApi.isIOS) {
2511
+ const mh = SlideTimeline.layoutService.env?.webkit?.messageHandlers ?? {};
2512
+ return "updateTimeline" in mh;
2513
+ }
2514
+ else {
2515
+ return false;
2516
+ }
2517
+ }
2518
+ get index() {
2519
+ return this.slideIndex;
2520
+ }
2521
+ async updateTimeline(action, showLoader = false, showError = false) {
2522
+ // два кейса
2523
+ // когда есть слои и у слоя вызываем showLayer который вызывает startTimer до старта слайда, потом start от sdk
2524
+ // в итоге два события вместо одного (баг)
2525
+ // второй кейс - когда заполнили виджет и он вызвал startDisabledTimer
2526
+ // в этом случае проверка стейта action === this.currentState не выполнит startTimer (баг)
2527
+ // можно сделать action_start_timer_disabeld и timer_enabled чтобы это было два разных состояния
2528
+ // if (action === this.currentState) {
2529
+ // return;
2530
+ // }
2531
+ this.currentState = action;
2532
+ let currentTime = this.timeSpent;
2533
+ let duration = this.slideDuration;
2534
+ // tmp
2535
+ // todo брать из модели
2536
+ if (!duration) {
2537
+ duration = DEFAULT_SLIDE_DURATION;
2538
+ }
2539
+ if (this.timelineDisabledState === TimelineDisabledState.disabled) {
2540
+ currentTime = 0;
2541
+ duration = 0;
2542
+ }
2543
+ if (currentTime > duration) {
2544
+ currentTime = duration;
2545
+ }
2546
+ //@ts-ignore
2547
+ // window._log(`updateTimeline 1, a: ${action} ct: ${currentTime} d: ${duration} tds: ${this.timelineDisabledState}`, true);
2548
+ await this.slideReady.then();
2549
+ //@ts-ignore
2550
+ // window._log(`updateTimeline, a: ${action} ct: ${currentTime} d: ${duration} tds: ${this.timelineDisabledState}`, true);
2551
+ // console.trace(`updateTimeline ${action} slideIndex: ${this.slideIndex} currentTime:${currentTime} duration:${duration} tds: ${this.timelineDisabledState}`);
2552
+ SlideTimeline.layoutService.sdkApi.updateTimeline(this.slideIndex, action, currentTime, duration, showLoader, showError);
2553
+ }
2554
+ /**
2555
+ * Start timeline after slide started
2556
+ * Nothing do if old sdk
2557
+ */
2558
+ slideStarted() {
2559
+ // console.trace("slideStarted");
2560
+ if (this.isSDKSupportUpdateTimeline) {
2561
+ this.resumedAt = new Date().getTime();
2562
+ this.timeSpent = 0; // for case when instance exists, but we return to slide again
2563
+ this.updateTimeline("start" /* TIMELINE_ACTION.START */);
2564
+ }
2565
+ }
2566
+ slideRestarted() {
2567
+ // console.trace("slideRestarted");
2568
+ if (this.isSDKSupportUpdateTimeline) {
2569
+ this.resumedAt = new Date().getTime();
2570
+ this.timeSpent = 0;
2571
+ this.updateTimeline("start" /* TIMELINE_ACTION.START */);
2572
+ }
2573
+ }
2574
+ /**
2575
+ *
2576
+ */
2577
+ slidePaused(videoCurrentTime) {
2578
+ // console.trace("slidePaused");
2579
+ if (this.isSDKSupportUpdateTimeline) {
2580
+ if (videoCurrentTime != null) {
2581
+ this.timeSpent = Math.round(videoCurrentTime);
2582
+ }
2583
+ else {
2584
+ const globalCurrentTime = new Date().getTime();
2585
+ let spent = globalCurrentTime - this.resumedAt;
2586
+ this.timeSpent += spent;
2587
+ }
2588
+ this.updateTimeline("pause" /* TIMELINE_ACTION.PAUSE */);
2589
+ }
2590
+ else {
2591
+ this.layoutService.sdkApi.cardPausedCallback(videoCurrentTime);
2592
+ }
2593
+ }
2594
+ slideResumed(videoCurrentTime) {
2595
+ // console.trace("slideResumed");
2596
+ // @ts-ignore
2597
+ // window._log(`updateTimeline slideResumed ${videoCurrentTime}`, true);
2598
+ if (this.isSDKSupportUpdateTimeline) {
2599
+ if (videoCurrentTime != null) {
2600
+ this.timeSpent = Math.round(videoCurrentTime);
2601
+ }
2602
+ this.resumedAt = new Date().getTime();
2603
+ this.updateTimeline("start" /* TIMELINE_ACTION.START */);
2604
+ }
2605
+ else {
2606
+ this.layoutService.sdkApi.cardResumedCallback(videoCurrentTime);
2607
+ }
2608
+ }
2609
+ slideStopped() {
2610
+ // console.trace("slideStopped");
2611
+ if (this.isSDKSupportUpdateTimeline) {
2612
+ this.updateTimeline("stop" /* TIMELINE_ACTION.STOP */);
2613
+ }
2614
+ }
2615
+ /**
2616
+ * Update timer state (duration from 0 to actual value) and start timeline
2617
+ * used by widgets
2618
+ */
2619
+ startDisabledTimeline(fallback) {
2620
+ // if app is paused (in background) - don't call start timeline (Android issues)
2621
+ // @ts-ignore
2622
+ // window._log(`Push startDisabledTimeline to queue at state: ${window.slideApi.state}, time: ${new Date().getTime()}`, true);
2623
+ this._afterResumeQueuePush(() => {
2624
+ // @ts-ignore
2625
+ // window._log(`Call startDisabledTimeline at state: ${window.slideApi.state}, time: ${new Date().getTime()}`, true);
2626
+ if (this.isSDKSupportUpdateTimeline) {
2627
+ this.timelineDisabledState = TimelineDisabledState.enabled;
2628
+ this.timeSpent = 0;
2629
+ this.updateTimeline("start" /* TIMELINE_ACTION.START */);
2630
+ }
2631
+ else {
2632
+ // OLD SDK
2633
+ fallback();
2634
+ }
2635
+ });
2636
+ }
2637
+ onSlideDataWaiting(videoCurrentTime) {
2638
+ // console.trace("onSlideDataWaiting");
2639
+ // @ts-ignore
2640
+ // window._log(`updateTimeline onSlideDataWaiting ${videoCurrentTime}`, true);
2641
+ if (videoCurrentTime != null) {
2642
+ this.timeSpent = Math.round(videoCurrentTime);
2643
+ }
2644
+ else {
2645
+ const globalCurrentTime = new Date().getTime();
2646
+ let spent = globalCurrentTime - this.resumedAt;
2647
+ this.timeSpent += spent;
2648
+ }
2649
+ this.updateTimeline("pause" /* TIMELINE_ACTION.PAUSE */, true, false);
2650
+ }
2651
+ onSlideError(videoCurrentTime) {
2652
+ // console.trace("onSlideError");
2653
+ if (videoCurrentTime != null) {
2654
+ this.timeSpent = Math.round(videoCurrentTime);
2655
+ }
2656
+ else {
2657
+ const globalCurrentTime = new Date().getTime();
2658
+ let spent = globalCurrentTime - this.resumedAt;
2659
+ this.timeSpent += spent;
2660
+ }
2661
+ this.updateTimeline("stop" /* TIMELINE_ACTION.STOP */, false, true);
2662
+ }
2663
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`number`, `number`, `boolean`, `Promise`, `(cb: () => void) => void`]; }
2664
+ }
2665
+
2666
+ class Layer {
2667
+ _nodeRef;
2668
+ _slide;
2669
+ _slideReadyPromise;
2670
+ _afterResumeQueuePush;
2671
+ _slideIndex;
2672
+ _cardId;
2673
+ _cardType;
2674
+ _slideCount;
2675
+ _duration;
2676
+ _disabledTimer;
2677
+ _disabledNavigation;
2678
+ _elements = [];
2679
+ _timeline;
2680
+ constructor(_nodeRef, _slide, _slideReadyPromise, _afterResumeQueuePush) {
2681
+ this._nodeRef = _nodeRef;
2682
+ this._slide = _slide;
2683
+ this._slideReadyPromise = _slideReadyPromise;
2684
+ this._afterResumeQueuePush = _afterResumeQueuePush;
2685
+ this._slideIndex = parseInt(this._nodeRef.getAttribute("data-index") ?? "0");
2686
+ this._cardId = parseInt(this._nodeRef.getAttribute("data-id") ?? "0");
2687
+ this._cardType = parseInt(this._nodeRef.getAttribute("data-card-type") ?? "1") || 1 /* CARD_TYPE.STORY */;
2688
+ this._slideCount = parseInt(this._nodeRef.getAttribute("data-slide-count") ?? "0");
2689
+ this._duration = parseInt(this._nodeRef.getAttribute("data-duration") ?? "") || DEFAULT_SLIDE_DURATION;
2690
+ this._disabledTimer = this._nodeRef.getAttribute("data-disable-timer") === "1";
2691
+ this._disabledNavigation = this._nodeRef.getAttribute("data-disable-navigation") === "1";
2692
+ this._timeline = new SlideTimeline(this._slideIndex, this._duration, this._disabledTimer, this._slideReadyPromise, this._afterResumeQueuePush);
2693
+ const _elementsNodes = this._nodeRef.querySelectorAll(".narrative-slide-elements .narrative-element");
2694
+ let layerWithWidgetQuest = false;
2695
+ _elementsNodes.forEach(item => {
2696
+ let element = tryCreateFromHtmlElement(item, this);
2697
+ if (element) {
2698
+ this._elements.push(element);
2699
+ if (element instanceof Quest) {
2700
+ layerWithWidgetQuest = true;
2701
+ }
2702
+ }
2703
+ });
2704
+ // console.log({ _elementsNodes }, this._elements);
2705
+ /**
2706
+ * Special behaviour for widget Quest
2707
+ * if current slide/layer without WidgetQuest element explicit but story has type Quest
2708
+ * - then init WidgetQuest with layer instead of WidgetQuest element (required for WidgetQuest slides navigation)
2709
+ */
2710
+ if (this.isQuest && !layerWithWidgetQuest && this.layoutService.layoutApi.widgetQuestApi != null) {
2711
+ this._elements.push(new Quest(this._nodeRef, this, this.layoutService.layoutApi.widgetQuestApi));
2712
+ }
2713
+ }
2714
+ init(localData) {
2715
+ if (this.sdkApi.isIOS || this.sdkApi.isAndroid) {
2716
+ this._nodeRef.classList.add("_app");
2717
+ this.sdkApi.isIOS && this._nodeRef.classList.add("_isIos");
2718
+ this.sdkApi.isAndroid && this._nodeRef.classList.add("_isAndroid");
2719
+ }
2720
+ const promises = this._elements.map(element => element.init(localData));
2721
+ this._initTextElementAutoWidthCorrection();
2722
+ this._initTextFit();
2723
+ return promises;
2724
+ }
2725
+ get nodeRef() {
2726
+ return this._nodeRef;
2727
+ }
2728
+ get elements() {
2729
+ return this._elements;
2730
+ }
2731
+ get slide() {
2732
+ return this._slide;
2733
+ }
2734
+ get timeline() {
2735
+ return this._timeline;
2736
+ }
2737
+ get layoutService() {
2738
+ return container.get({ identifier: "LayoutService" });
2739
+ }
2740
+ get sdkApi() {
2741
+ return container.get({ identifier: "SDKApi" });
2742
+ }
2743
+ getLocalData() {
2744
+ return this.layoutService.sdkApi.getCardLocalData();
2745
+ }
2746
+ get isQuest() {
2747
+ return this._nodeRef.getAttribute("data-quest-count") != null;
2748
+ }
2749
+ _initTextFit() {
2750
+ const textLines = Array.prototype.slice.call(this._nodeRef.querySelectorAll(".narrative-element-text-wrapper>.narrative-element-text-lines"));
2751
+ TextFit(textLines, {});
2752
+ }
2753
+ _initTextElementAutoWidthCorrection() {
2754
+ const textLines = this._nodeRef.querySelectorAll(".narrative-element-text-wrapper>.narrative-element-text-lines");
2755
+ for (const item of textLines) {
2756
+ if (item.parentElement) {
2757
+ new TextElementAutoWidthCorrection(item.parentElement);
2758
+ }
2759
+ }
2760
+ }
2761
+ get slideIndex() {
2762
+ return this._slideIndex;
2763
+ }
2764
+ get cardId() {
2765
+ return this._cardId;
2766
+ }
2767
+ get cardType() {
2768
+ return this._cardType;
2769
+ }
2770
+ get slideCount() {
2771
+ return this._slideCount;
2772
+ }
2773
+ get disabledNavigation() {
2774
+ return this._disabledNavigation;
2775
+ }
2776
+ get videoElement() {
2777
+ for (const element of this._elements) {
2778
+ if (Video.isTypeOf(element)) {
2779
+ return element;
2780
+ }
2781
+ }
2782
+ return null;
2783
+ }
2784
+ get rangeSliderElement() {
2785
+ for (const element of this._elements) {
2786
+ if (RangeSlider.isTypeOf(element)) {
2787
+ return element;
2788
+ }
2789
+ }
2790
+ return null;
2791
+ }
2792
+ get quizElement() {
2793
+ for (const element of this._elements) {
2794
+ if (Quiz.isTypeOf(element)) {
2795
+ return element;
2796
+ }
2797
+ }
2798
+ return null;
2799
+ }
2800
+ get quizGroupedElement() {
2801
+ for (const element of this._elements) {
2802
+ if (QuizGrouped.isTypeOf(element)) {
2803
+ return element;
2804
+ }
2805
+ }
2806
+ return null;
2807
+ }
2808
+ get questElement() {
2809
+ for (const element of this._elements) {
2810
+ if (Quest.isTypeOf(element)) {
2811
+ return element;
2812
+ }
2813
+ }
2814
+ return null;
2815
+ }
2816
+ get testElement() {
2817
+ for (const element of this._elements) {
2818
+ if (Test.isTypeOf(element)) {
2819
+ return element;
2820
+ }
2821
+ }
2822
+ return null;
2823
+ }
2824
+ get dataInputElement() {
2825
+ for (const element of this._elements) {
2826
+ if (DataInput.isTypeOf(element)) {
2827
+ return element;
2828
+ }
2829
+ }
2830
+ return null;
2831
+ }
2832
+ get pollElement() {
2833
+ for (const element of this._elements) {
2834
+ if (Poll.isTypeOf(element)) {
2835
+ return element;
2836
+ }
2837
+ }
2838
+ return null;
2839
+ }
2840
+ get pollLayersElement() {
2841
+ for (const element of this._elements) {
2842
+ if (PollLayers.isTypeOf(element)) {
2843
+ return element;
2844
+ }
2845
+ }
2846
+ return null;
2847
+ }
2848
+ get rateElement() {
2849
+ for (const element of this._elements) {
2850
+ if (Rate.isTypeOf(element)) {
2851
+ return element;
2852
+ }
2853
+ }
2854
+ return null;
2855
+ }
2856
+ get shareElement() {
2857
+ for (const element of this._elements) {
2858
+ if (Share.isTypeOf(element)) {
2859
+ return element;
2860
+ }
2861
+ }
2862
+ return null;
2863
+ }
2864
+ get swipeUpElement() {
2865
+ for (const element of this._elements) {
2866
+ if (SwipeUp.isTypeOf(element)) {
2867
+ return element;
2868
+ }
2869
+ }
2870
+ return null;
2871
+ }
2872
+ get swipeUpItemsElement() {
2873
+ for (const element of this._elements) {
2874
+ if (SwipeUpItems.isTypeOf(element)) {
2875
+ return element;
2876
+ }
2877
+ }
2878
+ return null;
2879
+ }
2880
+ get productsElement() {
2881
+ for (const element of this._elements) {
2882
+ if (Products.isTypeOf(element)) {
2883
+ return element;
2884
+ }
2885
+ }
2886
+ return null;
2887
+ }
2888
+ isClickCapturedBySlider() {
2889
+ return (this.rangeSliderElement?.isClickCapturedBySlider ?? false) || (this.productsElement?.isClickCapturedByWidget ?? false);
2890
+ }
2891
+ _animationPauseCb;
2892
+ _animationResumeCb;
2893
+ async start(muted = true) {
2894
+ const videoElement = this.videoElement;
2895
+ let currentTime = 0;
2896
+ if (videoElement != null) {
2897
+ currentTime = (await videoElement.start(muted)).currentTime;
2898
+ }
2899
+ if (this.sdkApi.cardAnimation) {
2900
+ this._animationPauseCb = this.sdkApi.cardAnimation.start(this._nodeRef);
2901
+ }
2902
+ for (const element of this._elements) {
2903
+ element.onStart();
2904
+ }
2905
+ for (const element of this._elements) {
2906
+ element.onResume();
2907
+ }
2908
+ // skip start timeline if we returned to slide with enabled timer and opened WidgetProducts modal
2909
+ if (!this.isLayerForcePaused) {
2910
+ this.timeline.slideStarted();
2911
+ }
2912
+ return { currentTime };
2913
+ }
2914
+ async stop() {
2915
+ this.videoElement?.stop();
2916
+ this.sdkApi.cardAnimation?.stop(this._nodeRef);
2917
+ for (const element of this._elements) {
2918
+ element.onPause();
2919
+ }
2920
+ for (const element of this._elements) {
2921
+ element.onStop();
2922
+ }
2923
+ this._timeline.slideStopped();
2924
+ }
2925
+ stopInternal() {
2926
+ this.videoElement?.stop();
2927
+ this.sdkApi.cardAnimation?.stop(this._nodeRef);
2928
+ for (const element of this._elements) {
2929
+ element.onPause();
2930
+ }
2931
+ for (const element of this._elements) {
2932
+ element.onStop();
2933
+ }
2934
+ }
2935
+ async pause(resetVideoTime = false, stopAnimation = false) {
2936
+ return new Promise(resolve => {
2937
+ const cb = () => {
2938
+ let currentTime = this.videoElement?.pause(resetVideoTime) ?? null;
2939
+ if (stopAnimation) {
2940
+ this.sdkApi.cardAnimation?.stop(this._nodeRef);
2941
+ }
2942
+ else {
2943
+ if (this._animationPauseCb != null && isFunction(this._animationPauseCb)) {
2944
+ this._animationResumeCb = this._animationPauseCb(false);
2945
+ }
2946
+ }
2947
+ if (currentTime != null) {
2948
+ currentTime *= 1000;
2949
+ }
2950
+ for (const element of this._elements) {
2951
+ element.onPause();
2952
+ }
2953
+ this.timeline.slidePaused(currentTime);
2954
+ resolve({ currentTime });
2955
+ };
2956
+ const videoStartedPromise = this.videoElement?.videoStartedPromise;
2957
+ if (videoStartedPromise != null && videoStartedPromise.then != null) {
2958
+ videoStartedPromise.then(cb);
2959
+ }
2960
+ else {
2961
+ cb();
2962
+ }
2963
+ });
2964
+ }
2965
+ async resume() {
2966
+ return new Promise(resolve => {
2967
+ const cb = ({ currentTime }) => {
2968
+ // console.log("resumed cb with currentTime", { currentTime });
2969
+ if (currentTime != null) {
2970
+ currentTime *= 1000;
2971
+ }
2972
+ if (isFunction(this._animationResumeCb)) {
2973
+ this._animationResumeCb();
2974
+ }
2975
+ for (const element of this._elements) {
2976
+ element.onResume();
2977
+ }
2978
+ this.timeline.slideResumed(currentTime);
2979
+ resolve({ currentTime });
2980
+ };
2981
+ const videoStartedPromise = this.videoElement?.resume();
2982
+ if (videoStartedPromise != null && videoStartedPromise.then != null) {
2983
+ videoStartedPromise.then(cb);
2984
+ }
2985
+ else {
2986
+ cb({ currentTime: null });
2987
+ }
2988
+ });
2989
+ }
2990
+ enableAudio() {
2991
+ this.videoElement?.enableAudio();
2992
+ }
2993
+ disableAudio() {
2994
+ this.videoElement?.disableAudio();
2995
+ }
2996
+ get isLayerForcePaused() {
2997
+ return this.elements.some(element => element.isLayerForcePaused);
2998
+ }
2999
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Slide`, `Promise`, `(cb: () => void) => void`]; }
3000
+ }
3001
+ const TextFit = (function () {
3002
+ const defaultSettings = {
3003
+ step: 1,
3004
+ maxSteps: 100,
3005
+ };
3006
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
3007
+ return function textFit(els, options) {
3008
+ if (!options)
3009
+ options = {};
3010
+ // Extend options.
3011
+ let settings = {};
3012
+ for (let key in defaultSettings) {
3013
+ if (hasOwnProperty.call(options, key)) {
3014
+ // @ts-ignore
3015
+ settings[key] = options[key];
3016
+ }
3017
+ else {
3018
+ // @ts-ignore
3019
+ settings[key] = defaultSettings[key];
3020
+ }
3021
+ }
3022
+ // Support passing a single el
3023
+ let elType = Object.prototype.toString.call(els);
3024
+ if (elType !== "[object Array]" && elType !== "[object NodeList]" && elType !== "[object HTMLCollection]") {
3025
+ // @ts-ignore
3026
+ els = [els];
3027
+ }
3028
+ // Process each el we've passed.
3029
+ for (let i = 0; i < els.length; i++) {
3030
+ processItem(els[i], settings);
3031
+ }
3032
+ };
3033
+ function processItem(el, settings) {
3034
+ if (!isElement(el) || el.getAttribute("textFitted")) {
3035
+ return false;
3036
+ }
3037
+ let parentHeight, parent;
3038
+ let low, high;
3039
+ parent = el.parentElement;
3040
+ if (!isElement(parent)) {
3041
+ return false;
3042
+ }
3043
+ // Get element data.
3044
+ parentHeight = innerHeight(parent);
3045
+ // Don't process if we can't find box dimensions
3046
+ if (parentHeight <= 0) {
3047
+ console.warn(`Set a static height and width on the target element ${el.outerHTML} before using textFit!`, el);
3048
+ return;
3049
+ }
3050
+ // Set textFitted attribute so we know this was processed.
3051
+ el.setAttribute("textFitted", "1");
3052
+ let step = settings.step;
3053
+ high = parseFloat(window.getComputedStyle(el).fontSize);
3054
+ low = high - step * settings.maxSteps;
3055
+ let size = high;
3056
+ if (size < low)
3057
+ return;
3058
+ while (size >= low) {
3059
+ let elBoundingClientRect = el.getBoundingClientRect();
3060
+ if (elBoundingClientRect.height > parentHeight) {
3061
+ size -= step;
3062
+ el.style.fontSize = size + "px";
3063
+ }
3064
+ else {
3065
+ break;
3066
+ }
3067
+ }
3068
+ }
3069
+ // Calculate height without padding.
3070
+ // @ts-ignore
3071
+ function innerHeight(el) {
3072
+ let style = window.getComputedStyle(el, null);
3073
+ return el.getBoundingClientRect().height - parseInt(style.getPropertyValue("padding-top"), 10) - parseInt(style.getPropertyValue("padding-bottom"), 10);
3074
+ }
3075
+ //Returns true if it is a DOM element
3076
+ // @ts-ignore
3077
+ function isElement(o) {
3078
+ return typeof HTMLElement === "object"
3079
+ ? o instanceof HTMLElement //DOM2
3080
+ : o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string";
3081
+ }
3082
+ })();
3083
+ class TextElementAutoWidthCorrection {
3084
+ textWrapperRef;
3085
+ // wrapper (flex row)
3086
+ // lead | text | tail //
3087
+ // wrapper (flex row)
3088
+ // text - can be multiline, use overflow-wrap: anywhere - for overflow prevent
3089
+ // iOS 17.5 break text on second line despite on enough space
3090
+ // fix it - detect and set min-width + max-width for text element
3091
+ leadWidth = null;
3092
+ tailWidth = null;
3093
+ columnGap = null;
3094
+ wrapperInnerWidth = null;
3095
+ //Returns true if it is a DOM element
3096
+ // @ts-ignore
3097
+ isElement(o) {
3098
+ return typeof HTMLElement === "object"
3099
+ ? o instanceof HTMLElement //DOM2
3100
+ : o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string";
3101
+ }
3102
+ computeWrapperSize() {
3103
+ const { columnGap, width, paddingLeft, paddingRight } = window.getComputedStyle(this.textWrapperRef, null);
3104
+ this.columnGap = parseFloat(columnGap);
3105
+ this.wrapperInnerWidth = parseFloat(width) - parseFloat(paddingLeft) - parseFloat(paddingRight);
3106
+ }
3107
+ measureTextWidth(text, { fontSize, fontWeight, fontStyle, fontFamily, }) {
3108
+ let textRef = document.createElement("div");
3109
+ textRef.style.setProperty("font-size", fontSize);
3110
+ textRef.style.setProperty("font-weight", fontWeight);
3111
+ textRef.style.setProperty("font-style", fontStyle);
3112
+ textRef.style.setProperty("font-family", fontFamily);
3113
+ textRef.style.setProperty("position", "absolute");
3114
+ textRef.style.setProperty("left", "-1000px");
3115
+ textRef.style.setProperty("top", "-1000px");
3116
+ textRef.style.setProperty("white-space", "nowrap");
3117
+ // textRef.style.setProperty("visibility", "hidden");
3118
+ textRef.textContent = text;
3119
+ document.body.appendChild(textRef);
3120
+ const textWidth = parseFloat(window.getComputedStyle(textRef, null).width);
3121
+ document.body.removeChild(textRef);
3122
+ // @ts-ignore
3123
+ textRef = null;
3124
+ return textWidth;
3125
+ }
3126
+ constructor(textWrapperRef) {
3127
+ this.textWrapperRef = textWrapperRef;
3128
+ const leadRef = textWrapperRef.querySelector(".narrative-element-text-lines-lead");
3129
+ const tailRef = textWrapperRef.querySelector(".narrative-element-text-lines-tail");
3130
+ const textRef = textWrapperRef.querySelector(".narrative-element-text-lines");
3131
+ if (leadRef && tailRef && textRef) {
3132
+ if (!this.isElement(textRef) || textRef.getAttribute("textWidthCorrected")) {
3133
+ return;
3134
+ }
3135
+ // Set textFitted attribute so we know this was processed.
3136
+ textRef.setAttribute("textWidthCorrected", "1");
3137
+ this.computeWrapperSize();
3138
+ this.leadWidth = leadRef.clientWidth;
3139
+ this.tailWidth = tailRef.clientWidth;
3140
+ const textMaxWidth = this.wrapperInnerWidth -
3141
+ this.leadWidth -
3142
+ this.columnGap * (this.leadWidth ? 1 : 0) -
3143
+ this.tailWidth -
3144
+ this.columnGap * (this.tailWidth ? 1 : 0);
3145
+ const { fontSize, fontFamily, fontWeight, fontStyle } = window.getComputedStyle(textRef, null);
3146
+ const textMinWidth = Math.min(this.measureTextWidth(textRef.textContent ?? "", {
3147
+ fontSize,
3148
+ fontFamily,
3149
+ fontWeight,
3150
+ fontStyle,
3151
+ }), textMaxWidth);
3152
+ // setTimeout(() => {
3153
+ // console.log({
3154
+ // textMaxWidth,
3155
+ // textMinWidth,
3156
+ // columnGap: this.columnGap,
3157
+ // leadWidth: this.leadWidth,
3158
+ // tailWidth: this.tailWidth,
3159
+ // wrapperInnerWidth: this.wrapperInnerWidth,
3160
+ // });
3161
+ // }, 10 * 1000);
3162
+ textRef.style.setProperty("min-width", `${textMinWidth}px`);
3163
+ textRef.style.setProperty("max-width", `${textMaxWidth}px`);
3164
+ }
3165
+ }
3166
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`]; }
3167
+ }
3168
+
3169
+ class Slide {
3170
+ _slidesNodesRefs;
3171
+ _slideReadyPromise;
3172
+ _afterResumeQueuePush;
3173
+ _layers;
3174
+ _start;
3175
+ constructor(_slidesNodesRefs, _slideReadyPromise, _afterResumeQueuePush) {
3176
+ this._slidesNodesRefs = _slidesNodesRefs;
3177
+ this._slideReadyPromise = _slideReadyPromise;
3178
+ this._afterResumeQueuePush = _afterResumeQueuePush;
3179
+ this._start = window.performance.now();
3180
+ if (!this._slidesNodesRefs.length) {
3181
+ throw new Error("No slides found.");
3182
+ }
3183
+ this._layers = this._slidesNodesRefs.map(item => new Layer(item, this, this._slideReadyPromise, this._afterResumeQueuePush));
3184
+ this._activeLayer = this._layers[0];
3185
+ }
3186
+ _activeLayer;
3187
+ get activeLayer() {
3188
+ return this._activeLayer;
3189
+ }
3190
+ get layers() {
3191
+ return this._layers;
3192
+ }
3193
+ get layersNodesRefs() {
3194
+ return this._slidesNodesRefs;
3195
+ // call from Slide CTOR -> exception, bcz this._layers is empty
3196
+ // return this._layers.map(layer => layer.nodeRef);
3197
+ }
3198
+ _initMultiSlide(localData) {
3199
+ const multiSlideApi = this.layoutService.layoutApi.widgetMultiSlideApi;
3200
+ if (multiSlideApi != null && this.layers.length > 1) {
3201
+ try {
3202
+ multiSlideApi.init(this.layersNodesRefs, localData);
3203
+ }
3204
+ catch (e) {
3205
+ console.error(e);
3206
+ }
3207
+ }
3208
+ }
3209
+ async init(localData) {
3210
+ this._initMultiSlide(localData);
3211
+ const promises = this.layers.flatMap(layer => layer.init(localData));
3212
+ const res = await Promise.all(promises);
3213
+ // rescan current slide
3214
+ this.refreshActiveLayer();
3215
+ // if not all true - return false
3216
+ // if not all Widgets return finishRender: true - return false
3217
+ return !res.some(item => item === false);
3218
+ }
3219
+ refreshActiveLayer() {
3220
+ this.layers.forEach(layer => {
3221
+ if (!layer.nodeRef.classList.contains("hidden")) {
3222
+ this._activeLayer = layer;
3223
+ }
3224
+ });
3225
+ }
3226
+ showLayer(showIndex, muted) {
3227
+ // todo allow to call only if Layer in state LAYER_STATE::STARTED
3228
+ // hotfix (VOD and showLayer issue) - just skip showLayer for already visible layer
3229
+ // if (this.layers[showIndex] != null && this.layers[showIndex].nodeRef != null && !this.layers[showIndex].nodeRef.classList.contains("hidden")) {
3230
+ // console.log("hotfix (VOD and showLayer issue) - just skip showLayer for already visible layer");
3231
+ // return;
3232
+ // }
3233
+ // console.log(`showLayer: ${showIndex}`);
3234
+ // first - stop (for correct timeline calls)
3235
+ this.layers.forEach((layer, index) => {
3236
+ // const isHidden = layer.nodeRef.classList.contains("hidden");
3237
+ if (index !== showIndex) {
3238
+ layer.nodeRef.classList.add("hidden");
3239
+ layer.stop();
3240
+ }
3241
+ });
3242
+ this.layers.forEach((layer, index) => {
3243
+ // const isHidden = layer.nodeRef.classList.contains("hidden");
3244
+ if (index === showIndex) {
3245
+ this._activeLayer = layer;
3246
+ layer.nodeRef.classList.remove("hidden");
3247
+ layer.start(muted);
3248
+ }
3249
+ });
3250
+ }
3251
+ get layoutService() {
3252
+ return container.get({ identifier: "LayoutService" });
3253
+ }
3254
+ get slideIndex() {
3255
+ return this._activeLayer.slideIndex;
3256
+ }
3257
+ get cardId() {
3258
+ return this._activeLayer.cardId;
3259
+ }
3260
+ get cardType() {
3261
+ return this._activeLayer.cardType;
3262
+ }
3263
+ get slideCount() {
3264
+ return this._activeLayer.slideCount;
3265
+ }
3266
+ get disabledNavigation() {
3267
+ return this._activeLayer.disabledNavigation;
3268
+ }
3269
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`Array`, `Promise`, `(cb: () => void) => void`]; }
3270
+ }
3271
+
3272
+ function getViewportWidth(viewport) {
3273
+ return viewport.innerWidth || viewport.document.documentElement.clientWidth || viewport.document.body.clientWidth;
3274
+ }
3275
+ function getViewportHeight(viewport) {
3276
+ return viewport.innerHeight || viewport.document.documentElement.clientHeight || viewport.document.body.clientHeight;
3277
+ }
3278
+ let SlideApi$1 = class SlideApi {
3279
+ config;
3280
+ get layoutDirection() {
3281
+ // warning, detection in ctor not working, bcz sdk changes layout later
3282
+ return this.layoutService.env.getComputedStyle(this._slideWrapper).direction === "rtl" ? "rtl" : "ltr";
3283
+ }
3284
+ static renderedBoxClassName = "narrative-slide-box-rendered";
3285
+ static prerenderBoxClassName = "narrative-slide-box-prerender";
3286
+ _slideWrapper;
3287
+ _viewport;
3288
+ constructor(config) {
3289
+ this.config = config;
3290
+ this._slideWrapper = config.slideWrapper;
3291
+ this._viewport = config.viewport;
3292
+ this.refreshSizes = proxy(this.refreshSizes, this);
3293
+ this.initListeners();
3294
+ this.refreshSizes();
3295
+ const slideBox = document.getElementById("narrative-slide-box");
3296
+ // todo via first child and its innerText - faster variant
3297
+ if (slideBox && slideBox.innerText.trim() !== "{%content}".replace("{", "{{").replace("}", "}}")) {
3298
+ this._slideInInit = null;
3299
+ this._slideInRender = true;
3300
+ this._init(() => this._slideBoxRenderComplete(), () => this._slideBoxRenderError()).then(({ slide, result, reason }) => {
3301
+ this._slide = slide;
3302
+ if (config.slideLoadedCb != null) {
3303
+ config.slideLoadedCb({ slide, result, reason });
3304
+ }
3305
+ });
3306
+ }
3307
+ }
3308
+ destroy() {
3309
+ this.destroyListeners();
3310
+ }
3311
+ initListeners() {
3312
+ this._viewport.addEventListener("resize", this.refreshSizes);
3313
+ }
3314
+ destroyListeners() {
3315
+ this._viewport.removeEventListener("resize", this.refreshSizes);
3316
+ }
3317
+ refreshSizes() {
3318
+ const viewportWidth = getViewportWidth(this._viewport);
3319
+ const viewportHeight = getViewportHeight(this._viewport);
3320
+ const viewportRatio = viewportWidth / viewportHeight;
3321
+ let slideWidth = 0;
3322
+ let slideHeight = 0;
3323
+ // _ratio = 310 / 480,
3324
+ const _ratio = this.config.slideRatio;
3325
+ let _isFullscreen = this.config.isFullscreen;
3326
+ const slideOffset = this._slideWrapper.querySelector(".narrative-slide-offset");
3327
+ let offset = 0;
3328
+ let xOffset = "0px";
3329
+ // for elements with bottom anchor (absolute position)
3330
+ let yOffset = "0px";
3331
+ // alert(viewportHeight);
3332
+ if (viewportRatio > _ratio) {
3333
+ // disable _isFullscreen if viewport small
3334
+ _isFullscreen = false;
3335
+ }
3336
+ if (_isFullscreen) {
3337
+ // fit by width, top and bottom - to offscreen or fill with bg image
3338
+ slideWidth = viewportWidth;
3339
+ slideHeight = Math.ceil(viewportWidth / _ratio);
3340
+ offset = Math.ceil(slideHeight - viewportHeight) / 2;
3341
+ if (slideOffset != null) {
3342
+ slideOffset.style.margin = -1 * offset + "px" + " 0 ";
3343
+ }
3344
+ // offset from viewport bottom to StoryBottom plus safe area offset bottom
3345
+ yOffset = `calc(${offset}px + env(safe-area-inset-bottom))`;
3346
+ // detect safe area offset
3347
+ }
3348
+ else {
3349
+ // более квадратное чем надо
3350
+ if (viewportRatio > _ratio) {
3351
+ // fit by width, top and bottom - to offscreen
3352
+ slideWidth = viewportWidth;
3353
+ slideHeight = Math.ceil(viewportWidth / _ratio);
3354
+ offset = Math.ceil(slideHeight - viewportHeight) / 2;
3355
+ if (slideOffset != null) {
3356
+ slideOffset.style.margin = -offset + "px" + " 0 ";
3357
+ }
3358
+ yOffset = offset + "px";
3359
+ }
3360
+ else {
3361
+ // вьюпорт более вытянутый чем надо
3362
+ // fit by height, sides - to offscreen
3363
+ slideHeight = viewportHeight;
3364
+ slideWidth = Math.ceil(slideHeight * _ratio);
3365
+ offset = Math.ceil(slideWidth - viewportWidth) / 2;
3366
+ if (slideOffset != null) {
3367
+ slideOffset.style.margin = "0 " + -offset + "px"; // -8.5
3368
+ }
3369
+ xOffset = offset + "px";
3370
+ }
3371
+ }
3372
+ const fontSize = slideWidth / 20;
3373
+ // todo CSP violation
3374
+ this._slideWrapper.style.fontSize = fontSize + "px";
3375
+ if (slideOffset != null) {
3376
+ // todo CSP violation
3377
+ slideOffset.style.setProperty("--y-offset", yOffset);
3378
+ slideOffset.style.setProperty("--x-offset", xOffset);
3379
+ }
3380
+ if (_isFullscreen) {
3381
+ slideOffset?.classList.add("narrative-slide-offset-fullscreen");
3382
+ }
3383
+ if (this.config.userResizeHandler != null) {
3384
+ this.config.userResizeHandler({ viewportWidth, viewportHeight, fontSize });
3385
+ }
3386
+ }
3387
+ async showSlide(html) {
3388
+ const slideBox = this._slideWrapper.querySelector(`.${SlideApi.renderedBoxClassName}`);
3389
+ const slideBoxPrerender = this._slideWrapper.querySelector(`.${SlideApi.prerenderBoxClassName}`);
3390
+ const _result = { slide: this.slide, result: false, reason: "" };
3391
+ if (slideBox && slideBoxPrerender) {
3392
+ if (this._slideInRender) {
3393
+ this._slideInRender = false;
3394
+ this._slideBoxRenderComplete();
3395
+ }
3396
+ this._slideInInit = null;
3397
+ this._slideInRender = true;
3398
+ slideBoxPrerender.innerHTML = html;
3399
+ const { slide, result, reason } = await this._init(() => this._slideBoxRenderComplete(), () => this._slideBoxRenderError());
3400
+ this._slide = slide;
3401
+ _result.result = result;
3402
+ _result.reason = reason;
3403
+ }
3404
+ _result.slide = this.slide;
3405
+ return _result;
3406
+ }
3407
+ handleBackpress() {
3408
+ this.activeLayer.productsElement?.handleBackpress();
3409
+ }
3410
+ get layoutService() {
3411
+ return container.get({ identifier: "LayoutService" });
3412
+ }
3413
+ getLocalData() {
3414
+ return this.layoutService.sdkApi.getCardLocalData();
3415
+ }
3416
+ get sdkApi() {
3417
+ return container.get({ identifier: "SDKApi" });
3418
+ }
3419
+ _fontsInit = false;
3420
+ _initAndLoadFonts(fonts) {
3421
+ if (this._fontsInit) {
3422
+ return Promise.resolve();
3423
+ }
3424
+ return new Promise(resolve => {
3425
+ if ("fonts" in document) {
3426
+ // https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API
3427
+ const promises = [];
3428
+ try {
3429
+ if (fonts != null && Array.isArray(fonts)) {
3430
+ for (let i = 0; i < fonts.length; i++) {
3431
+ const src = fonts[i];
3432
+ if (src && src.family && src.style && src.weight && src.url) {
3433
+ // var font = new FontFace(fonts[i].family, "url(" + src.url + "&s=css_font_face)", {
3434
+ const font = new FontFace(fonts[i].family, "url(" + src.url + ")", {
3435
+ style: src.style,
3436
+ weight: src.weight,
3437
+ // display: "block"
3438
+ });
3439
+ document.fonts.add && document.fonts.add(font);
3440
+ promises.push(font.load());
3441
+ }
3442
+ }
3443
+ }
3444
+ this._fontsInit = true;
3445
+ Promise.all(promises)
3446
+ .then(_ => {
3447
+ resolve();
3448
+ })
3449
+ .catch(reason => {
3450
+ console.error(reason);
3451
+ resolve();
3452
+ });
3453
+ }
3454
+ catch (e) {
3455
+ console.error(e);
3456
+ resolve();
3457
+ }
3458
+ }
3459
+ });
3460
+ }
3461
+ _slide;
3462
+ _slideInInit;
3463
+ _state;
3464
+ _afterStartInitQueue = [];
3465
+ _afterResumeQueue = [];
3466
+ get state() {
3467
+ return this._state;
3468
+ }
3469
+ async _onAllMediaLoaded(slide) {
3470
+ return new Promise((resolve, reject) => {
3471
+ const promises = slide.layers.flatMap(layer => layer.elements.flatMap(element => element.mediaElementsLoadingPromises));
3472
+ let checkerTimerId = undefined;
3473
+ let timeOutFired = false;
3474
+ if (promises.length > 0) {
3475
+ checkerTimerId = this.layoutService.env.setTimeout(() => {
3476
+ timeOutFired = true;
3477
+ reject("onAllMediaLoaded timeout");
3478
+ }, 3000);
3479
+ }
3480
+ else {
3481
+ resolve();
3482
+ return;
3483
+ }
3484
+ Promise.all(promises).then(_ => {
3485
+ checkerTimerId && this.layoutService.env.clearTimeout(checkerTimerId);
3486
+ if (!timeOutFired) {
3487
+ resolve();
3488
+ }
3489
+ }, reason => {
3490
+ checkerTimerId && this.layoutService.env.clearTimeout(checkerTimerId);
3491
+ if (!timeOutFired) {
3492
+ reject(reason);
3493
+ }
3494
+ });
3495
+ });
3496
+ }
3497
+ async _init(slideBoxCb, slideBoxFailedCb) {
3498
+ this._state = 0 /* STATE.INIT */;
3499
+ const slideNodeRef = this._slideWrapper.querySelector(`.${SlideApi.prerenderBoxClassName} .narrative-slide`);
3500
+ const slidesNodesRefs = Array.prototype.slice.call(this._slideWrapper.querySelectorAll(`.${SlideApi.prerenderBoxClassName} .narrative-slide.narrative-multi-slide`));
3501
+ if (!slidesNodesRefs.length && slideNodeRef != null) {
3502
+ slidesNodesRefs.push(slideNodeRef);
3503
+ }
3504
+ if (!slidesNodesRefs.length) {
3505
+ throw new Error("No slides found.");
3506
+ }
3507
+ let slideReadyResolve = null;
3508
+ let slideReadyReject = null;
3509
+ const slideReadyPromise = new Promise((resolve, reject) => {
3510
+ slideReadyResolve = resolve;
3511
+ slideReadyReject = reject;
3512
+ });
3513
+ const slide = new Slide(slidesNodesRefs, slideReadyPromise, this.afterResumeQueuePush.bind(this));
3514
+ this._slideInInit = slide;
3515
+ const onAllMediaLoaded = this._onAllMediaLoaded(slide);
3516
+ if (this.sdkApi.isAndroid) {
3517
+ this._afterStartInitQueue = [];
3518
+ }
3519
+ this._afterResumeQueue = [];
3520
+ const result = { slide, result: false, reason: "" };
3521
+ await this._initAndLoadFonts(this.layoutService.sdkApi.getCardFonts());
3522
+ const localData = await this.getLocalData();
3523
+ const finishRender = await slide.init(localData);
3524
+ /**
3525
+ * если есть виджеты, которых надо ждать - то не завершаем рендеринг текущего слайда
3526
+ * пример - квест, если зашли в сторис а виджету нужно показать другой слайд вместо первого
3527
+ */
3528
+ if (finishRender) {
3529
+ this._state = 1 /* STATE.INITED */;
3530
+ try {
3531
+ await onAllMediaLoaded;
3532
+ result.result = true;
3533
+ slideBoxCb();
3534
+ this.layoutService.env.setTimeout(() => {
3535
+ slideReadyResolve();
3536
+ });
3537
+ }
3538
+ catch (reason) {
3539
+ console.log("SlideInit, onAllMediaLoaded reject", reason);
3540
+ slideBoxFailedCb();
3541
+ this.layoutService.env.setTimeout(() => {
3542
+ slideReadyReject();
3543
+ });
3544
+ result.result = false;
3545
+ result.reason = String(reason);
3546
+ }
3547
+ }
3548
+ else {
3549
+ this._state = 10 /* STATE.STOPPED */;
3550
+ this.layoutService.env.setTimeout(() => {
3551
+ slideReadyResolve();
3552
+ });
3553
+ result.result = true;
3554
+ }
3555
+ return result;
3556
+ }
3557
+ _slideInRender = false;
3558
+ _slideBoxRenderComplete() {
3559
+ if (!this._slideInRender) {
3560
+ this._slideInRender = true;
3561
+ return;
3562
+ }
3563
+ const slideBox = this._slideWrapper.querySelector(`.${SlideApi.renderedBoxClassName}`);
3564
+ const slideBoxPrerender = this._slideWrapper.querySelector(`.${SlideApi.prerenderBoxClassName}`);
3565
+ if (slideBox && slideBoxPrerender) {
3566
+ slideBoxPrerender.classList.remove(SlideApi.prerenderBoxClassName);
3567
+ slideBox.classList.remove(SlideApi.renderedBoxClassName);
3568
+ slideBox.classList.add(SlideApi.prerenderBoxClassName);
3569
+ slideBox.innerHTML = "";
3570
+ slideBoxPrerender.classList.add(SlideApi.renderedBoxClassName);
3571
+ }
3572
+ this._slideInRender = false;
3573
+ }
3574
+ _slideBoxRenderError() {
3575
+ // if (!slideInRender) {
3576
+ // slideInRender = true;
3577
+ // return;
3578
+ // }
3579
+ const slideBox = this._slideWrapper.querySelector(`.${SlideApi.renderedBoxClassName}`);
3580
+ const slideBoxPrerender = this._slideWrapper.querySelector(`.${SlideApi.prerenderBoxClassName}`);
3581
+ if (slideBox && slideBoxPrerender) {
3582
+ const slides = Array.prototype.slice.call(slideBoxPrerender.querySelectorAll(".narrative-slide"));
3583
+ for (let i = 0; i < slides.length; ++i) {
3584
+ const slide = slides[i];
3585
+ if (slide) {
3586
+ slide.innerHTML = "";
3587
+ }
3588
+ }
3589
+ slideBoxPrerender.classList.remove(SlideApi.prerenderBoxClassName);
3590
+ slideBox.classList.remove(SlideApi.renderedBoxClassName);
3591
+ slideBox.classList.add(SlideApi.prerenderBoxClassName);
3592
+ slideBox.innerHTML = "";
3593
+ slideBoxPrerender.classList.add(SlideApi.renderedBoxClassName);
3594
+ }
3595
+ // slideInRender = false;
3596
+ }
3597
+ async _startVideo(cb) {
3598
+ const videoElement = this.slide?.activeLayer?.videoElement;
3599
+ const videoStartedPromise = videoElement?.start(this._slideConfig.muted);
3600
+ if (videoStartedPromise) {
3601
+ videoStartedPromise.then(({ currentTime }) => {
3602
+ cb({ currentTime, slideIndex: this.slide?.slideIndex || 0 });
3603
+ });
3604
+ }
3605
+ else {
3606
+ cb({ currentTime: 0, slideIndex: this.slide?.slideIndex || 0 });
3607
+ }
3608
+ }
3609
+ _slideConfig = {};
3610
+ async slideStart(config) {
3611
+ // console.log(`slideStart slideIdx: ${this.activeLayer.slideIndex} state: ${this._state}`);
3612
+ if (!(this._state === 10 /* STATE.STOPPED */ || this._state === 1 /* STATE.INITED */)) {
3613
+ return { currentTime: 0 };
3614
+ }
3615
+ this._state = 2 /* STATE.START */;
3616
+ this._slideConfig = config;
3617
+ // start deferred fncs from widgets
3618
+ // important - Android only
3619
+ if (this.sdkApi.isAndroid && this._afterStartInitQueue && Array.isArray(this._afterStartInitQueue)) {
3620
+ for (const job of this._afterStartInitQueue) {
3621
+ if (isFunction(job)) {
3622
+ job();
3623
+ }
3624
+ }
3625
+ this._afterStartInitQueue = [];
3626
+ }
3627
+ if (this._afterResumeQueue && Array.isArray(this._afterResumeQueue)) {
3628
+ for (const job of this._afterResumeQueue) {
3629
+ if (isFunction(job)) {
3630
+ job();
3631
+ }
3632
+ }
3633
+ this._afterResumeQueue = [];
3634
+ }
3635
+ const { currentTime } = await this.slide.activeLayer.start(this._slideConfig.muted);
3636
+ this._state = 3 /* STATE.STARTED */;
3637
+ if (this.slide.activeLayer.isLayerForcePaused) {
3638
+ this._state = 7 /* STATE.PAUSED */;
3639
+ }
3640
+ return { currentTime };
3641
+ }
3642
+ async slideRestart(config) {
3643
+ this._state = 10 /* STATE.STOPPED */;
3644
+ return this.slideStart(config);
3645
+ }
3646
+ _pauseCbTimer = null;
3647
+ async slidePause() {
3648
+ if (!(this._state === 3 /* STATE.STARTED */ || this._state === 5 /* STATE.RESUMED */)) {
3649
+ return;
3650
+ }
3651
+ // обход бага на андроиде (вызывает pause/resume при любом нажатии на экран, даже если это клик - для перехода по слайдам)
3652
+ // поэтому делаем отложенный вызов (300мс) а если следом приходит stop - то отменяем таймер
3653
+ const pauseCb = () => {
3654
+ if (!(this._state === 3 /* STATE.STARTED */ || this._state === 5 /* STATE.RESUMED */)) {
3655
+ return;
3656
+ }
3657
+ if (this.slide.activeLayer.isClickCapturedBySlider()) {
3658
+ // stop pause event (from sdk) if _narrative_range_slider is active
3659
+ return;
3660
+ }
3661
+ this._state = 6 /* STATE.PAUSE */;
3662
+ // _log("pause: " + (performance.now() - window.start));
3663
+ this.slide.activeLayer.pause(false, false);
3664
+ // clean up
3665
+ if (this._pauseCbTimer != null) {
3666
+ clearTimeout(this._pauseCbTimer);
3667
+ }
3668
+ this._state = 7 /* STATE.PAUSED */;
3669
+ };
3670
+ if (this.sdkApi.isAndroid) {
3671
+ this._pauseCbTimer = this.layoutService.env.setTimeout(pauseCb, 300);
3672
+ }
3673
+ else {
3674
+ pauseCb();
3675
+ }
3676
+ }
3677
+ async slideResume() {
3678
+ if (this._pauseCbTimer != null) {
3679
+ // отменяем pause если есть (баг андроида - шлет pause/resume на простой клик)
3680
+ clearTimeout(this._pauseCbTimer);
3681
+ }
3682
+ if (this._state !== 7 /* STATE.PAUSED */) {
3683
+ return;
3684
+ }
3685
+ this._state = 4 /* STATE.RESUME */;
3686
+ // _log("resume: " + (performance.now() - window.start));
3687
+ if (this._afterResumeQueue && Array.isArray(this._afterResumeQueue)) {
3688
+ for (const job of this._afterResumeQueue) {
3689
+ if (isFunction(job)) {
3690
+ job();
3691
+ }
3692
+ }
3693
+ this._afterResumeQueue = [];
3694
+ }
3695
+ this.slide.activeLayer.resume();
3696
+ this._state = 5 /* STATE.RESUMED */;
3697
+ }
3698
+ async slideStop() {
3699
+ if (!(this._state === 3 /* STATE.STARTED */ || this._state === 5 /* STATE.RESUMED */ || this._state === 7 /* STATE.PAUSED */)) {
3700
+ return;
3701
+ }
3702
+ this._state = 9 /* STATE.STOP */;
3703
+ if (this._pauseCbTimer != null) {
3704
+ // отменяем pause если есть (баг андроида - шлет pause/resume на простой клик)
3705
+ clearTimeout(this._pauseCbTimer);
3706
+ }
3707
+ await this.slide.activeLayer.stop();
3708
+ this._state = 10 /* STATE.STOPPED */;
3709
+ }
3710
+ slideTimerEnd() {
3711
+ const defaultAction = () => {
3712
+ const nextSlideIndex = this.slide.slideIndex + 1;
3713
+ if (nextSlideIndex >= 0 && nextSlideIndex < this.slide.slideCount) {
3714
+ this.sdkApi.showCardSlide(nextSlideIndex);
3715
+ }
3716
+ else {
3717
+ this.sdkApi.cardShowNext();
3718
+ }
3719
+ };
3720
+ if (this.activeLayer.questElement) {
3721
+ const slideIndex = this.slide.slideIndex;
3722
+ const slideCount = this.slide.slideCount;
3723
+ const { continueDefaultNavigation } = this.activeLayer.questElement.handleRouteClick({
3724
+ // handleRouteTrigger
3725
+ direction: "forward",
3726
+ slideIndex: slideIndex,
3727
+ slideCount: slideCount,
3728
+ });
3729
+ if (continueDefaultNavigation) {
3730
+ // default action
3731
+ defaultAction();
3732
+ }
3733
+ return;
3734
+ }
3735
+ defaultAction();
3736
+ }
3737
+ // for call from SlideApi internals (from widgets)
3738
+ // skip state checking and sdk issues
3739
+ async slidePauseUI() {
3740
+ await this.slide.activeLayer.pause(false, false);
3741
+ this._state = 8 /* STATE.FORCE_PAUSED */;
3742
+ }
3743
+ // for call from SlideApi internals (from widgets)
3744
+ // skip state checking and sdk issues
3745
+ async slideResumeUI() {
3746
+ await this.slide.activeLayer.resume();
3747
+ this._state = 5 /* STATE.RESUMED */;
3748
+ }
3749
+ enableAudio() {
3750
+ this.slide.activeLayer.enableAudio();
3751
+ this._slideConfig.muted = false;
3752
+ }
3753
+ disableAudio() {
3754
+ this.slide.activeLayer.disableAudio();
3755
+ this._slideConfig.muted = true;
3756
+ }
3757
+ get isStopped() {
3758
+ return this._state === 10 /* STATE.STOPPED */;
3759
+ }
3760
+ afterStartInitQueuePush(cb) {
3761
+ if (!isFunction(cb)) {
3762
+ return false;
3763
+ }
3764
+ if (this.sdkApi.isAndroid && this._state === 0 /* STATE.INIT */) {
3765
+ this._afterStartInitQueue.push(cb);
3766
+ }
3767
+ else {
3768
+ cb();
3769
+ }
3770
+ }
3771
+ afterResumeQueuePush(cb) {
3772
+ if (!isFunction(cb)) {
3773
+ return false;
3774
+ }
3775
+ if ([4 /* STATE.RESUME */, 5 /* STATE.RESUMED */, 1 /* STATE.INITED */, 2 /* STATE.START */, 3 /* STATE.STARTED */].includes(this._state)) {
3776
+ cb();
3777
+ }
3778
+ else {
3779
+ this._afterResumeQueue.push(cb);
3780
+ }
3781
+ }
3782
+ get activeLayer() {
3783
+ return this.slide.activeLayer;
3784
+ }
3785
+ get slide() {
3786
+ // todo - call showLayer with arg slide: Slide - where slide is widget parent (prevent mismatch)
3787
+ // when widget in init state, it can call showLayer
3788
+ // then we must call showLayer not on this._slide but on this._slideInInit (on slide contains widget itself)
3789
+ return this._slideInInit || this._slide;
3790
+ }
3791
+ showLayer(index) {
3792
+ // todo - call showLayer with arg slide: Slide - where slide is widget parent (prevent mismatch)
3793
+ // when widget in init state, it can call showLayer
3794
+ // then we must call showLayer not on this._slide but on this._slideInInit (on slide contains widget itself)
3795
+ this.slide.showLayer(index, this._slideConfig.muted);
3796
+ }
3797
+ slideClickHandler(targetElement, navigationDirection) {
3798
+ const result = { canClickNext: true };
3799
+ let target = targetElement;
3800
+ let element;
3801
+ let propagation = true;
3802
+ // prevent click on geometry
3803
+ if (target?.classList.contains("narrative-element-geometry")) {
3804
+ target = target?.querySelector(".narrative-element");
3805
+ }
3806
+ if (target?.classList.contains("narrative-element-link")) {
3807
+ element = target;
3808
+ }
3809
+ else {
3810
+ element = target?.closest(".narrative-element-link");
3811
+ }
3812
+ if (element) {
3813
+ this._performLinkTarget(element);
3814
+ result.canClickNext = false;
3815
+ return result;
3816
+ }
3817
+ else {
3818
+ /** Image */
3819
+ if (target?.classList.contains("narrative-element-image")) {
3820
+ element = target;
3821
+ }
3822
+ else {
3823
+ element = target?.closest(".narrative-element-image");
3824
+ }
3825
+ if (element) {
3826
+ this._performLinkTarget(element);
3827
+ result.canClickNext = false;
3828
+ return result;
3829
+ }
3830
+ /** Swipe Up */
3831
+ if (target?.classList.contains("narrative-element-swipe-up")) {
3832
+ element = target;
3833
+ }
3834
+ else {
3835
+ element = target?.closest(".narrative-element-swipe-up");
3836
+ }
3837
+ if (element) {
3838
+ if (this.slideSwipeUpHandler(element)) {
3839
+ result.canClickNext = false;
3840
+ return result;
3841
+ }
3842
+ }
3843
+ /** Swipe Up Items */
3844
+ if (target?.classList.contains("narrative-element-swipe-up-items")) {
3845
+ element = target;
3846
+ }
3847
+ else {
3848
+ element = target?.closest(".narrative-element-swipe-up-items");
3849
+ }
3850
+ if (element) {
3851
+ if (this.slideSwipeUpHandler(element)) {
3852
+ result.canClickNext = false;
3853
+ return result;
3854
+ }
3855
+ }
3856
+ /** Products */
3857
+ if (target?.classList.contains("narrative-element-products")) {
3858
+ element = target;
3859
+ }
3860
+ else {
3861
+ element = target?.closest(".narrative-element-products");
3862
+ }
3863
+ if (element) {
3864
+ if (this.slideSwipeUpHandler(element)) {
3865
+ result.canClickNext = false;
3866
+ return result;
3867
+ }
3868
+ }
3869
+ /** Vote complete button (multiple choice) */
3870
+ if (target?.classList.contains("narrative-element-vote-next-button")) {
3871
+ element = target;
3872
+ }
3873
+ else {
3874
+ element = target?.closest(".narrative-element-vote-next-button");
3875
+ }
3876
+ if (element) {
3877
+ // if is widget file connected to Window
3878
+ if (this.layoutService.layoutApi.widgetVoteApi) {
3879
+ result.canClickNext = this.layoutService.layoutApi.widgetVoteApi.click(element);
3880
+ return result;
3881
+ }
3882
+ }
3883
+ /** Next button */
3884
+ if (target?.classList.contains("narrative-element-quiz-next-button")) {
3885
+ element = target;
3886
+ }
3887
+ else {
3888
+ element = target?.closest(".narrative-element-quiz-next-button");
3889
+ }
3890
+ if (!element) {
3891
+ if (target?.classList.contains("narrative-element-test-next-button")) {
3892
+ element = target;
3893
+ }
3894
+ else {
3895
+ element = target?.closest(".narrative-element-test-next-button");
3896
+ }
3897
+ }
3898
+ if (element) {
3899
+ this.layoutService.env.setTimeout(() => {
3900
+ this.sdkApi.showNextSlide(0);
3901
+ });
3902
+ result.canClickNext = false;
3903
+ return result;
3904
+ }
3905
+ /** Range slider */
3906
+ let rangeSliderBorderBoxView = target;
3907
+ if (target?.classList.contains("border-box-view") || (rangeSliderBorderBoxView = target?.closest(".border-box-view"))) {
3908
+ if (rangeSliderBorderBoxView?.parentElement && rangeSliderBorderBoxView.parentElement.classList.contains("narrative-element-range-slider")) {
3909
+ // skip click on .border-box-view inside .narrative-element-range-slider - prevent navigation trigger at click inside widget body (expect NextButton)
3910
+ result.canClickNext = false;
3911
+ return result;
3912
+ }
3913
+ }
3914
+ // if (_hasClass(target, "rangeslider") || target.closest(".rangeslider")) {
3915
+ // return;
3916
+ // }
3917
+ /** Range slider complete button */
3918
+ if (target?.classList.contains("narrative-element-range-slider-next-button")) {
3919
+ element = target;
3920
+ }
3921
+ else {
3922
+ element = target?.closest(".narrative-element-range-slider-next-button");
3923
+ }
3924
+ if (element) {
3925
+ if (this.layoutService.layoutApi.widgetRangeSliderApi) {
3926
+ result.canClickNext = this.layoutService.layoutApi.widgetRangeSliderApi.click(element);
3927
+ return result;
3928
+ }
3929
+ }
3930
+ /** Data input widget расширенный охват на весь виджет */
3931
+ if (target?.classList.contains("narrative-element-data-input")) {
3932
+ element = target;
3933
+ }
3934
+ else {
3935
+ element = target?.closest(".narrative-element-data-input");
3936
+ }
3937
+ if (element) {
3938
+ if (this.layoutService.layoutApi.widgetDataInputApi) {
3939
+ result.canClickNext = this.layoutService.layoutApi.widgetDataInputApi.click(element);
3940
+ return result;
3941
+ }
3942
+ }
3943
+ /** quiz */
3944
+ if (target?.classList.contains("narrative-element-quiz-answer")) {
3945
+ element = target;
3946
+ }
3947
+ else {
3948
+ element = target?.closest(".narrative-element-quiz-answer");
3949
+ }
3950
+ if (element) {
3951
+ if (element.closest(".narrative-element-quiz")) {
3952
+ /* quiz */
3953
+ if (this.layoutService.layoutApi.widgetQuizApi) {
3954
+ propagation = this.layoutService.layoutApi.widgetQuizApi.select(element);
3955
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
3956
+ }
3957
+ }
3958
+ else if (element.closest(".narrative-element-quiz-grouped")) {
3959
+ /* quiz-grouped */
3960
+ if (this.layoutService.layoutApi.widgetQuizGroupedApi) {
3961
+ propagation = this.layoutService.layoutApi.widgetQuizGroupedApi.select(element);
3962
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
3963
+ }
3964
+ }
3965
+ }
3966
+ /** poll or poll layers */
3967
+ if (target?.classList.contains("narrative-element-poll-button")) {
3968
+ element = target;
3969
+ }
3970
+ else {
3971
+ element = target?.closest(".narrative-element-poll-button");
3972
+ }
3973
+ if (element) {
3974
+ if (this.activeLayer.pollElement) {
3975
+ if (this.layoutService.layoutApi.widgetPollApi) {
3976
+ this.layoutService.layoutApi.widgetPollApi.select(element);
3977
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
3978
+ }
3979
+ }
3980
+ if (this.activeLayer.pollLayersElement) {
3981
+ if (this.layoutService.layoutApi.widgetPollLayersApi) {
3982
+ this.layoutService.layoutApi.widgetPollLayersApi.select(element);
3983
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
3984
+ }
3985
+ }
3986
+ }
3987
+ /** vote */
3988
+ if (target?.classList.contains("narrative-element-vote-answer")) {
3989
+ element = target;
3990
+ }
3991
+ else {
3992
+ element = target?.closest(".narrative-element-vote-answer");
3993
+ }
3994
+ if (element) {
3995
+ if (this.layoutService.layoutApi.widgetVoteApi) {
3996
+ propagation = this.layoutService.layoutApi.widgetVoteApi.select(element);
3997
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
3998
+ }
3999
+ }
4000
+ /** rate */
4001
+ if (target?.classList.contains("narrative-element-rate-input")) {
4002
+ element = target;
4003
+ }
4004
+ else {
4005
+ element = target?.closest(".narrative-element-rate-input");
4006
+ }
4007
+ if (element) {
4008
+ if (this.layoutService.layoutApi.widgetRateApi) {
4009
+ propagation = this.layoutService.layoutApi.widgetRateApi.select(element);
4010
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
4011
+ }
4012
+ }
4013
+ /** test */
4014
+ if (target?.classList.contains("narrative-element-test-answer")) {
4015
+ element = target;
4016
+ }
4017
+ else {
4018
+ element = target?.closest(".narrative-element-test-answer");
4019
+ }
4020
+ if (element) {
4021
+ if (element.closest(".narrative-element-test")) {
4022
+ /* test */
4023
+ if (this.layoutService.layoutApi.widgetTestApi) {
4024
+ propagation = this.layoutService.layoutApi.widgetTestApi.select(element);
4025
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
4026
+ }
4027
+ }
4028
+ else if (element.closest(".narrative-element-quest")) {
4029
+ /* quest */
4030
+ if (this.layoutService.layoutApi.widgetQuestApi) {
4031
+ propagation = this.layoutService.layoutApi.widgetQuestApi.select(element);
4032
+ propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
4033
+ }
4034
+ }
4035
+ }
4036
+ /** copy */
4037
+ if (target?.classList.contains("narrative-element-copy")) {
4038
+ element = target;
4039
+ }
4040
+ else {
4041
+ element = target?.closest(".narrative-element-copy");
4042
+ }
4043
+ if (element) {
4044
+ // if ("_narrative_test" in window) {
4045
+ // propagation = window._narrative_test.select(element);
4046
+ // propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
4047
+ // }
4048
+ if (this.layoutService.layoutApi.widgetCopyApi) {
4049
+ propagation = this.layoutService.layoutApi.widgetCopyApi.click(element);
4050
+ propagation = false; // по клику на Копировать не делаем клик на слайде
4051
+ }
4052
+ // copyToClipboard(element.getAttribute('data-clipboard-target'));
4053
+ // propagation = false;
4054
+ }
4055
+ /** barcode */
4056
+ if (target?.classList.contains("narrative-element-barcode")) {
4057
+ element = target;
4058
+ }
4059
+ else {
4060
+ element = target?.closest(".narrative-element-barcode");
4061
+ }
4062
+ if (element) {
4063
+ // if ("_narrative_test" in window) {
4064
+ // propagation = window._narrative_test.select(element);
4065
+ // propagation = false; // по клику на варианты ответа(даже на законченной викторине) не делаем клик на слайде
4066
+ // }
4067
+ if (this.layoutService.layoutApi.widgetBarcodeApi) {
4068
+ propagation = this.layoutService.layoutApi.widgetBarcodeApi.click(element);
4069
+ propagation = false; // по клику на Копировать не делаем клик на слайде
4070
+ }
4071
+ // copyToClipboard(element.getAttribute('data-clipboard-target'));
4072
+ // propagation = false;
4073
+ }
4074
+ /** share */
4075
+ if (target?.classList.contains("narrative-element-share")) {
4076
+ element = target;
4077
+ }
4078
+ else {
4079
+ element = target?.closest(".narrative-element-share");
4080
+ }
4081
+ if (element) {
4082
+ if (this.layoutService.layoutApi.widgetShareApi) {
4083
+ this.layoutService.layoutApi.widgetShareApi.click(element);
4084
+ propagation = false;
4085
+ }
4086
+ }
4087
+ /** story-repeat */
4088
+ if (target?.classList.contains("narrative-element-story-repeat")) {
4089
+ element = target;
4090
+ }
4091
+ else {
4092
+ element = target?.closest(".narrative-element-story-repeat");
4093
+ }
4094
+ if (element) {
4095
+ propagation = false;
4096
+ this.sdkApi.setCardLocalData({}, true);
4097
+ this.sdkApi.updateCardServerDataLocally(this.slide.cardId, {});
4098
+ // window._resetTimers();
4099
+ // сделать async в ios
4100
+ let slideIndex = this.slide.slideIndex;
4101
+ // prevent simultaneous call _showNarrativeSlide and _showLayer - prevent 2 calls of initAfterLoad (break video start on iOS)
4102
+ if (slideIndex === 0) {
4103
+ // for story repeat on the first slide with layers
4104
+ this.sdkApi.showLayer(0);
4105
+ }
4106
+ else {
4107
+ this.sdkApi.showCardSlide(0); // сделать ее async
4108
+ }
4109
+ }
4110
+ if (!propagation) {
4111
+ result.canClickNext = false;
4112
+ return result;
4113
+ }
4114
+ }
4115
+ /** can tap to next slide */
4116
+ if (this.activeLayer.quizElement) {
4117
+ result.canClickNext = this.activeLayer.quizElement.slideQuizIsDone;
4118
+ }
4119
+ if (this.activeLayer.quizGroupedElement) {
4120
+ result.canClickNext = this.activeLayer.quizGroupedElement.slideQuizGroupedIsDone;
4121
+ }
4122
+ if (this.activeLayer.testElement) {
4123
+ result.canClickNext = this.activeLayer.testElement.slideTestIsDone;
4124
+ if (this.activeLayer.testElement.slideTestWithTimer && !result.canClickNext) {
4125
+ result.canClickNext = false;
4126
+ return result; // disable all clicks
4127
+ }
4128
+ }
4129
+ if (this.activeLayer.rangeSliderElement) {
4130
+ if (this.activeLayer.rangeSliderElement.isClickCapturedBySlider) {
4131
+ result.canClickNext = false;
4132
+ return result; // disable all clicks if event captured by slider
4133
+ }
4134
+ }
4135
+ if (this.activeLayer.productsElement) {
4136
+ if (this.activeLayer.productsElement.isClickCapturedByWidget) {
4137
+ result.canClickNext = false;
4138
+ return result; // disable all clicks if event captured by products widget (slider or swipe down)
4139
+ }
4140
+ }
4141
+ if (this.activeLayer.questElement) {
4142
+ const slideIndex = this.slide.slideIndex;
4143
+ const slideCount = this.slide.slideCount;
4144
+ const { continueDefaultNavigation } = this.activeLayer.questElement.handleRouteClick({
4145
+ direction: navigationDirection,
4146
+ slideIndex: slideIndex,
4147
+ slideCount: slideCount,
4148
+ });
4149
+ result.canClickNext = continueDefaultNavigation;
4150
+ return result;
4151
+ }
4152
+ const disableNavigation = this.slide.disabledNavigation;
4153
+ if (disableNavigation) {
4154
+ result.canClickNext = false;
4155
+ return result; // disable slide tap navigation
4156
+ }
4157
+ // _clickNext(canClickNext, xPercent);
4158
+ return result;
4159
+ }
4160
+ _performLinkSpecialAndReturnTarget(element) {
4161
+ const linkType = element.getAttribute("data-link-type");
4162
+ let linkTarget = element.getAttribute("data-link-target");
4163
+ const linkTargetIos = element.getAttribute("data-link-target-ios");
4164
+ const linkTargetAndroid = element.getAttribute("data-link-target-android");
4165
+ const linkTargetWeb = element.getAttribute("data-link-target-web");
4166
+ let emitClick = false;
4167
+ if (this.sdkApi.isAndroid && linkTargetAndroid) {
4168
+ linkTarget = linkTargetAndroid;
4169
+ }
4170
+ if (this.sdkApi.isIOS && linkTargetIos) {
4171
+ linkTarget = linkTargetIos;
4172
+ }
4173
+ if (this.sdkApi.isWeb && linkTargetWeb) {
4174
+ linkTarget = linkTargetWeb;
4175
+ }
4176
+ if (linkType === "closeStory" || linkType === "closeIAM") {
4177
+ this.layoutService.env.setTimeout(() => this.sdkApi.closeCard("click"));
4178
+ emitClick = false;
4179
+ }
4180
+ if (linkType && linkTarget) {
4181
+ emitClick = true;
4182
+ if (linkType === "story") {
4183
+ // storyId: number, slideIndex: number
4184
+ this.layoutService.env.setTimeout(() => this.sdkApi.openStory(parseInt(linkTarget), 0));
4185
+ emitClick = false;
4186
+ }
4187
+ if (linkType === "slide") {
4188
+ const __slideIndex = parseInt(linkTarget);
4189
+ const __slideCount = this.slide.slideCount;
4190
+ if (__slideIndex >= 0 && __slideIndex < __slideCount) {
4191
+ this.layoutService.env.setTimeout(() => this.sdkApi.showCardSlide(__slideIndex));
4192
+ emitClick = false;
4193
+ }
4194
+ }
4195
+ if (linkType === "game") {
4196
+ this.layoutService.env.setTimeout(() => this.sdkApi.openGame(linkTarget));
4197
+ emitClick = false;
4198
+ }
4199
+ if (linkType === "layer") {
4200
+ const layerIndex = parseInt(linkTarget);
4201
+ if (layerIndex >= 0) {
4202
+ this.layoutService.env.setTimeout(() => this.sdkApi.showLayer(layerIndex));
4203
+ emitClick = false;
4204
+ }
4205
+ }
4206
+ }
4207
+ return { linkType, linkTarget, emitClick };
4208
+ }
4209
+ _performLinkTarget(element) {
4210
+ const { linkType, linkTarget, emitClick } = this._performLinkSpecialAndReturnTarget(element);
4211
+ // for btn(link) without url (openGame, openStory, closeCard, etc)
4212
+ let statisticWidgetValue = linkType;
4213
+ if (emitClick && linkTarget && (linkType === "url" || linkType === "json")) {
4214
+ const obj = {
4215
+ type: "link",
4216
+ link: {
4217
+ type: linkType,
4218
+ target: linkTarget,
4219
+ },
4220
+ };
4221
+ // traditional link, with url
4222
+ statisticWidgetValue = linkTarget;
4223
+ this.layoutService.env.setTimeout(() => {
4224
+ this.sdkApi.openUrl(obj);
4225
+ });
4226
+ }
4227
+ try {
4228
+ const cardId = this.slide.cardId;
4229
+ const cardType = this.slide.cardType;
4230
+ const slideIndex = this.slide.slideIndex;
4231
+ let baseFields = {};
4232
+ switch (cardType) {
4233
+ case 1 /* CARD_TYPE.STORY */:
4234
+ case 2 /* CARD_TYPE.UGC_STORY */:
4235
+ baseFields.story_id = cardId;
4236
+ break;
4237
+ case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
4238
+ baseFields.message_id = cardId;
4239
+ break;
4240
+ }
4241
+ const elementId = element.getAttribute("data-element-id");
4242
+ this.sdkApi.sendStatisticEvent("w-link", {
4243
+ i: cardId,
4244
+ si: slideIndex,
4245
+ wi: elementId ?? "",
4246
+ wl: element.textContent ?? "",
4247
+ wv: statisticWidgetValue ?? "",
4248
+ }, {
4249
+ ...baseFields,
4250
+ slide_index: slideIndex,
4251
+ widget_id: elementId ?? "",
4252
+ widget_label: element.textContent ?? "",
4253
+ widget_value: statisticWidgetValue ?? "",
4254
+ });
4255
+ }
4256
+ catch (error) {
4257
+ console.error(error);
4258
+ }
4259
+ }
4260
+ // получать событие swipeUp от sdk, в том числе и от web sdk
4261
+ slideSwipeUpHandler(target) {
4262
+ if (target == null) {
4263
+ const targetElement = this.activeLayer.swipeUpElement || this.activeLayer.swipeUpItemsElement || this.activeLayer.productsElement;
4264
+ target = targetElement?.elementNodeRef;
4265
+ }
4266
+ if (!target) {
4267
+ return false;
4268
+ }
4269
+ const elementId = target.getAttribute("data-element-id") || "";
4270
+ const { linkType, linkTarget: _linkTarget, emitClick } = this._performLinkSpecialAndReturnTarget(target);
4271
+ if (emitClick) {
4272
+ const linkTarget = decodeURIComponent(_linkTarget ?? "");
4273
+ if (linkType === "products") {
4274
+ if (this.layoutService.layoutApi.widgetProductsApi) {
4275
+ this.layoutService.layoutApi.widgetProductsApi.click(target);
4276
+ }
4277
+ return true;
4278
+ }
4279
+ let swipeUpLinkObj = {
4280
+ type: "swipeUpLink",
4281
+ link: {
4282
+ type: "url",
4283
+ target: linkTarget,
4284
+ },
4285
+ elementId,
4286
+ };
4287
+ if (linkType === "swipe-up-items") {
4288
+ swipeUpLinkObj = {
4289
+ type: "swipeUpItems",
4290
+ link: {
4291
+ type: "json",
4292
+ target: linkTarget,
4293
+ },
4294
+ elementId,
4295
+ };
4296
+ try {
4297
+ // TODO CSP violation
4298
+ target.style.setProperty("opacity", "0");
4299
+ }
4300
+ catch (e) {
4301
+ console.error(e);
4302
+ }
4303
+ }
4304
+ this.layoutService.env.setTimeout(() => {
4305
+ this.sdkApi.openUrl(swipeUpLinkObj);
4306
+ });
4307
+ let eventType = "";
4308
+ if (linkType === "url") {
4309
+ eventType = "w-link";
4310
+ }
4311
+ else if (linkType === "swipe-up-items") {
4312
+ eventType = "w-goods-open";
4313
+ }
4314
+ if (eventType) {
4315
+ try {
4316
+ const cardId = this.slide.cardId;
4317
+ const cardType = this.slide.cardType;
4318
+ const slideIndex = this.slide.slideIndex;
4319
+ let baseFields = {};
4320
+ switch (cardType) {
4321
+ case 1 /* CARD_TYPE.STORY */:
4322
+ case 2 /* CARD_TYPE.UGC_STORY */:
4323
+ baseFields.story_id = cardId;
4324
+ break;
4325
+ case 4 /* CARD_TYPE.IN_APP_MESSAGING */:
4326
+ baseFields.message_id = cardId;
4327
+ break;
4328
+ }
4329
+ this.sdkApi.sendStatisticEvent(eventType, {
4330
+ i: cardId,
4331
+ si: slideIndex,
4332
+ wi: elementId,
4333
+ wl: target.textContent ?? "",
4334
+ wv: linkTarget,
4335
+ }, {
4336
+ ...baseFields,
4337
+ slide_index: slideIndex,
4338
+ widget_id: elementId,
4339
+ widget_label: target.textContent ?? "",
4340
+ widget_value: linkTarget,
4341
+ });
4342
+ }
4343
+ catch (error) {
4344
+ console.error(error);
4345
+ }
4346
+ }
4347
+ return true;
4348
+ }
4349
+ else {
4350
+ return false;
4351
+ }
4352
+ }
4353
+ setTextInputResult(id, text) {
4354
+ if (this.activeLayer.dataInputElement) {
4355
+ this.activeLayer.dataInputElement.setUserData(id, text);
4356
+ }
4357
+ if (this.activeLayer.pollElement) {
4358
+ this.activeLayer.pollElement.setUserData(id, text);
4359
+ }
4360
+ if (this.activeLayer.rateElement) {
4361
+ this.activeLayer.rateElement.setUserData(id, text);
4362
+ }
4363
+ }
4364
+ setShareComplete(id, isSuccess) {
4365
+ if (this.activeLayer.shareElement) {
4366
+ this.activeLayer.shareElement.complete(id, isSuccess);
4367
+ }
4368
+ }
4369
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`{\n slideWrapper: HTMLElement;\n viewport: Window;\n userResizeHandler?: (data: { viewportWidth: number; viewportHeight: number; fontSize: number }) => void;\n slideRatio: number;\n isFullscreen: boolean;\n slideLoadedCb?: (data: { slide: Slide; result: boolean; reason?: string }) => void;\n }`]; }
4370
+ };
4371
+
4372
+ let sdkInterface;
4373
+ const createSlideWrapper = ({ slideBoxRatio, nonce }) => {
4374
+ const slideWrapper = document.createElement("div");
4375
+ slideWrapper.classList.add("narrative-slide-wrapper");
4376
+ slideWrapper.classList.add("stories-viewer");
4377
+ const slideOffset = document.createElement("div");
4378
+ slideOffset.classList.add("narrative-slide-offset");
4379
+ const slideBoxPrerender = document.createElement("div");
4380
+ slideBoxPrerender.classList.add("narrative-slide-box");
4381
+ slideBoxPrerender.classList.add("narrative-slide-box-prerender");
4382
+ const slideBoxRendered = document.createElement("div");
4383
+ slideBoxRendered.classList.add("narrative-slide-box");
4384
+ slideBoxRendered.classList.add("narrative-slide-box-rendered");
4385
+ const style = document.createElement("style");
4386
+ if (nonce != null) {
4387
+ style.nonce = nonce;
4388
+ }
4389
+ const paddingTop = `${String(100 / slideBoxRatio)}%`;
4390
+ // .narrative-slide-box {
4391
+ // padding: <?= $slideRatioPadding ?> 0 0 0;
4392
+ // }
4393
+ style.sheet?.insertRule(`.narrative-slide-box {padding: ${paddingTop} 0 0 0;`);
4394
+ slideOffset.appendChild(slideBoxPrerender);
4395
+ slideOffset.appendChild(slideBoxRendered);
4396
+ slideWrapper.appendChild(slideOffset);
4397
+ slideWrapper.appendChild(style);
4398
+ return slideWrapper;
4399
+ };
4400
+ class SlideApi extends SlideApi$1 {
4401
+ constructor(_sdkInterface, config) {
4402
+ sdkInterface = _sdkInterface;
4403
+ config.VODPlayer;
4404
+ const slideWrapper = createSlideWrapper({ slideBoxRatio: config.slideRatio, nonce: config.nonce });
4405
+ // todo need to clear root node before append slideWrapper?
4406
+ config.root.appendChild(slideWrapper);
4407
+ super({
4408
+ slideWrapper,
4409
+ viewport: config.viewport,
4410
+ slideRatio: config.slideRatio,
4411
+ isFullscreen: config.isFullscreen,
4412
+ userResizeHandler: config.userResizeHandler,
4413
+ });
4414
+ }
4415
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`SDKInterface`, `{\n root: HTMLElement;\n slideRatio: number;\n isFullscreen: boolean;\n nonce?: string;\n viewport: Window;\n userResizeHandler?: (data: { viewportWidth: number; viewportHeight: number; fontSize: number }) => void;\n VODPlayer?: typeof VODPlayer;\n }`]; }
4416
+ }
4417
+
4418
+ container.registerSingleton(() => new EsModuleSdkApi(() => sdkInterface), { identifier: `SDKApi` });
4419
+
4420
+ exports.SlideApi = SlideApi;
1003
4421
  //# sourceMappingURL=index.cjs.map