@flexem/fc-gui 3.0.0-alpha.187 → 3.0.0-alpha.189

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.
@@ -42487,6 +42487,174 @@ C140,111.8,99.2,158.4,78,178.6z M78,40.4c-17.8,0-32.4,14.4-32.4,32.2s14.5,32.2,3
42487
42487
  }
42488
42488
  }
42489
42489
 
42490
+ // CONCATENATED MODULE: ./.tmp/elements/alarm/alarm-table-scrollbar.ts
42491
+ /** SVG scrollbar overlays the table bounds but stays outside foreignObject for WKWebView scaling. */
42492
+ class AlarmTableScrollbar {
42493
+ constructor(parent, x, y, width, height, visibleRows, onChange, onPause, onResume) {
42494
+ this.y = y;
42495
+ this.height = height;
42496
+ this.visibleRows = visibleRows;
42497
+ this.onChange = onChange;
42498
+ this.onPause = onPause;
42499
+ this.onResume = onResume;
42500
+ this.maxStart = 0;
42501
+ this.start = 0;
42502
+ this.thumbHeight = 0;
42503
+ this.thumbTop = 0;
42504
+ this.dragging = false;
42505
+ this.hovered = false;
42506
+ this.dragStartY = 0;
42507
+ this.dragStartRow = 0;
42508
+ this.handleStart = (event) => {
42509
+ if (!this.maxStart || ('button' in event && event.button !== 0) || ('touches' in event && event.touches.length !== 1))
42510
+ return;
42511
+ event.preventDefault();
42512
+ event.stopPropagation();
42513
+ this.onPause();
42514
+ const localY = this.getLocalY(event);
42515
+ // The full gutter is clickable, including the transparent sides of the thumb.
42516
+ if (localY < this.y + this.thumbTop || localY > this.y + this.thumbTop + this.thumbHeight) {
42517
+ this.onChange(this.start + (localY < this.y + this.thumbTop ? -this.visibleRows : this.visibleRows));
42518
+ this.onResume();
42519
+ return;
42520
+ }
42521
+ this.dragging = true;
42522
+ this.dragStartY = localY;
42523
+ this.dragStartRow = this.start;
42524
+ this.thumb.setAttribute('fill', '#8f99aa');
42525
+ this.thumb.style.cursor = 'grabbing';
42526
+ this.ownerDocument.addEventListener('mousemove', this.handleMove);
42527
+ this.ownerDocument.addEventListener('mouseup', this.handleEnd);
42528
+ this.ownerDocument.addEventListener('touchmove', this.handleMove, { passive: false });
42529
+ this.ownerDocument.addEventListener('touchend', this.handleEnd);
42530
+ this.ownerDocument.addEventListener('touchcancel', this.handleEnd);
42531
+ this.ownerDocument.defaultView.addEventListener('blur', this.handleEnd);
42532
+ };
42533
+ this.handleMove = (event) => {
42534
+ if (!this.dragging || ('touches' in event && event.touches.length !== 1))
42535
+ return;
42536
+ event.preventDefault();
42537
+ event.stopPropagation();
42538
+ const travel = this.height - this.thumbHeight;
42539
+ if (travel <= 0)
42540
+ return;
42541
+ const rowDelta = Math.round((this.getLocalY(event) - this.dragStartY) / travel * this.maxStart);
42542
+ this.onChange(this.dragStartRow + rowDelta);
42543
+ };
42544
+ this.handleEnd = () => {
42545
+ if (!this.dragging)
42546
+ return;
42547
+ this.dragging = false;
42548
+ this.unbindDrag();
42549
+ this.thumb.setAttribute('fill', '#b6bdc9');
42550
+ this.thumb.style.cursor = 'grab';
42551
+ this.onResume();
42552
+ };
42553
+ this.handleLeave = () => {
42554
+ this.hovered = false;
42555
+ this.onResume();
42556
+ };
42557
+ this.handleEnter = () => {
42558
+ if (!this.supportsMouseHover())
42559
+ return;
42560
+ this.hovered = true;
42561
+ this.onPause();
42562
+ };
42563
+ this.handleKeyDown = (event) => {
42564
+ const targets = {
42565
+ ArrowUp: this.start - 1,
42566
+ ArrowDown: this.start + 1,
42567
+ PageUp: this.start - this.visibleRows,
42568
+ PageDown: this.start + this.visibleRows,
42569
+ Home: 0,
42570
+ End: this.maxStart
42571
+ };
42572
+ if (!(event.key in targets))
42573
+ return;
42574
+ event.preventDefault();
42575
+ event.stopPropagation();
42576
+ this.onChange(targets[event.key]);
42577
+ };
42578
+ this.ownerDocument = parent.ownerDocument;
42579
+ this.group = this.createElement('g');
42580
+ this.group.setAttribute('role', 'scrollbar');
42581
+ this.group.setAttribute('aria-orientation', 'vertical');
42582
+ this.group.setAttribute('aria-valuemin', '0');
42583
+ this.group.setAttribute('tabindex', '0');
42584
+ this.group.style.cursor = 'default';
42585
+ this.track = this.createElement('rect');
42586
+ this.setRect(this.track, x, y, width, height);
42587
+ this.track.setAttribute('fill', '#eef0f4');
42588
+ this.track.setAttribute('rx', '0');
42589
+ this.thumb = this.createElement('rect');
42590
+ this.setRect(this.thumb, x + width / 4, y, width / 2, height);
42591
+ this.thumb.setAttribute('fill', '#b6bdc9');
42592
+ this.thumb.setAttribute('rx', String(width / 4));
42593
+ this.thumb.style.cursor = 'grab';
42594
+ this.group.appendChild(this.track);
42595
+ this.group.appendChild(this.thumb);
42596
+ parent.appendChild(this.group);
42597
+ this.group.addEventListener('mousedown', this.handleStart);
42598
+ this.group.addEventListener('touchstart', this.handleStart, { passive: false });
42599
+ this.group.addEventListener('keydown', this.handleKeyDown);
42600
+ this.group.addEventListener('mouseenter', this.handleEnter);
42601
+ this.group.addEventListener('mouseleave', this.handleLeave);
42602
+ }
42603
+ get isInteracting() {
42604
+ return this.dragging || this.hovered;
42605
+ }
42606
+ update(start, totalRows) {
42607
+ this.maxStart = Math.max(0, totalRows - this.visibleRows);
42608
+ this.start = Math.min(this.maxStart, Math.max(0, start));
42609
+ this.group.setAttribute('display', this.maxStart ? 'inline' : 'none');
42610
+ this.group.setAttribute('aria-valuemax', String(this.maxStart));
42611
+ this.group.setAttribute('aria-valuenow', String(this.start));
42612
+ this.thumbHeight = Math.min(this.height, Math.max(20, this.height * this.visibleRows / Math.max(1, totalRows)));
42613
+ this.thumbTop = this.maxStart ? (this.height - this.thumbHeight) * this.start / this.maxStart : 0;
42614
+ this.thumb.setAttribute('height', String(this.thumbHeight));
42615
+ this.thumb.setAttribute('y', String(this.y + this.thumbTop));
42616
+ }
42617
+ dispose() {
42618
+ this.dragging = false;
42619
+ this.unbindDrag();
42620
+ this.group.removeEventListener('mousedown', this.handleStart);
42621
+ this.group.removeEventListener('touchstart', this.handleStart);
42622
+ this.group.removeEventListener('keydown', this.handleKeyDown);
42623
+ this.group.removeEventListener('mouseenter', this.handleEnter);
42624
+ this.group.removeEventListener('mouseleave', this.handleLeave);
42625
+ this.group.remove();
42626
+ }
42627
+ createElement(name) {
42628
+ return this.ownerDocument.createElementNS('http://www.w3.org/2000/svg', name);
42629
+ }
42630
+ setRect(rect, x, y, width, height) {
42631
+ rect.setAttribute('x', String(x));
42632
+ rect.setAttribute('y', String(y));
42633
+ rect.setAttribute('width', String(width));
42634
+ rect.setAttribute('height', String(height));
42635
+ }
42636
+ getLocalY(event) {
42637
+ const pointer = 'touches' in event ? event.touches[0] : event;
42638
+ const point = this.group.ownerSVGElement.createSVGPoint();
42639
+ point.x = pointer.clientX;
42640
+ point.y = pointer.clientY;
42641
+ const matrix = this.group.getScreenCTM();
42642
+ return matrix ? point.matrixTransform(matrix.inverse()).y : point.y;
42643
+ }
42644
+ unbindDrag() {
42645
+ this.ownerDocument.removeEventListener('mousemove', this.handleMove);
42646
+ this.ownerDocument.removeEventListener('mouseup', this.handleEnd);
42647
+ this.ownerDocument.removeEventListener('touchmove', this.handleMove);
42648
+ this.ownerDocument.removeEventListener('touchend', this.handleEnd);
42649
+ this.ownerDocument.removeEventListener('touchcancel', this.handleEnd);
42650
+ this.ownerDocument.defaultView.removeEventListener('blur', this.handleEnd);
42651
+ }
42652
+ supportsMouseHover() {
42653
+ const view = this.ownerDocument.defaultView;
42654
+ return !!view && (!view.matchMedia || view.matchMedia('(hover: hover) and (pointer: fine)').matches);
42655
+ }
42656
+ }
42657
+
42490
42658
  // CONCATENATED MODULE: ./.tmp/elements/alarm/alarm-element.ts
42491
42659
 
42492
42660
 
@@ -42494,6 +42662,7 @@ C140,111.8,99.2,158.4,78,178.6z M78,40.4c-17.8,0-32.4,14.4-32.4,32.2s14.5,32.2,3
42494
42662
 
42495
42663
 
42496
42664
 
42665
+
42497
42666
  var AlaertElementStatus;
42498
42667
  (function (AlaertElementStatus) {
42499
42668
  AlaertElementStatus[AlaertElementStatus["Normal"] = 0] = "Normal";
@@ -42532,97 +42701,62 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
42532
42701
  this.rowHeight = 0;
42533
42702
  this.touchStartY = 0;
42534
42703
  this.touchScrollAccumulator = 0;
42535
- this.thumbDragStartY = 0;
42536
- this.thumbDragStartWindow = 0;
42537
- this.thumbDragging = false;
42704
+ this.scrollHovered = false;
42705
+ this.touchScrolling = false;
42538
42706
  this.isDisposed = false;
42539
42707
  this.handleScrollWheel = (event) => {
42540
- if (!this.rowHeight)
42708
+ if (!this.rowHeight || !this.getMaxWindowStart())
42541
42709
  return;
42542
42710
  event.preventDefault();
42543
- this.touchScrollAccumulator += event.deltaY;
42544
- const rowDelta = Math.trunc(this.touchScrollAccumulator / this.rowHeight);
42711
+ event.stopPropagation();
42712
+ const screenRowHeight = this.getScreenRowHeight();
42713
+ const delta = event.deltaMode === 1 ? event.deltaY * screenRowHeight
42714
+ : event.deltaMode === 2 ? event.deltaY * screenRowHeight * this.maxVisibleRows : event.deltaY;
42715
+ this.touchScrollAccumulator += delta;
42716
+ const rowDelta = Math.trunc(this.touchScrollAccumulator / screenRowHeight);
42545
42717
  if (rowDelta !== 0) {
42546
- this.touchScrollAccumulator -= rowDelta * this.rowHeight;
42718
+ this.touchScrollAccumulator -= rowDelta * screenRowHeight;
42547
42719
  this.moveScrollWindowBy(rowDelta);
42548
42720
  }
42549
42721
  };
42550
42722
  this.handleScrollTouchStart = (event) => {
42723
+ if (event.touches.length !== 1 || !this.getMaxWindowStart())
42724
+ return;
42725
+ this.touchScrolling = true;
42726
+ clearInterval(this.scrollIntervalId);
42727
+ event.stopPropagation();
42551
42728
  this.touchStartY = event.touches[0].clientY;
42552
42729
  this.touchScrollAccumulator = 0;
42553
42730
  };
42554
42731
  this.handleScrollTouchMove = (event) => {
42555
- if (!this.rowHeight)
42732
+ if (!this.touchScrolling || event.touches.length !== 1)
42556
42733
  return;
42557
42734
  event.preventDefault();
42735
+ event.stopPropagation();
42558
42736
  const currentY = event.touches[0].clientY;
42559
42737
  const deltaY = this.touchStartY - currentY;
42560
42738
  this.touchStartY = currentY;
42561
42739
  this.touchScrollAccumulator += deltaY;
42562
- const rowDelta = Math.trunc(this.touchScrollAccumulator / this.rowHeight);
42740
+ const screenRowHeight = this.getScreenRowHeight();
42741
+ const rowDelta = Math.trunc(this.touchScrollAccumulator / screenRowHeight);
42563
42742
  if (rowDelta !== 0) {
42564
- this.touchScrollAccumulator -= rowDelta * this.rowHeight;
42743
+ this.touchScrollAccumulator -= rowDelta * screenRowHeight;
42565
42744
  this.moveScrollWindowBy(rowDelta);
42566
42745
  }
42567
42746
  };
42568
42747
  this.handleScrollMouseEnter = () => {
42748
+ if (!this.supportsMouseHover())
42749
+ return;
42750
+ this.scrollHovered = true;
42569
42751
  clearInterval(this.scrollIntervalId);
42570
42752
  };
42571
42753
  this.handleScrollMouseLeave = () => {
42572
- if (!this.thumbDragging)
42573
- this.startAutoScroll();
42574
- };
42575
- // 拖拽滑块时挂全局 mousemove/mouseup,允许拖出滚动条区域也能继续跟手,松开时才解绑
42576
- this.handleThumbDragStart = (event) => {
42577
- event.preventDefault();
42578
- event.stopPropagation();
42579
- this.thumbDragging = true;
42580
- clearInterval(this.scrollIntervalId);
42581
- this.thumbDragStartY = this.getClientY(event);
42582
- this.thumbDragStartWindow = this.scrollWindowStart;
42583
- document.addEventListener('mousemove', this.handleThumbDragMove);
42584
- document.addEventListener('mouseup', this.handleThumbDragEnd);
42585
- document.addEventListener('touchmove', this.handleThumbDragMove, { passive: false });
42586
- document.addEventListener('touchend', this.handleThumbDragEnd);
42587
- };
42588
- this.handleThumbDragMove = (event) => {
42589
- if (!this.thumbDragging || !this.scrollTrack)
42590
- return;
42591
- event.preventDefault();
42592
- const maxWindowStart = Math.max(0, this.pageSize - this.maxVisibleRows);
42593
- if (maxWindowStart <= 0)
42594
- return;
42595
- const trackHeight = this.scrollTrack.clientHeight;
42596
- const thumbHeightRatio = Math.min(1, this.maxVisibleRows / this.pageSize);
42597
- const thumbHeight = Math.max(20, trackHeight * thumbHeightRatio);
42598
- const maxThumbTop = trackHeight - thumbHeight;
42599
- if (maxThumbTop <= 0)
42600
- return;
42601
- const deltaY = this.getClientY(event) - this.thumbDragStartY;
42602
- const deltaWindow = Math.round((deltaY / maxThumbTop) * maxWindowStart);
42603
- const nextStart = Math.min(maxWindowStart, Math.max(0, this.thumbDragStartWindow + deltaWindow));
42604
- if (nextStart === this.scrollWindowStart)
42605
- return;
42606
- this.scrollWindowStart = nextStart;
42607
- this.renderScrollWindow(this.scrollWindowStart);
42608
- };
42609
- this.handleThumbDragEnd = () => {
42610
- this.thumbDragging = false;
42611
- document.removeEventListener('mousemove', this.handleThumbDragMove);
42612
- document.removeEventListener('mouseup', this.handleThumbDragEnd);
42613
- document.removeEventListener('touchmove', this.handleThumbDragMove);
42614
- document.removeEventListener('touchend', this.handleThumbDragEnd);
42754
+ this.scrollHovered = false;
42615
42755
  this.startAutoScroll();
42616
42756
  };
42617
- // 点击轨道空白处(非滑块)时整页跳转,方向取决于点击位置在滑块上方还是下方
42618
- this.handleTrackClick = (event) => {
42619
- if (event.target !== this.scrollTrack || !this.scrollTrack)
42620
- return;
42621
- const trackRect = this.scrollTrack.getBoundingClientRect();
42622
- const clickTop = event.clientY - trackRect.top;
42623
- const thumbTop = parseFloat(this.scrollThumb.style.top) || 0;
42624
- const rowDelta = clickTop < thumbTop ? -this.maxVisibleRows : this.maxVisibleRows;
42625
- this.moveScrollWindowBy(rowDelta);
42757
+ this.handleScrollTouchEnd = () => {
42758
+ this.touchScrolling = false;
42759
+ this.startAutoScroll();
42626
42760
  };
42627
42761
  this.rootElement.selectAll('*').remove();
42628
42762
  this.setStatusAsLoading();
@@ -42905,7 +43039,7 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
42905
43039
  if (useScroll) {
42906
43040
  if (!this.scrollContent)
42907
43041
  return;
42908
- this.scrollWindowStart = Math.min(this.scrollWindowStart, Math.max(0, this.pageSize - this.maxVisibleRows));
43042
+ this.scrollWindowStart = Math.min(this.scrollWindowStart, this.getMaxWindowStart());
42909
43043
  this.renderScrollWindow(this.scrollWindowStart);
42910
43044
  return;
42911
43045
  }
@@ -42940,24 +43074,12 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
42940
43074
  }
42941
43075
  this.updateScrollThumb();
42942
43076
  }
42943
- // 滑块高度按"可见行数/总行数"的比例算,位置按当前窗口起始行占可滚动范围的比例算,
42944
- // 只用 top/height 两个数值属性更新,不涉及 transform,不会触发合成层
42945
43077
  updateScrollThumb() {
42946
- if (!this.scrollTrack || !this.scrollThumb)
42947
- return;
42948
- const maxWindowStart = Math.max(0, this.pageSize - this.maxVisibleRows);
42949
- if (maxWindowStart <= 0) {
42950
- this.scrollThumb.style.display = 'none';
42951
- return;
42952
- }
42953
- this.scrollThumb.style.display = 'block';
42954
- const trackHeight = this.scrollTrack.clientHeight;
42955
- const thumbHeightRatio = Math.min(1, this.maxVisibleRows / this.pageSize);
42956
- const thumbHeight = Math.max(20, trackHeight * thumbHeightRatio);
42957
- const maxThumbTop = trackHeight - thumbHeight;
42958
- const thumbTop = maxThumbTop * (this.scrollWindowStart / maxWindowStart);
42959
- this.scrollThumb.style.height = `${thumbHeight}px`;
42960
- this.scrollThumb.style.top = `${thumbTop}px`;
43078
+ if (this.scrollbar)
43079
+ this.scrollbar.update(this.scrollWindowStart, this.pageSize);
43080
+ }
43081
+ getMaxWindowStart() {
43082
+ return Math.max(0, this.pageSize - this.maxVisibleRows);
42961
43083
  }
42962
43084
  getIconScale() {
42963
43085
  const initSize = this.model.initSize;
@@ -43006,7 +43128,7 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43006
43128
  vertical-align: middle;`;
43007
43129
  for (let col = 0; col < 4; col++) {
43008
43130
  const th = document.createElement('th');
43009
- th.innerHTML = this.getHeaderTextByColumn(col);
43131
+ th.textContent = this.getHeaderTextByColumn(col);
43010
43132
  th.style.cssText = `width: ${this.model.widths[col] / this.model.size.width * 100}%;
43011
43133
  border-style: solid;
43012
43134
  border-color: ${this.model.generalSetting.splitLine};
@@ -43033,7 +43155,7 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43033
43155
  border-left-width: ${!col || this.model.generalSetting.isHiddenColumnSplitLine ? 0 : 1}px;`;
43034
43156
  if (this.alarmList[row]) {
43035
43157
  if (col !== 2) {
43036
- td.innerHTML = this.alarmList[row][col];
43158
+ td.textContent = this.alarmList[row][col];
43037
43159
  td.style.cssText += `${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
43038
43160
  }
43039
43161
  else {
@@ -43052,14 +43174,14 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43052
43174
  border-radius: 5px;
43053
43175
  background: ${levelColors[this.alarmList[row][col]]};
43054
43176
  color: #ffffff;
43055
- width: ${this.model.widths[col] - 30}px;
43177
+ width: calc(100% - 30px);
43056
43178
  height: ${alarmHeight}px;
43057
43179
  max-height: ${rowHeight}px;
43058
43180
  display: flex;
43059
43181
  justify-content: center;
43060
43182
  align-items: center;
43061
43183
  ${this.model.generalSetting.isUnderline ? 'text-decoration: underline' : ''};`;
43062
- alarmLevel.innerHTML = this.model.levelText[this.alarmList[row][col]];
43184
+ alarmLevel.textContent = this.model.levelText[this.alarmList[row][col]];
43063
43185
  td.appendChild(alarmLevel);
43064
43186
  }
43065
43187
  }
@@ -43099,40 +43221,27 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43099
43221
  const dataRowHeight = this.model.heights[1] || this.model.heights[0];
43100
43222
  this.rowHeight = dataRowHeight;
43101
43223
  this.scrollWindowStart = 0;
43102
- // 之前用"表头/表体分两个 table + flex 包裹容器 + overflow/transform 滚动"的结构,
43103
- // 在 iOS WKWebView 上表体会明显放大错位,换了两种滚动实现方式(原生 overflow:auto、
43104
- // JS transform 平移)都复现同样的问题,怀疑是这套多层 div + 双 table 结构本身的问题。
43105
- // 这里改成和 renderPlainTable() 完全同构的单 table 结构(已验证在所有平台上都正常),
43106
- // DOM 里始终只保留 maxVisibleRows 行数据,滚动时只增删 <tr> 内容,不做任何位移/滚动。
43107
- // 自定义滚动条(轨道+滑块)只用 position + top/height 定位,不用 overflow/transform/
43108
- // will-change,这些属性都不会触发 WebKit 合成层提升,不会重新引入 iOS 缩放错位问题。
43109
- const scrollbarWidth = 6;
43110
- const wrapper = document.createElement('div');
43111
- wrapper.style.cssText = `position: relative; width: ${this.model.size.width}px;
43112
- height: ${elementHeight - operationAreaReservedHeight}px;`;
43224
+ // WKWebView can paint positioned HTML descendants outside the SVG scale.
43225
+ // Keep a single unpositioned table directly in foreignObject. The sibling
43226
+ // SVG scrollbar overlays the table's right edge without an HTML scrolling layer.
43227
+ const scrollbarWidth = Math.min(12, this.model.size.width * 0.04);
43228
+ const tableHeight = elementHeight - operationAreaReservedHeight;
43113
43229
  const table = document.createElement('table');
43114
43230
  table.style.cssText = `border: 2px solid ${this.model.generalSetting.stroke};
43115
- height: ${elementHeight - operationAreaReservedHeight}px;
43116
- width: calc(100% - ${scrollbarWidth}px);`;
43231
+ height: ${tableHeight}px; width: 100%; table-layout: fixed;
43232
+ overflow-wrap: break-word; -webkit-text-size-adjust: none; text-size-adjust: none;`;
43117
43233
  table.appendChild(this.buildHeaderRow());
43118
- wrapper.appendChild(table);
43119
- const track = document.createElement('div');
43120
- track.style.cssText = `position: absolute; top: 0; right: 0; width: ${scrollbarWidth}px;
43121
- height: 100%; background: rgba(0,0,0,0.06); border-radius: ${scrollbarWidth / 2}px;`;
43122
- const thumb = document.createElement('div');
43123
- thumb.style.cssText = `position: absolute; left: 0; width: 100%;
43124
- background: rgba(0,0,0,0.35); border-radius: ${scrollbarWidth / 2}px; cursor: pointer;`;
43125
- track.appendChild(thumb);
43126
- wrapper.appendChild(track);
43127
- this.element.appendChild(wrapper);
43234
+ this.element.appendChild(table);
43128
43235
  this.scrollContent = table;
43129
- this.scrollTrack = track;
43130
- this.scrollThumb = thumb;
43131
43236
  this.renderScrollWindow(0);
43237
+ const canvasScaleY = this.getCanvasScaleY();
43238
+ const renderedTableHeight = table.getBoundingClientRect().height / canvasScaleY || tableHeight;
43239
+ const renderedHeaderHeight = table.rows[0].getBoundingClientRect().height / canvasScaleY || this.model.heights[0];
43240
+ const scrollbarInset = 2;
43241
+ this.scrollbar = new AlarmTableScrollbar(this.element.parentNode, this.model.size.width - scrollbarWidth, renderedHeaderHeight + scrollbarInset, scrollbarWidth, Math.max(0, renderedTableHeight - renderedHeaderHeight - scrollbarInset * 2), this.maxVisibleRows, start => this.moveScrollWindowBy(start - this.scrollWindowStart), () => clearInterval(this.scrollIntervalId), () => this.startAutoScroll());
43132
43242
  this.updateScrollThumb();
43133
43243
  this.hoverTarget = table;
43134
43244
  this.bindScrollHoverEvents();
43135
- this.bindScrollbarEvents();
43136
43245
  this.startAutoScroll();
43137
43246
  }
43138
43247
  bindScrollHoverEvents() {
@@ -43144,10 +43253,16 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43144
43253
  this.hoverTarget.addEventListener('wheel', this.handleScrollWheel, { passive: false });
43145
43254
  this.hoverTarget.addEventListener('touchstart', this.handleScrollTouchStart, { passive: true });
43146
43255
  this.hoverTarget.addEventListener('touchmove', this.handleScrollTouchMove, { passive: false });
43256
+ this.hoverTarget.addEventListener('touchend', this.handleScrollTouchEnd);
43257
+ this.hoverTarget.addEventListener('touchcancel', this.handleScrollTouchEnd);
43147
43258
  }
43148
43259
  }
43149
43260
  unbindScrollHoverEvents() {
43150
- this.unbindScrollbarEvents();
43261
+ if (this.scrollbar)
43262
+ this.scrollbar.dispose();
43263
+ this.scrollbar = null;
43264
+ this.scrollHovered = false;
43265
+ this.touchScrolling = false;
43151
43266
  if (!this.hoverTarget)
43152
43267
  return;
43153
43268
  this.hoverTarget.removeEventListener('mouseenter', this.handleScrollMouseEnter);
@@ -43155,6 +43270,8 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43155
43270
  this.hoverTarget.removeEventListener('wheel', this.handleScrollWheel);
43156
43271
  this.hoverTarget.removeEventListener('touchstart', this.handleScrollTouchStart);
43157
43272
  this.hoverTarget.removeEventListener('touchmove', this.handleScrollTouchMove);
43273
+ this.hoverTarget.removeEventListener('touchend', this.handleScrollTouchEnd);
43274
+ this.hoverTarget.removeEventListener('touchcancel', this.handleScrollTouchEnd);
43158
43275
  this.hoverTarget = null;
43159
43276
  }
43160
43277
  // 手动滚动只在当前可见窗口范围内移动(不触发翻页),到顶/到底停住,
@@ -43162,41 +43279,31 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43162
43279
  moveScrollWindowBy(rowDelta) {
43163
43280
  if (!this.scrollContent)
43164
43281
  return;
43165
- const maxWindowStart = Math.max(0, this.pageSize - this.maxVisibleRows);
43282
+ const maxWindowStart = this.getMaxWindowStart();
43166
43283
  const nextStart = Math.min(maxWindowStart, Math.max(0, this.scrollWindowStart + rowDelta));
43167
43284
  if (nextStart === this.scrollWindowStart)
43168
43285
  return;
43169
43286
  this.scrollWindowStart = nextStart;
43170
43287
  this.renderScrollWindow(this.scrollWindowStart);
43171
43288
  }
43172
- bindScrollbarEvents() {
43173
- if (!this.scrollTrack || !this.scrollThumb)
43174
- return;
43175
- this.scrollThumb.addEventListener('mousedown', this.handleThumbDragStart);
43176
- this.scrollThumb.addEventListener('touchstart', this.handleThumbDragStart, { passive: true });
43177
- this.scrollTrack.addEventListener('mousedown', this.handleTrackClick);
43289
+ getCanvasScaleY() {
43290
+ const matrix = this.element.getScreenCTM();
43291
+ return matrix ? Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d) || 1 : 1;
43178
43292
  }
43179
- unbindScrollbarEvents() {
43180
- if (this.scrollThumb) {
43181
- this.scrollThumb.removeEventListener('mousedown', this.handleThumbDragStart);
43182
- this.scrollThumb.removeEventListener('touchstart', this.handleThumbDragStart);
43183
- }
43184
- if (this.scrollTrack) {
43185
- this.scrollTrack.removeEventListener('mousedown', this.handleTrackClick);
43186
- }
43187
- document.removeEventListener('mousemove', this.handleThumbDragMove);
43188
- document.removeEventListener('mouseup', this.handleThumbDragEnd);
43189
- document.removeEventListener('touchmove', this.handleThumbDragMove);
43190
- document.removeEventListener('touchend', this.handleThumbDragEnd);
43191
- this.scrollTrack = null;
43192
- this.scrollThumb = null;
43293
+ getScreenRowHeight() {
43294
+ var _a;
43295
+ const row = (_a = this.scrollContent) === null || _a === void 0 ? void 0 : _a.querySelectorAll('tr')[1];
43296
+ return (row === null || row === void 0 ? void 0 : row.getBoundingClientRect().height) || this.rowHeight * this.getCanvasScaleY();
43193
43297
  }
43194
- getClientY(event) {
43195
- return 'touches' in event ? event.touches[0].clientY : event.clientY;
43298
+ supportsMouseHover() {
43299
+ var _a, _b;
43300
+ const view = (_b = (_a = this.element) === null || _a === void 0 ? void 0 : _a.ownerDocument) === null || _b === void 0 ? void 0 : _b.defaultView;
43301
+ return !!view && (!view.matchMedia || view.matchMedia('(hover: hover) and (pointer: fine)').matches);
43196
43302
  }
43197
43303
  startAutoScroll() {
43304
+ var _a;
43198
43305
  clearInterval(this.scrollIntervalId);
43199
- if (!this.model.generalSetting.autoScroll)
43306
+ if (this.isDisposed || this.scrollHovered || this.touchScrolling || ((_a = this.scrollbar) === null || _a === void 0 ? void 0 : _a.isInteracting) || !this.model.generalSetting.autoScroll)
43200
43307
  return;
43201
43308
  const totalPages = Math.max(1, Math.ceil(this.totalCount / this.pageSize));
43202
43309
  if (totalPages <= 1 && !this.scrollContent)
@@ -43209,7 +43316,7 @@ class alarm_element_AlarmElement extends conditional_display_element_Conditional
43209
43316
  this.autoNextPage();
43210
43317
  return;
43211
43318
  }
43212
- const maxWindowStart = this.pageSize - this.maxVisibleRows;
43319
+ const maxWindowStart = this.getMaxWindowStart();
43213
43320
  if (maxWindowStart <= 0 || this.scrollWindowStart >= maxWindowStart) {
43214
43321
  this.autoNextPage();
43215
43322
  return;
@@ -45120,7 +45227,7 @@ var shared = __webpack_require__(6);
45120
45227
  // EXTERNAL MODULE: ./.tmp/view/view.service.ts
45121
45228
  var view_service = __webpack_require__(27);
45122
45229
 
45123
- // EXTERNAL MODULE: ./.tmp/gui/gui-view.ts + 126 modules
45230
+ // EXTERNAL MODULE: ./.tmp/gui/gui-view.ts + 127 modules
45124
45231
  var gui_view = __webpack_require__(32);
45125
45232
 
45126
45233
  // EXTERNAL MODULE: external "rxjs/operators"