@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 +3425 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +3425 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|