eoss 0.1.0-alpha.32 → 0.1.0-alpha.34

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.
Files changed (56) hide show
  1. package/lib/account-login.js +1 -1
  2. package/lib/audit-trajectory.js +1 -1
  3. package/lib/autocomplete.js +109 -70
  4. package/lib/cascader.js +109 -70
  5. package/lib/checkbox-group.js +1 -1
  6. package/lib/color-picker.js +109 -70
  7. package/lib/config/api.js +1 -1
  8. package/lib/data-table.js +1 -1
  9. package/lib/date-picker.js +109 -70
  10. package/lib/dropdown-menu.js +109 -70
  11. package/lib/email-login.js +1 -1
  12. package/lib/eoss.common.js +320 -147
  13. package/lib/flow.js +1 -1
  14. package/lib/flows.js +1 -1
  15. package/lib/form.js +1 -1
  16. package/lib/icon.js +1 -1
  17. package/lib/index.js +1 -1
  18. package/lib/login.js +1 -1
  19. package/lib/lowcode-view.js +94 -35
  20. package/lib/lowcode.js +98 -24
  21. package/lib/main.js +3 -2
  22. package/lib/menu.js +109 -70
  23. package/lib/phone-login.js +1 -1
  24. package/lib/popover.js +109 -70
  25. package/lib/process-config.js +1 -1
  26. package/lib/process-module.js +1 -1
  27. package/lib/process-rule.js +1 -1
  28. package/lib/qrcode-login.js +1 -1
  29. package/lib/radio-group.js +1 -1
  30. package/lib/select.js +110 -71
  31. package/lib/selector-panel.js +1 -1
  32. package/lib/selector.js +1 -1
  33. package/lib/submenu.js +109 -70
  34. package/lib/table.js +110 -71
  35. package/lib/theme-chalk/base.css +1 -1
  36. package/lib/theme-chalk/index.css +1 -1
  37. package/lib/theme-chalk/main.css +1 -1
  38. package/lib/time-picker.js +109 -70
  39. package/lib/time-select.js +109 -70
  40. package/lib/tips.js +1 -1
  41. package/lib/tooltip.js +109 -70
  42. package/lib/tree-group.js +1 -1
  43. package/lib/tree.js +1 -1
  44. package/lib/update-history.js +1 -1
  45. package/lib/upload.js +1 -1
  46. package/lib/utils/popper.js +97 -48
  47. package/package.json +1 -1
  48. package/packages/lowcode/src/lowcode.vue +43 -2
  49. package/packages/lowcode/src/render.vue +47 -12
  50. package/packages/lowcode-view/src/render.vue +66 -26
  51. package/packages/lowcode-view/src/view.vue +13 -2
  52. package/packages/main/src/minxs.js +2 -1
  53. package/packages/theme-chalk/src/base.scss +2 -1
  54. package/src/config/api.js +1 -1
  55. package/src/index.js +1 -1
  56. package/src/utils/popper.js +109 -70
@@ -3765,7 +3765,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
3765
3765
  //
3766
3766
  var referenceOffsets = getOffsetRectRelativeToCustomParent(
3767
3767
  reference,
3768
- getOffsetParent(popper),
3768
+ popper,
3769
3769
  isParentFixed
3770
3770
  );
3771
3771
 
@@ -3820,17 +3820,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
3820
3820
  Popper.prototype._setupEventListeners = function () {
3821
3821
  // NOTE: 1 DOM access here
3822
3822
  this.state.updateBound = this.update.bind(this);
3823
- root.addEventListener('resize', this.state.updateBound);
3823
+ // 无界等微前端场景下沙箱 window 不会触发 resize,需监听真实 window
3824
+ this.state.realWindow = getRealWindow(this._popper);
3825
+ this.state.realWindow.addEventListener('resize', this.state.updateBound);
3824
3826
  // if the boundariesElement is window we don't need to listen for the scroll event
3825
3827
  if (this._options.boundariesElement !== 'window') {
3826
3828
  var target = getScrollParent(this._reference);
3827
- // here it could be both `body` or `documentElement` thanks to Firefox, we then check both
3828
- if (
3829
- target === root.document.body ||
3830
- target === root.document.documentElement
3831
- ) {
3832
- target = root;
3833
- }
3834
3829
  target.addEventListener('scroll', this.state.updateBound);
3835
3830
  this.state.scrollTarget = target;
3836
3831
  }
@@ -3844,7 +3839,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
3844
3839
  */
3845
3840
  Popper.prototype._removeEventListeners = function () {
3846
3841
  // NOTE: 1 DOM access here
3847
- root.removeEventListener('resize', this.state.updateBound);
3842
+ (this.state.realWindow || root).removeEventListener(
3843
+ 'resize',
3844
+ this.state.updateBound
3845
+ );
3848
3846
  if (
3849
3847
  this._options.boundariesElement !== 'window' &&
3850
3848
  this.state.scrollTarget
@@ -3898,47 +3896,24 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
3898
3896
  left: 0
3899
3897
  };
3900
3898
  } else if (boundariesElement === 'viewport') {
3901
- var offsetParent = getOffsetParent(this._popper);
3902
- var scrollParent = getScrollParent(this._popper);
3903
- var offsetParentRect = getOffsetRect(offsetParent);
3904
-
3905
- // Thanks the fucking native API, `document.body.scrollTop` & `document.documentElement.scrollTop`
3906
- var getScrollTopValue = function (element) {
3907
- return element == document.body
3908
- ? Math.max(
3909
- document.documentElement.scrollTop,
3910
- document.body.scrollTop
3911
- )
3912
- : element.scrollTop;
3913
- };
3914
- var getScrollLeftValue = function (element) {
3915
- return element == document.body
3916
- ? Math.max(
3917
- document.documentElement.scrollLeft,
3918
- document.body.scrollLeft
3919
- )
3920
- : element.scrollLeft;
3921
- };
3922
-
3923
- // if the popper is fixed we don't have to substract scrolling from the boundaries
3924
- var scrollTop =
3925
- data.offsets.popper.position === 'fixed'
3926
- ? 0
3927
- : getScrollTopValue(scrollParent);
3928
- var scrollLeft =
3899
+ // 将真实 window 的视口换算到 popper 所在包含块的坐标系。
3900
+ // 无界等场景下沙箱 window 的尺寸、shadowRoot 内元素的 scrollTop 均不可靠,
3901
+ // 统一从元素自身的 view 与真实包含块获取
3902
+ var realWindow = getRealWindow(this._popper);
3903
+ var containingBlockRect = getContainingBlockRect(
3904
+ this._popper,
3929
3905
  data.offsets.popper.position === 'fixed'
3930
- ? 0
3931
- : getScrollLeftValue(scrollParent);
3906
+ );
3932
3907
 
3933
3908
  boundaries = {
3934
- top: 0 - (offsetParentRect.top - scrollTop),
3909
+ top: 0 - containingBlockRect.top,
3935
3910
  right:
3936
- root.document.documentElement.clientWidth -
3937
- (offsetParentRect.left - scrollLeft),
3911
+ realWindow.document.documentElement.clientWidth -
3912
+ containingBlockRect.left,
3938
3913
  bottom:
3939
- root.document.documentElement.clientHeight -
3940
- (offsetParentRect.top - scrollTop),
3941
- left: 0 - (offsetParentRect.left - scrollLeft)
3914
+ realWindow.document.documentElement.clientHeight -
3915
+ containingBlockRect.top,
3916
+ left: 0 - containingBlockRect.left
3942
3917
  };
3943
3918
  } else {
3944
3919
  if (getOffsetParent(this._popper) === boundariesElement) {
@@ -4406,7 +4381,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4406
4381
  element.style.visibility = 'hidden';
4407
4382
  var calcWidthToForceRepaint = element.offsetWidth;
4408
4383
  // original method
4409
- var styles = root.getComputedStyle(element);
4384
+ var styles = getRealWindow(element).getComputedStyle(element);
4410
4385
  var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
4411
4386
  var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
4412
4387
  var result = {
@@ -4477,9 +4452,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4477
4452
  */
4478
4453
  function getStyleComputedProperty(element, property) {
4479
4454
  // NOTE: 1 DOM access here
4480
- var css = root.getComputedStyle(element, null);
4455
+ // 无界等微前端场景下沙箱 window 与元素实际渲染所在 window 可能不一致,
4456
+ // 需使用元素自身的 view 读取计算样式,避免跨 document 读取到空值
4457
+ var css = getRealWindow(element).getComputedStyle(element, null);
4481
4458
  return css[property];
4482
4459
  }
4460
+
4483
4461
  /**
4484
4462
  * Returns the offset parent of the given element
4485
4463
  * @function
@@ -4494,6 +4472,68 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4494
4472
  : offsetParent;
4495
4473
  }
4496
4474
 
4475
+ /**
4476
+ * Returns the window the given element actually renders in.
4477
+ * 无界等微前端场景下组件代码运行在沙箱 window 中,而 DOM 实际渲染在
4478
+ * 主应用的 window(shadowRoot 内),滚动量、视口尺寸等必须取自元素自身的 view
4479
+ * @function
4480
+ * @ignore
4481
+ * @argument {Element} element
4482
+ * @returns {Window} window
4483
+ */
4484
+ function getRealWindow(element) {
4485
+ return (
4486
+ (element &&
4487
+ element.ownerDocument &&
4488
+ element.ownerDocument.defaultView) ||
4489
+ root
4490
+ );
4491
+ }
4492
+
4493
+ /**
4494
+ * Returns the viewport rect of the containing block actually used to position the popper.
4495
+ * 无界微前端等场景下 popper 被挂载进子应用的 shadowRoot,offsetParent 的兜底值
4496
+ * (documentElement)与浏览器真实的包含块不再重合,导致下拉框/提示框整体偏移
4497
+ * (偏移量恰为子应用容器在主应用中的位置),因此需要沿 composed tree 查找:
4498
+ * - fixed 定位:包含块为视口;
4499
+ * - absolute 定位:最近的 positioned 祖先元素(跨 shadowRoot 边界查找);
4500
+ * - 无 positioned 祖先:初始包含块,其视口原点为真实 window 滚动量的负值。
4501
+ * @function
4502
+ * @ignore
4503
+ * @argument {Element} element - popper element
4504
+ * @argument {Boolean} fixed - whether the popper is fixed positioned
4505
+ * @returns {Object} rect
4506
+ */
4507
+ function getContainingBlockRect(element, fixed) {
4508
+ if (fixed) {
4509
+ return { top: 0, left: 0, right: 0, bottom: 0 };
4510
+ }
4511
+
4512
+ var node = element.parentNode;
4513
+ while (node) {
4514
+ if (node.nodeType === 1) {
4515
+ if (getStyleComputedProperty(node, 'position') !== 'static') {
4516
+ return getBoundingClientRect(node);
4517
+ }
4518
+ } else if (node.nodeType === 11) {
4519
+ // 遇到 shadowRoot,跨边界从宿主元素继续向上查找
4520
+ node = node.host;
4521
+ continue;
4522
+ } else {
4523
+ break;
4524
+ }
4525
+ node = node.parentNode;
4526
+ }
4527
+
4528
+ var win = getRealWindow(element);
4529
+ return {
4530
+ top: -(win.pageYOffset || 0),
4531
+ left: -(win.pageXOffset || 0),
4532
+ right: 0,
4533
+ bottom: 0
4534
+ };
4535
+ }
4536
+
4497
4537
  /**
4498
4538
  * Returns the scrolling parent of the given element
4499
4539
  * @function
@@ -4503,18 +4543,20 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4503
4543
  */
4504
4544
  function getScrollParent(element) {
4505
4545
  var parent = element.parentNode;
4506
- if (!parent || parent.nodeType !== 1) {
4546
+ if (!parent) {
4507
4547
  return element;
4508
4548
  }
4509
4549
 
4510
- if (parent === root.document) {
4511
- // Firefox puts the scrollTOp value on `documentElement` instead of `body`, we then check which of them is
4512
- // greater than 0 and return the proper element
4513
- if (root.document.body.scrollTop || root.document.body.scrollLeft) {
4514
- return root.document.body;
4515
- } else {
4516
- return root.document.documentElement;
4517
- }
4550
+ if (parent.nodeType === 11) {
4551
+ // 无界等微前端场景 DOM 位于 shadowRoot 内,需跨边界从宿主元素继续向上查找,
4552
+ // 否则查找到 shadowRoot 即终止,滚动事件无法被监听
4553
+ return getScrollParent(parent.host);
4554
+ }
4555
+
4556
+ if (parent.nodeType !== 1) {
4557
+ // 到达 document,返回元素实际渲染所在的真实 window,
4558
+ // 保证 window 滚动时能触发位置更新
4559
+ return getRealWindow(element);
4518
4560
  }
4519
4561
 
4520
4562
  // Firefox want us to check `-x` and `-y` variations as well
@@ -4534,7 +4576,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4534
4576
  // fixes issue #65
4535
4577
  return parent;
4536
4578
  }
4537
- return getScrollParent(element.parentNode);
4579
+ return getScrollParent(parent);
4538
4580
  }
4539
4581
 
4540
4582
  /**
@@ -4552,9 +4594,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4552
4594
  if (getStyleComputedProperty(element, 'position') === 'fixed') {
4553
4595
  return true;
4554
4596
  }
4555
- return element.parentNode && element.parentNode.nodeType === 1
4556
- ? isFixed(element.parentNode)
4557
- : element;
4597
+ var parent = element.parentNode;
4598
+ if (parent && parent.nodeType === 11) {
4599
+ // 跨 shadowRoot 边界,从宿主元素继续向上判断
4600
+ parent = parent.host;
4601
+ }
4602
+ return parent && parent.nodeType === 1 ? isFixed(parent) : false;
4558
4603
  }
4559
4604
 
4560
4605
  /**
@@ -4670,15 +4715,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
4670
4715
  */
4671
4716
  function getOffsetRectRelativeToCustomParent(element, parent, fixed) {
4672
4717
  var elementRect = getBoundingClientRect(element);
4673
- var parentRect = getBoundingClientRect(parent);
4674
-
4675
- if (fixed) {
4676
- var scrollParent = getScrollParent(parent);
4677
- parentRect.top += scrollParent.scrollTop;
4678
- parentRect.bottom += scrollParent.scrollTop;
4679
- parentRect.left += scrollParent.scrollLeft;
4680
- parentRect.right += scrollParent.scrollLeft;
4681
- }
4718
+ // parent 为 popper 元素:取其真实包含块的视口 rect,
4719
+ // 避免无界 shadowRoot 等场景下包含块假设错误导致的整体偏移
4720
+ var parentRect = getContainingBlockRect(parent, fixed);
4682
4721
 
4683
4722
  var rect = {
4684
4723
  top: elementRect.top - parentRect.top,
package/lib/config/api.js CHANGED
@@ -279,7 +279,7 @@ var publishedLists = exports.publishedLists = '/main2/pageComponentConfig/listPu
279
279
  // 获取自定义配置详情
280
280
  var pageInfo = exports.pageInfo = '/main2/pageComponentConfig/info';
281
281
  // 获取自定义配置授权列表
282
- var pageGroup = exports.pageGroup = 'main2/pageComponentTarget/listByConfigIdAndTypeGroup';
282
+ var pageGroup = exports.pageGroup = '/main2/pageComponentTarget/listByConfigIdAndTypeGroup';
283
283
 
284
284
  // 保存自定义配置,发布也调这个接口但要加上字段status=1
285
285
  var pageSave = exports.pageSave = '/main2/pageComponentConfig/save';
package/lib/data-table.js CHANGED
@@ -4902,7 +4902,7 @@ var publishedLists = '/main2/pageComponentConfig/listPublished';
4902
4902
  // 获取自定义配置详情
4903
4903
  var pageInfo = '/main2/pageComponentConfig/info';
4904
4904
  // 获取自定义配置授权列表
4905
- var pageGroup = 'main2/pageComponentTarget/listByConfigIdAndTypeGroup';
4905
+ var pageGroup = '/main2/pageComponentTarget/listByConfigIdAndTypeGroup';
4906
4906
 
4907
4907
  // 保存自定义配置,发布也调这个接口但要加上字段status=1
4908
4908
  var pageSave = '/main2/pageComponentConfig/save';
@@ -10482,7 +10482,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
10482
10482
  //
10483
10483
  var referenceOffsets = getOffsetRectRelativeToCustomParent(
10484
10484
  reference,
10485
- getOffsetParent(popper),
10485
+ popper,
10486
10486
  isParentFixed
10487
10487
  );
10488
10488
 
@@ -10537,17 +10537,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
10537
10537
  Popper.prototype._setupEventListeners = function () {
10538
10538
  // NOTE: 1 DOM access here
10539
10539
  this.state.updateBound = this.update.bind(this);
10540
- root.addEventListener('resize', this.state.updateBound);
10540
+ // 无界等微前端场景下沙箱 window 不会触发 resize,需监听真实 window
10541
+ this.state.realWindow = getRealWindow(this._popper);
10542
+ this.state.realWindow.addEventListener('resize', this.state.updateBound);
10541
10543
  // if the boundariesElement is window we don't need to listen for the scroll event
10542
10544
  if (this._options.boundariesElement !== 'window') {
10543
10545
  var target = getScrollParent(this._reference);
10544
- // here it could be both `body` or `documentElement` thanks to Firefox, we then check both
10545
- if (
10546
- target === root.document.body ||
10547
- target === root.document.documentElement
10548
- ) {
10549
- target = root;
10550
- }
10551
10546
  target.addEventListener('scroll', this.state.updateBound);
10552
10547
  this.state.scrollTarget = target;
10553
10548
  }
@@ -10561,7 +10556,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
10561
10556
  */
10562
10557
  Popper.prototype._removeEventListeners = function () {
10563
10558
  // NOTE: 1 DOM access here
10564
- root.removeEventListener('resize', this.state.updateBound);
10559
+ (this.state.realWindow || root).removeEventListener(
10560
+ 'resize',
10561
+ this.state.updateBound
10562
+ );
10565
10563
  if (
10566
10564
  this._options.boundariesElement !== 'window' &&
10567
10565
  this.state.scrollTarget
@@ -10615,47 +10613,24 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
10615
10613
  left: 0
10616
10614
  };
10617
10615
  } else if (boundariesElement === 'viewport') {
10618
- var offsetParent = getOffsetParent(this._popper);
10619
- var scrollParent = getScrollParent(this._popper);
10620
- var offsetParentRect = getOffsetRect(offsetParent);
10621
-
10622
- // Thanks the fucking native API, `document.body.scrollTop` & `document.documentElement.scrollTop`
10623
- var getScrollTopValue = function (element) {
10624
- return element == document.body
10625
- ? Math.max(
10626
- document.documentElement.scrollTop,
10627
- document.body.scrollTop
10628
- )
10629
- : element.scrollTop;
10630
- };
10631
- var getScrollLeftValue = function (element) {
10632
- return element == document.body
10633
- ? Math.max(
10634
- document.documentElement.scrollLeft,
10635
- document.body.scrollLeft
10636
- )
10637
- : element.scrollLeft;
10638
- };
10639
-
10640
- // if the popper is fixed we don't have to substract scrolling from the boundaries
10641
- var scrollTop =
10642
- data.offsets.popper.position === 'fixed'
10643
- ? 0
10644
- : getScrollTopValue(scrollParent);
10645
- var scrollLeft =
10616
+ // 将真实 window 的视口换算到 popper 所在包含块的坐标系。
10617
+ // 无界等场景下沙箱 window 的尺寸、shadowRoot 内元素的 scrollTop 均不可靠,
10618
+ // 统一从元素自身的 view 与真实包含块获取
10619
+ var realWindow = getRealWindow(this._popper);
10620
+ var containingBlockRect = getContainingBlockRect(
10621
+ this._popper,
10646
10622
  data.offsets.popper.position === 'fixed'
10647
- ? 0
10648
- : getScrollLeftValue(scrollParent);
10623
+ );
10649
10624
 
10650
10625
  boundaries = {
10651
- top: 0 - (offsetParentRect.top - scrollTop),
10626
+ top: 0 - containingBlockRect.top,
10652
10627
  right:
10653
- root.document.documentElement.clientWidth -
10654
- (offsetParentRect.left - scrollLeft),
10628
+ realWindow.document.documentElement.clientWidth -
10629
+ containingBlockRect.left,
10655
10630
  bottom:
10656
- root.document.documentElement.clientHeight -
10657
- (offsetParentRect.top - scrollTop),
10658
- left: 0 - (offsetParentRect.left - scrollLeft)
10631
+ realWindow.document.documentElement.clientHeight -
10632
+ containingBlockRect.top,
10633
+ left: 0 - containingBlockRect.left
10659
10634
  };
10660
10635
  } else {
10661
10636
  if (getOffsetParent(this._popper) === boundariesElement) {
@@ -11123,7 +11098,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11123
11098
  element.style.visibility = 'hidden';
11124
11099
  var calcWidthToForceRepaint = element.offsetWidth;
11125
11100
  // original method
11126
- var styles = root.getComputedStyle(element);
11101
+ var styles = getRealWindow(element).getComputedStyle(element);
11127
11102
  var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
11128
11103
  var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
11129
11104
  var result = {
@@ -11194,9 +11169,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11194
11169
  */
11195
11170
  function getStyleComputedProperty(element, property) {
11196
11171
  // NOTE: 1 DOM access here
11197
- var css = root.getComputedStyle(element, null);
11172
+ // 无界等微前端场景下沙箱 window 与元素实际渲染所在 window 可能不一致,
11173
+ // 需使用元素自身的 view 读取计算样式,避免跨 document 读取到空值
11174
+ var css = getRealWindow(element).getComputedStyle(element, null);
11198
11175
  return css[property];
11199
11176
  }
11177
+
11200
11178
  /**
11201
11179
  * Returns the offset parent of the given element
11202
11180
  * @function
@@ -11211,6 +11189,68 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11211
11189
  : offsetParent;
11212
11190
  }
11213
11191
 
11192
+ /**
11193
+ * Returns the window the given element actually renders in.
11194
+ * 无界等微前端场景下组件代码运行在沙箱 window 中,而 DOM 实际渲染在
11195
+ * 主应用的 window(shadowRoot 内),滚动量、视口尺寸等必须取自元素自身的 view
11196
+ * @function
11197
+ * @ignore
11198
+ * @argument {Element} element
11199
+ * @returns {Window} window
11200
+ */
11201
+ function getRealWindow(element) {
11202
+ return (
11203
+ (element &&
11204
+ element.ownerDocument &&
11205
+ element.ownerDocument.defaultView) ||
11206
+ root
11207
+ );
11208
+ }
11209
+
11210
+ /**
11211
+ * Returns the viewport rect of the containing block actually used to position the popper.
11212
+ * 无界微前端等场景下 popper 被挂载进子应用的 shadowRoot,offsetParent 的兜底值
11213
+ * (documentElement)与浏览器真实的包含块不再重合,导致下拉框/提示框整体偏移
11214
+ * (偏移量恰为子应用容器在主应用中的位置),因此需要沿 composed tree 查找:
11215
+ * - fixed 定位:包含块为视口;
11216
+ * - absolute 定位:最近的 positioned 祖先元素(跨 shadowRoot 边界查找);
11217
+ * - 无 positioned 祖先:初始包含块,其视口原点为真实 window 滚动量的负值。
11218
+ * @function
11219
+ * @ignore
11220
+ * @argument {Element} element - popper element
11221
+ * @argument {Boolean} fixed - whether the popper is fixed positioned
11222
+ * @returns {Object} rect
11223
+ */
11224
+ function getContainingBlockRect(element, fixed) {
11225
+ if (fixed) {
11226
+ return { top: 0, left: 0, right: 0, bottom: 0 };
11227
+ }
11228
+
11229
+ var node = element.parentNode;
11230
+ while (node) {
11231
+ if (node.nodeType === 1) {
11232
+ if (getStyleComputedProperty(node, 'position') !== 'static') {
11233
+ return getBoundingClientRect(node);
11234
+ }
11235
+ } else if (node.nodeType === 11) {
11236
+ // 遇到 shadowRoot,跨边界从宿主元素继续向上查找
11237
+ node = node.host;
11238
+ continue;
11239
+ } else {
11240
+ break;
11241
+ }
11242
+ node = node.parentNode;
11243
+ }
11244
+
11245
+ var win = getRealWindow(element);
11246
+ return {
11247
+ top: -(win.pageYOffset || 0),
11248
+ left: -(win.pageXOffset || 0),
11249
+ right: 0,
11250
+ bottom: 0
11251
+ };
11252
+ }
11253
+
11214
11254
  /**
11215
11255
  * Returns the scrolling parent of the given element
11216
11256
  * @function
@@ -11220,18 +11260,20 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11220
11260
  */
11221
11261
  function getScrollParent(element) {
11222
11262
  var parent = element.parentNode;
11223
- if (!parent || parent.nodeType !== 1) {
11263
+ if (!parent) {
11224
11264
  return element;
11225
11265
  }
11226
11266
 
11227
- if (parent === root.document) {
11228
- // Firefox puts the scrollTOp value on `documentElement` instead of `body`, we then check which of them is
11229
- // greater than 0 and return the proper element
11230
- if (root.document.body.scrollTop || root.document.body.scrollLeft) {
11231
- return root.document.body;
11232
- } else {
11233
- return root.document.documentElement;
11234
- }
11267
+ if (parent.nodeType === 11) {
11268
+ // 无界等微前端场景 DOM 位于 shadowRoot 内,需跨边界从宿主元素继续向上查找,
11269
+ // 否则查找到 shadowRoot 即终止,滚动事件无法被监听
11270
+ return getScrollParent(parent.host);
11271
+ }
11272
+
11273
+ if (parent.nodeType !== 1) {
11274
+ // 到达 document,返回元素实际渲染所在的真实 window,
11275
+ // 保证 window 滚动时能触发位置更新
11276
+ return getRealWindow(element);
11235
11277
  }
11236
11278
 
11237
11279
  // Firefox want us to check `-x` and `-y` variations as well
@@ -11251,7 +11293,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11251
11293
  // fixes issue #65
11252
11294
  return parent;
11253
11295
  }
11254
- return getScrollParent(element.parentNode);
11296
+ return getScrollParent(parent);
11255
11297
  }
11256
11298
 
11257
11299
  /**
@@ -11269,9 +11311,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11269
11311
  if (getStyleComputedProperty(element, 'position') === 'fixed') {
11270
11312
  return true;
11271
11313
  }
11272
- return element.parentNode && element.parentNode.nodeType === 1
11273
- ? isFixed(element.parentNode)
11274
- : element;
11314
+ var parent = element.parentNode;
11315
+ if (parent && parent.nodeType === 11) {
11316
+ // 跨 shadowRoot 边界,从宿主元素继续向上判断
11317
+ parent = parent.host;
11318
+ }
11319
+ return parent && parent.nodeType === 1 ? isFixed(parent) : false;
11275
11320
  }
11276
11321
 
11277
11322
  /**
@@ -11387,15 +11432,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11387
11432
  */
11388
11433
  function getOffsetRectRelativeToCustomParent(element, parent, fixed) {
11389
11434
  var elementRect = getBoundingClientRect(element);
11390
- var parentRect = getBoundingClientRect(parent);
11391
-
11392
- if (fixed) {
11393
- var scrollParent = getScrollParent(parent);
11394
- parentRect.top += scrollParent.scrollTop;
11395
- parentRect.bottom += scrollParent.scrollTop;
11396
- parentRect.left += scrollParent.scrollLeft;
11397
- parentRect.right += scrollParent.scrollLeft;
11398
- }
11435
+ // parent 为 popper 元素:取其真实包含块的视口 rect,
11436
+ // 避免无界 shadowRoot 等场景下包含块假设错误导致的整体偏移
11437
+ var parentRect = getContainingBlockRect(parent, fixed);
11399
11438
 
11400
11439
  var rect = {
11401
11440
  top: elementRect.top - parentRect.top,