@next-core/brick-utils 2.43.7 → 2.44.0

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.
@@ -691,7 +691,11 @@
691
691
  onAnchorLoad,
692
692
  onAnchorUnload,
693
693
  onMessage,
694
- onMessageClose
694
+ onMessageClose,
695
+ onBeforePageLoad,
696
+ onBeforePageLeave,
697
+ onMediaChange,
698
+ onScrollIntoView
695
699
  } = brickConf.lifeCycle;
696
700
 
697
701
  if (Array.isArray(useResolves)) {
@@ -704,14 +708,17 @@
704
708
  });
705
709
  }
706
710
 
707
- var messageLifeCycleHandlers = [].concat(onMessage).filter(Boolean).reduce((previousValue, currentValue) => previousValue.concat(currentValue.handlers), []);
711
+ var specialHandlers = [].concat(onMessage, onScrollIntoView).filter(Boolean).reduce((previousValue, currentValue) => previousValue.concat(currentValue.handlers), []);
708
712
  collectUsedBricksInEventHandlers({
709
713
  onPageLoad,
710
714
  onPageLeave,
711
715
  onAnchorLoad,
712
716
  onAnchorUnload,
713
717
  onMessageClose,
714
- onMessage: messageLifeCycleHandlers
718
+ onBeforePageLoad,
719
+ onBeforePageLeave,
720
+ onMediaChange,
721
+ specialHandlers
715
722
  }, collection);
716
723
  }
717
724
 
@@ -23380,6 +23387,282 @@
23380
23387
  };
23381
23388
  }
23382
23389
 
23390
+ /**
23391
+ * Remove dead conditions in storyboard like `if: '<% FLAGS["your-feature-flag"] %>'` when
23392
+ * `FLAGS["your-feature-flag"]` is falsy.
23393
+ */
23394
+ function removeDeadConditions(storyboard, options) {
23395
+ var _storyboard$meta;
23396
+
23397
+ if (storyboard.$$deadConditionsRemoved) {
23398
+ return;
23399
+ }
23400
+
23401
+ removeDeadConditionsInRoutes(storyboard.routes, options);
23402
+ var {
23403
+ customTemplates
23404
+ } = (_storyboard$meta = storyboard.meta) !== null && _storyboard$meta !== void 0 ? _storyboard$meta : {};
23405
+
23406
+ if (Array.isArray(customTemplates)) {
23407
+ for (var tpl of customTemplates) {
23408
+ removeDeadConditionsInTpl(tpl, options);
23409
+ }
23410
+ }
23411
+
23412
+ storyboard.$$deadConditionsRemoved = true;
23413
+ }
23414
+ /**
23415
+ * Like `removeDeadConditions` but applied to a custom template.
23416
+ */
23417
+
23418
+ function removeDeadConditionsInTpl(tplConstructor, options) {
23419
+ removeDeadConditionsInBricks(tplConstructor.bricks, options);
23420
+ }
23421
+
23422
+ function removeDeadConditionsInRoutes(routes, options) {
23423
+ removeDeadConditionsInArray(routes, options, route => {
23424
+ removeDeadConditionsInContext(route.context, options);
23425
+
23426
+ if (route.type === "routes") {
23427
+ removeDeadConditionsInRoutes(route.routes, options);
23428
+ } else {
23429
+ removeDeadConditionsInBricks(route.bricks, options);
23430
+ }
23431
+ });
23432
+ }
23433
+
23434
+ function removeDeadConditionsInBricks(bricks, options) {
23435
+ removeDeadConditionsInArray(bricks, options, brick => {
23436
+ if (brick.slots) {
23437
+ for (var slot of Object.values(brick.slots)) {
23438
+ if (slot.type === "routes") {
23439
+ removeDeadConditionsInRoutes(slot.routes, options);
23440
+ } else {
23441
+ removeDeadConditionsInBricks(slot.bricks, options);
23442
+ }
23443
+ }
23444
+ }
23445
+
23446
+ removeDeadConditionsInLifeCycle(brick.lifeCycle, options);
23447
+ removeDeadConditionsInEvents(brick.events, options);
23448
+ removeDeadConditionsInContext(brick.context, options);
23449
+ removeDeadConditionsInProperties(brick.properties, options);
23450
+ });
23451
+ }
23452
+
23453
+ function removeDeadConditionsInProperties(value, options) {
23454
+ if (Array.isArray(value)) {
23455
+ for (var _item of value) {
23456
+ removeDeadConditionsInProperties(_item, options);
23457
+ }
23458
+ } else if (isObject(value)) {
23459
+ if (value.useBrick) {
23460
+ if (Array.isArray(value.useBrick)) {
23461
+ // For useBrick as array, just remove dead items.
23462
+ removeDeadConditionsInArray(value.useBrick, options, useBrick => {
23463
+ removeDeadConditionsInUseBrick(useBrick, options);
23464
+ });
23465
+ } else {
23466
+ // For useBrick as single one, we have to keep it,
23467
+ // and we change it to an empty <div>.
23468
+ computeConstantCondition(value.useBrick, options);
23469
+
23470
+ if (value.useBrick.if === false) {
23471
+ value.useBrick = {
23472
+ brick: "div",
23473
+ if: false
23474
+ };
23475
+ } else {
23476
+ removeDeadConditionsInUseBrick(value.useBrick, options);
23477
+ }
23478
+ }
23479
+ } else {
23480
+ for (var _item2 of Object.values(value)) {
23481
+ removeDeadConditionsInProperties(_item2, options);
23482
+ }
23483
+ }
23484
+ }
23485
+ }
23486
+
23487
+ function removeDeadConditionsInUseBrick(useBrick, options) {
23488
+ removeDeadConditionsInProperties(useBrick.properties, options);
23489
+ removeDeadConditionsInEvents(useBrick.events, options);
23490
+
23491
+ if (useBrick.slots) {
23492
+ for (var slot of Object.values(useBrick.slots)) {
23493
+ removeDeadConditionsInBricks(slot.bricks, options);
23494
+ }
23495
+ }
23496
+ }
23497
+
23498
+ function removeDeadConditionsInEvents(events, options) {
23499
+ if (isObject(events)) {
23500
+ for (var eventType of Object.keys(events)) {
23501
+ removeDeadConditionsInEvent(events, eventType, options);
23502
+ }
23503
+ }
23504
+ }
23505
+
23506
+ function removeDeadConditionsInEvent(events, eventType, options) {
23507
+ var handlers = events[eventType];
23508
+
23509
+ if (!handlers) {
23510
+ return;
23511
+ }
23512
+
23513
+ if (Array.isArray(handlers)) {
23514
+ removeDeadConditionsInArray(handlers, options, handler => {
23515
+ if (handler.callback) {
23516
+ removeDeadConditionsInEvents(handler.callback, options);
23517
+ }
23518
+ });
23519
+ } else {
23520
+ computeConstantCondition(handlers, options);
23521
+
23522
+ if (handlers.if === false) {
23523
+ delete events[eventType];
23524
+ return;
23525
+ }
23526
+
23527
+ if (handlers.callback) {
23528
+ removeDeadConditionsInEvents(handlers.callback, options);
23529
+ }
23530
+ }
23531
+ }
23532
+
23533
+ function removeDeadConditionsInContext(context, options) {
23534
+ removeDeadConditionsInArray(context, options);
23535
+ }
23536
+
23537
+ function removeDeadConditionsInArray(list, options, callback) {
23538
+ if (Array.isArray(list)) {
23539
+ var removes = [];
23540
+
23541
+ for (var _item3 of list) {
23542
+ computeConstantCondition(_item3, options);
23543
+
23544
+ if (_item3.if === false) {
23545
+ removes.push(_item3);
23546
+ continue;
23547
+ }
23548
+
23549
+ callback === null || callback === void 0 ? void 0 : callback(_item3);
23550
+ }
23551
+
23552
+ lodash.pull(list, ...removes);
23553
+ }
23554
+ }
23555
+
23556
+ function removeDeadConditionsInLifeCycle(lifeCycle, options) {
23557
+ if (lifeCycle) {
23558
+ removeDeadConditionsInArray(lifeCycle.useResolves, options);
23559
+
23560
+ for (var key of ["onPageLoad", "onPageLeave", "onAnchorLoad", "onAnchorUnload", "onMessageClose", "onBeforePageLoad", "onBeforePageLeave", "onMediaChange"]) {
23561
+ removeDeadConditionsInEvent(lifeCycle, key, options);
23562
+ }
23563
+
23564
+ for (var _key of ["onMessage", "onScrollIntoView"]) {
23565
+ for (var withHandlers of [].concat(lifeCycle[_key])) {
23566
+ if (withHandlers) {
23567
+ removeDeadConditionsInEvent(withHandlers, "handlers", options);
23568
+ }
23569
+ }
23570
+ }
23571
+ }
23572
+ }
23573
+
23574
+ function computeConstantCondition(ifContainer) {
23575
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
23576
+
23577
+ if (hasOwnProperty$1(ifContainer, "if")) {
23578
+ if (typeof ifContainer.if === "string" && isEvaluable(ifContainer.if)) {
23579
+ try {
23580
+ var {
23581
+ expression,
23582
+ attemptToVisitGlobals,
23583
+ source
23584
+ } = preevaluate(ifContainer.if);
23585
+ var {
23586
+ constantFeatureFlags,
23587
+ featureFlags
23588
+ } = options;
23589
+ var hasDynamicVariables = false;
23590
+
23591
+ for (var _item4 of attemptToVisitGlobals) {
23592
+ if (_item4 !== "undefined" && (!constantFeatureFlags || _item4 !== "FLAGS")) {
23593
+ hasDynamicVariables = true;
23594
+ break;
23595
+ }
23596
+ }
23597
+
23598
+ if (hasDynamicVariables) {
23599
+ if (isConstantLogical(expression, false, options)) {
23600
+ if (process.env.NODE_ENV === "development") {
23601
+ // eslint-disable-next-line no-console
23602
+ console.warn("[removed dead if]:", ifContainer.if, ifContainer);
23603
+ }
23604
+
23605
+ ifContainer.if = false;
23606
+ }
23607
+
23608
+ return;
23609
+ }
23610
+
23611
+ var originalIf = ifContainer.if;
23612
+ var globalVariables = {
23613
+ undefined: undefined
23614
+ };
23615
+
23616
+ if (constantFeatureFlags) {
23617
+ globalVariables.FLAGS = featureFlags;
23618
+ }
23619
+
23620
+ ifContainer.if = !!cook(expression, source, {
23621
+ globalVariables
23622
+ });
23623
+
23624
+ if (process.env.NODE_ENV === "development" && ifContainer.if === false) {
23625
+ // eslint-disable-next-line no-console
23626
+ console.warn("[removed dead if]:", originalIf, ifContainer);
23627
+ }
23628
+ } catch (error) {
23629
+ // eslint-disable-next-line no-console
23630
+ console.error("Parse storyboard expression failed:", error);
23631
+ }
23632
+ } else if (!ifContainer.if && ifContainer.if !== false) {
23633
+ // eslint-disable-next-line no-console
23634
+ console.warn("[potential dead if]:", typeof ifContainer.if, ifContainer.if, ifContainer);
23635
+ }
23636
+ }
23637
+ }
23638
+ /**
23639
+ * We can safely remove the code for the following use cases,
23640
+ * even though they contain runtime variables such as CTX:
23641
+ *
23642
+ * - if: '<% false && CTX.any %>'
23643
+ * - if: '<% FLAGS["disabled"] && CTX.any %>'
23644
+ * - if: '<% !FLAGS["enabled"] && CTX.any %>'
23645
+ * - if: '<% !(FLAGS["enabled"] || CTX.any) %>'
23646
+ *
23647
+ * Since these logics will always get a falsy result.
23648
+ *
23649
+ * Here we simply only consider these kinds of AST node:
23650
+ *
23651
+ * - LogicalExpression: with operator of '||' or '&&'
23652
+ * - UnaryExpression: with operator of '!'
23653
+ * - Literal: such as boolean/number/string/null/regex
23654
+ * - MemberExpression: of 'FLAGS["disabled"]' or 'FLAGS.disabled'
23655
+ * - Identifier: of 'undefined'
23656
+ */
23657
+
23658
+ function isConstantLogical(node, expect, options) {
23659
+ var {
23660
+ constantFeatureFlags,
23661
+ featureFlags
23662
+ } = options;
23663
+ return node.type === "LogicalExpression" ? node.operator === (expect ? "||" : "&&") && [node.left, node.right].some(item => isConstantLogical(item, expect, options)) : node.type === "UnaryExpression" ? node.operator === "!" && isConstantLogical(node.argument, !expect, options) : node.type === "Literal" ? !!node.value === expect : node.type === "Identifier" ? node.name === "undefined" ? !expect : false : constantFeatureFlags && node.type === "MemberExpression" && node.object.type === "Identifier" && node.object.name === "FLAGS" && (node.computed ? node.property.type === "Literal" && typeof node.property.value === "string" && !!featureFlags[node.property.value] === expect : node.property.type === "Identifier" && !!featureFlags[node.property.name] === expect);
23664
+ }
23665
+
23383
23666
  Object.defineProperty(exports, 'pipes', {
23384
23667
  enumerable: true,
23385
23668
  get: function () { return pipes.pipes; }
@@ -23390,6 +23673,7 @@
23390
23673
  exports.asyncProcessBrick = asyncProcessBrick;
23391
23674
  exports.asyncProcessStoryboard = asyncProcessStoryboard;
23392
23675
  exports.collectBricksByCustomTemplates = collectBricksByCustomTemplates;
23676
+ exports.computeConstantCondition = computeConstantCondition;
23393
23677
  exports.computeRealRoutePath = computeRealRoutePath;
23394
23678
  exports.convertValueByPrecision = convertValueByPrecision;
23395
23679
  exports.cook = cook;
@@ -23423,6 +23707,8 @@
23423
23707
  exports.precookFunction = precookFunction;
23424
23708
  exports.preevaluate = preevaluate;
23425
23709
  exports.prefetchScript = prefetchScript;
23710
+ exports.removeDeadConditions = removeDeadConditions;
23711
+ exports.removeDeadConditionsInTpl = removeDeadConditionsInTpl;
23426
23712
  exports.resolveContextConcurrently = resolveContextConcurrently;
23427
23713
  exports.restoreDynamicTemplates = restoreDynamicTemplates;
23428
23714
  exports.scanAppGetMenuInAny = scanAppGetMenuInAny;