@fusion.dev/helix-core 0.219.0 → 0.220.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.
@@ -194,6 +194,13 @@ export interface FilterDetail {
194
194
  /** What the list is being narrowed to. */
195
195
  value: string;
196
196
  }
197
+ /** Detail carried by `helix-found`. */
198
+ export interface FoundDetail {
199
+ /** How many matches the search found. */
200
+ count: number;
201
+ /** Which match is current, counting from 0, or -1 for none. */
202
+ index: number;
203
+ }
197
204
  /**
198
205
  * Detail carried by `helix-facet`.
199
206
  *
@@ -77,6 +77,7 @@ import { HelixExpandEvent } from './expand.js';
77
77
  import { HelixFacetEvent } from './facet.js';
78
78
  import { HelixFilterEvent } from './filter.js';
79
79
  import { HelixFilteredEvent } from './filtered.js';
80
+ import { HelixFoundEvent } from './found.js';
80
81
  import { HelixGraphFilterEvent } from './graph-filter.js';
81
82
  import { HelixGraphLayoutEvent } from './graph-layout.js';
82
83
  import { HelixGraphPanEvent } from './graph-pan.js';
@@ -140,9 +141,9 @@ import { HelixToggleEvent } from './toggle.js';
140
141
  import { HelixTourAskEvent } from './tour-ask.js';
141
142
  import { HelixTourStatusEvent } from './tour-status.js';
142
143
  import { HelixTypingEvent } from './typing.js';
143
- export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DeviceButton, DeviceButtonDetail, DeviceKeyDetail, DeviceScrollDetail, DeviceSwipeDetail, DeviceTapDetail, DeviceTextDetail, DeviceTouchDetail, DismissDetail, FacetDetail, FilterDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, ListenDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PasteDetail, PlotChangeDetail, PlotTurnDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, StrandsFallbackDetail, TerminalInputDetail, TerminalLinkDetail, TerminalResizeDetail, TerminalTitleDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
144
+ export type { ActivateDetail, AuraFallbackDetail, BandDetail, CanvasView, CaretDetail, ChangeDetail, CompleteDetail, ConnectDetail, ConsoleDetail, CopyDetail, CreateDetail, DeviceButton, DeviceButtonDetail, DeviceKeyDetail, DeviceScrollDetail, DeviceSwipeDetail, DeviceTapDetail, DeviceTextDetail, DeviceTouchDetail, DismissDetail, FacetDetail, FilterDetail, FoundDetail, GraphFilterDetail, GraphLayoutDetail, GraphPartChangeDetail, GraphSignalDetail, ListenDetail, MapClusterDetail, MapPanDetail, MapPartChangeDetail, MapRotateDetail, MapTiltDetail, MapZoomDetail, MoveDetail, NavigateDetail, OpenDetail, PasteDetail, PlotChangeDetail, PlotTurnDetail, PressDetail, PressPointerType, RangeDetail, ReadDetail, ReadingDetail, ReconnectDetail, Refusal, RefusedFile, RejectDetail, RelabelDetail, RemoveDetail, ReorderDetail, ResizeDetail, ScrolledDetail, SelectDetail, SendDetail, ShortcutDetail, SkipDetail, SortDetail, StrandsFallbackDetail, TerminalInputDetail, TerminalLinkDetail, TerminalResizeDetail, TerminalTitleDetail, ToggleDetail, TourAskDetail, TourStatusDetail, TypingDetail, ViewportPanDetail, ViewportZoomDetail, } from './details.js';
144
145
  export { helixEventNames } from './names.js';
145
- export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
146
+ export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixFoundEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
146
147
  /**
147
148
  * Every event class, and the one place a new one is registered: a class in a
148
149
  * module of its own, imported above, and named here and in `names.ts`.
@@ -205,6 +206,7 @@ declare const registry: {
205
206
  readonly HelixFacetEvent: typeof HelixFacetEvent;
206
207
  readonly HelixFilterEvent: typeof HelixFilterEvent;
207
208
  readonly HelixFilteredEvent: typeof HelixFilteredEvent;
209
+ readonly HelixFoundEvent: typeof HelixFoundEvent;
208
210
  readonly HelixGraphFilterEvent: typeof HelixGraphFilterEvent;
209
211
  readonly HelixGraphLayoutEvent: typeof HelixGraphLayoutEvent;
210
212
  readonly HelixGraphPanEvent: typeof HelixGraphPanEvent;
@@ -47,6 +47,7 @@ import { HelixExpandEvent } from './expand.js';
47
47
  import { HelixFacetEvent } from './facet.js';
48
48
  import { HelixFilterEvent } from './filter.js';
49
49
  import { HelixFilteredEvent } from './filtered.js';
50
+ import { HelixFoundEvent } from './found.js';
50
51
  import { HelixGraphFilterEvent } from './graph-filter.js';
51
52
  import { HelixGraphLayoutEvent } from './graph-layout.js';
52
53
  import { HelixGraphPanEvent } from './graph-pan.js';
@@ -111,7 +112,7 @@ import { HelixTourAskEvent } from './tour-ask.js';
111
112
  import { HelixTourStatusEvent } from './tour-status.js';
112
113
  import { HelixTypingEvent } from './typing.js';
113
114
  export { helixEventNames } from './names.js';
114
- export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
115
+ export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixFoundEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, };
115
116
  const registry = {
116
117
  HelixActionEvent,
117
118
  HelixActivateEvent,
@@ -162,6 +163,7 @@ const registry = {
162
163
  HelixFacetEvent,
163
164
  HelixFilterEvent,
164
165
  HelixFilteredEvent,
166
+ HelixFoundEvent,
165
167
  HelixGraphFilterEvent,
166
168
  HelixGraphLayoutEvent,
167
169
  HelixGraphPanEvent,
@@ -0,0 +1,14 @@
1
+ import type { FoundDetail } from './details.js';
2
+ /**
3
+ * A search found its matches, or moved among them, with how many there are
4
+ * and which is current.
5
+ *
6
+ * Sent by Find after each search and each move, and again when content that
7
+ * changed under an open search is searched again. Not cancelable: it reports
8
+ * matches already marked, as `helix-filtered` reports a list already
9
+ * narrowed.
10
+ */
11
+ export declare class HelixFoundEvent extends CustomEvent<FoundDetail> {
12
+ static readonly eventName = "helix-found";
13
+ constructor(detail: FoundDetail);
14
+ }
@@ -0,0 +1,11 @@
1
+ export class HelixFoundEvent extends CustomEvent {
2
+ static { this.eventName = 'helix-found'; }
3
+ constructor(detail) {
4
+ super(HelixFoundEvent.eventName, {
5
+ bubbles: true,
6
+ cancelable: false,
7
+ composed: true,
8
+ detail,
9
+ });
10
+ }
11
+ }
@@ -4,7 +4,7 @@ export const helixEventNames = new Set(('action activate aura-fallback band befo
4
4
  'canvas-edit canvas-pan canvas-view canvas-zoom caret clear collapse complete ' +
5
5
  'connect console copy copy-error create device-button device-key device-screenshot ' +
6
6
  'device-scroll device-swipe device-tap device-text device-touch dismiss edit end expand facet filter ' +
7
- 'filtered graph-filter graph-layout graph-pan graph-part-change graph-ready ' +
7
+ 'filtered found graph-filter graph-layout graph-pan graph-part-change graph-ready ' +
8
8
  'graph-signal graph-zoom history listen load load-more map-cluster map-pan map-part-change ' +
9
9
  'map-ready map-rotate map-tilt map-zoom move navigate next panel-resize pasted pin plot-change ' +
10
10
  'plot-turn press ' +
package/dist/index.d.ts CHANGED
@@ -41,7 +41,7 @@ export { UpgradeController, type UpgradeOptions, } from './controllers/upgrade-c
41
41
  export { type Rendered, VirtualizeController, type VirtualizeOptions, type Window as VirtualizeWindow, } from './controllers/virtualize-controller/virtualize-controller.js';
42
42
  export { Waterfall } from './controllers/virtualize-controller/waterfall.js';
43
43
  export { eventsForTag, registerElementEvents } from './events/element-events.js';
44
- export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DeviceButton, type DeviceButtonDetail, type DeviceKeyDetail, type DeviceScrollDetail, type DeviceSwipeDetail, type DeviceTapDetail, type DeviceTextDetail, type DeviceTouchDetail, type DismissDetail, type FacetDetail, type FilterDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type ListenDetail, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PasteDetail, type PlotChangeDetail, type PlotTurnDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type TerminalInputDetail, type TerminalLinkDetail, type TerminalResizeDetail, type TerminalTitleDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
44
+ export { type ActivateDetail, type AuraFallbackDetail, type BandDetail, type CanvasView, type CaretDetail, type ChangeDetail, type CompleteDetail, type ConnectDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DeviceButton, type DeviceButtonDetail, type DeviceKeyDetail, type DeviceScrollDetail, type DeviceSwipeDetail, type DeviceTapDetail, type DeviceTextDetail, type DeviceTouchDetail, type DismissDetail, type FacetDetail, type FilterDetail, type FoundDetail, type GraphFilterDetail, type GraphLayoutDetail, type GraphPartChangeDetail, type GraphSignalDetail, HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixFoundEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, type ListenDetail, type MapClusterDetail, type MapPanDetail, type MapPartChangeDetail, type MapRotateDetail, type MapTiltDetail, type MapZoomDetail, type MoveDetail, type NavigateDetail, type OpenDetail, type PasteDetail, type PlotChangeDetail, type PlotTurnDetail, type PressDetail, type PressPointerType, type RangeDetail, type ReadDetail, type ReadingDetail, type ReconnectDetail, type Refusal, type RefusedFile, type RejectDetail, type RelabelDetail, type RemoveDetail, type ReorderDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type StrandsFallbackDetail, type TerminalInputDetail, type TerminalLinkDetail, type TerminalResizeDetail, type TerminalTitleDetail, type ToggleDetail, type TourStatusDetail, type TypingDetail, type ViewportPanDetail, type ViewportZoomDetail, } from './events/events.js';
45
45
  export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
46
46
  export { LAYERS_RULE, MIRROR_RULE, SCROLLER_RULE, SPOKEN_RULE, TOUCHES_RULE, VIRTUAL_RULE, } from './helix-element/mark-rules.js';
47
47
  export { HelixFormElement } from './helix-form-element/helix-form-element.js';
@@ -100,6 +100,7 @@ export { type ElementByIdOptions, elementById, searchableById, } from './utils/e
100
100
  export { exportParts } from './utils/export-parts/export-parts.js';
101
101
  export { fillTemplate, labelWith } from './utils/fill-template/fill-template.js';
102
102
  export { FILTER_MARK, filterKeeps, markMatches, rangeOf, } from './utils/filter-marks/filter-marks.js';
103
+ export { FIND_CURRENT, FIND_MATCH, type FindDirection, type Finder, type FindQuery, type FindResult, findPattern, findRanges, findTextRanges, type TextFinderOptions, textFinder, } from './utils/find-text/find-text.js';
103
104
  export { focusTarget } from './utils/focus-target/focus-target.js';
104
105
  export { deepActiveElement, deepContains, focusableElements, PRESSABLE, pressedOwnControl, } from './utils/focusable-elements/focusable-elements.js';
105
106
  export { afterLinkFollowed, followLink, type LinkModifiers, type LinkTarget, } from './utils/follow-link/follow-link.js';
package/dist/index.js CHANGED
@@ -41,7 +41,7 @@ export { UpgradeController, } from './controllers/upgrade-controller/upgrade-con
41
41
  export { VirtualizeController, } from './controllers/virtualize-controller/virtualize-controller.js';
42
42
  export { Waterfall } from './controllers/virtualize-controller/waterfall.js';
43
43
  export { eventsForTag, registerElementEvents } from './events/element-events.js';
44
- export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
44
+ export { HelixActionEvent, HelixActivateEvent, HelixAuraFallbackEvent, HelixBandEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeListenEvent, HelixBeforeMoveEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePasteEvent, HelixBeforePinEvent, HelixBeforeReconnectEvent, HelixBeforeRelabelEvent, HelixBeforeReorderEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCanvasEditEvent, HelixCanvasPanEvent, HelixCanvasViewEvent, HelixCanvasZoomEvent, HelixCaretEvent, HelixClearEvent, HelixCollapseEvent, HelixCompleteEvent, HelixConnectEvent, HelixConsoleEvent, HelixCopyErrorEvent, HelixCopyEvent, HelixCreateEvent, HelixDeviceButtonEvent, HelixDeviceKeyEvent, HelixDeviceScreenshotEvent, HelixDeviceScrollEvent, HelixDeviceSwipeEvent, HelixDeviceTapEvent, HelixDeviceTextEvent, HelixDeviceTouchEvent, HelixDismissEvent, HelixEditEvent, HelixEndEvent, HelixExpandEvent, HelixFacetEvent, HelixFilterEvent, HelixFilteredEvent, HelixFoundEvent, HelixGraphFilterEvent, HelixGraphLayoutEvent, HelixGraphPanEvent, HelixGraphPartChangeEvent, HelixGraphReadyEvent, HelixGraphSignalEvent, HelixGraphZoomEvent, HelixHistoryEvent, HelixListenEvent, HelixLoadEvent, HelixLoadMoreEvent, HelixMapClusterEvent, HelixMapPanEvent, HelixMapPartChangeEvent, HelixMapReadyEvent, HelixMapRotateEvent, HelixMapTiltEvent, HelixMapZoomEvent, HelixMoveEvent, HelixNavigateEvent, HelixNextEvent, HelixPanelResizeEvent, HelixPastedEvent, HelixPinEvent, HelixPlotChangeEvent, HelixPlotTurnEvent, HelixPressEvent, HelixPreviewEvent, HelixPreviousEvent, HelixRangeChangeEvent, HelixReadEvent, HelixReadingChangeEvent, HelixReadingPressEvent, HelixReconnectEvent, HelixRejectEvent, HelixRelabelEvent, HelixRemoveEvent, HelixReorderEvent, HelixReorderedEvent, HelixResizedEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSelectedEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixSortedEvent, HelixSplitEvent, HelixStopEvent, HelixStrandsFallbackEvent, HelixTerminalBellEvent, HelixTerminalInputEvent, HelixTerminalLinkEvent, HelixTerminalResizeEvent, HelixTerminalRestartEvent, HelixTerminalTitleEvent, HelixToggleEvent, HelixTourAskEvent, HelixTourStatusEvent, HelixTypingEvent, } from './events/events.js';
45
45
  export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
46
46
  export { LAYERS_RULE, MIRROR_RULE, SCROLLER_RULE, SPOKEN_RULE, TOUCHES_RULE, VIRTUAL_RULE, } from './helix-element/mark-rules.js';
47
47
  export { HelixFormElement } from './helix-form-element/helix-form-element.js';
@@ -100,6 +100,7 @@ export { elementById, searchableById, } from './utils/element-by-id/element-by-i
100
100
  export { exportParts } from './utils/export-parts/export-parts.js';
101
101
  export { fillTemplate, labelWith } from './utils/fill-template/fill-template.js';
102
102
  export { FILTER_MARK, filterKeeps, markMatches, rangeOf, } from './utils/filter-marks/filter-marks.js';
103
+ export { FIND_CURRENT, FIND_MATCH, findPattern, findRanges, findTextRanges, textFinder, } from './utils/find-text/find-text.js';
103
104
  export { focusTarget } from './utils/focus-target/focus-target.js';
104
105
  export { deepActiveElement, deepContains, focusableElements, PRESSABLE, pressedOwnControl, } from './utils/focusable-elements/focusable-elements.js';
105
106
  export { afterLinkFollowed, followLink, } from './utils/follow-link/follow-link.js';
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Finding words in what a page shows, as ranges over its text, and painting
3
+ * them with the Custom Highlight API: the query every finder takes, and the
4
+ * finder Find uses for the content its `for` names.
5
+ *
6
+ * **Painted, and nothing is inserted.** The text is the page's own light DOM,
7
+ * often written by React or by another Helix family, and a `<mark>` wrapped
8
+ * around a match would be undone by the next render or would break it, as
9
+ * `filter-marks` explains for a filtered list.
10
+ */
11
+ /** What every match is painted as, in `CSS.highlights` and in `base.css`. */
12
+ export declare const FIND_MATCH = "helix-find-match";
13
+ /** What the current match is painted as, over the others. */
14
+ export declare const FIND_CURRENT = "helix-find-current";
15
+ /** The search Find hands a finder. */
16
+ export interface FindQuery {
17
+ /** Whether case has to match, so "Error" does not find "error". */
18
+ caseSensitive: boolean;
19
+ /** Whether `search` is a regular expression, in JavaScript's syntax. */
20
+ regex: boolean;
21
+ /** What Replace puts in place of a match. */
22
+ replace: string;
23
+ /** What the reader typed. */
24
+ search: string;
25
+ /** Whether a match has to be a whole word. */
26
+ wholeWord: boolean;
27
+ }
28
+ /** Where a search stands: how many matches, and which is current, counting from 0, or -1 for none. */
29
+ export interface FindResult {
30
+ count: number;
31
+ index: number;
32
+ }
33
+ /**
34
+ * Which match a search makes current. `first` stays on the current match
35
+ * where it still matches, as while the reader types, and otherwise takes the
36
+ * next one from there. `next` and `previous` move one match either way, and
37
+ * wrap around at the ends.
38
+ */
39
+ export type FindDirection = 'first' | 'next' | 'previous';
40
+ /**
41
+ * Whatever searches content for Find: the text finder Find makes for the
42
+ * content `for` names, or one a frame or a page attaches, as Terminal's
43
+ * emulator and Code Editor's engine are.
44
+ */
45
+ export interface Finder {
46
+ /** Takes away the marks a search drew, as Find closes or its field empties. */
47
+ end(): void;
48
+ /**
49
+ * Finds `query`, marks every match, and makes one current by `direction`.
50
+ * Returns where the search stands, or `undefined` from a finder that reports
51
+ * it later through the sink `attach` returned, as one that searches in a
52
+ * worker does.
53
+ */
54
+ find(query: FindQuery, direction: FindDirection): FindResult | undefined;
55
+ /**
56
+ * Replaces the current match, or every match with `all`, and returns where
57
+ * the search stands after. Find offers replacing only to a finder that has
58
+ * this.
59
+ */
60
+ replace?(query: FindQuery, all: boolean): FindResult | undefined;
61
+ }
62
+ /** The pattern a query reads as, or nothing for an empty search or a regular expression that cannot be read. */
63
+ export declare const findPattern: (query: FindQuery) => RegExp | undefined;
64
+ /** Where a query matches in a text, as `[from, to]` offsets, with no empty match. */
65
+ export declare const findRanges: (text: string, query: FindQuery) => Array<[number, number]>;
66
+ /**
67
+ * Every place the text under `root` matches `query`, as ranges in the order
68
+ * they come. A match may run across the elements inside one block, as
69
+ * "**bold** words" does, and never from one block into the next.
70
+ */
71
+ export declare const findTextRanges: (root: Element, query: FindQuery, skip?: string) => Range[];
72
+ /** What `textFinder` takes beside its root. */
73
+ export interface TextFinderOptions {
74
+ /**
75
+ * Called with where the search stands once the content has changed under
76
+ * it, as a log that keeps writing does. A search that `find` returned is
77
+ * not reported again here.
78
+ */
79
+ found?: ((result: FindResult) => void) | undefined;
80
+ /**
81
+ * Elements under the root whose text is not searched, as a selector, such
82
+ * as line numbers or the buttons beside each message.
83
+ */
84
+ skip?: string | undefined;
85
+ }
86
+ /**
87
+ * A finder over the text a reader sees under `root`, in its light DOM and
88
+ * what is slotted there: Find's own, for the content its `for` names.
89
+ *
90
+ * Every match is painted as `helix-find-match`, and the current one as
91
+ * `helix-find-current`, by the Custom Highlight API. The first search starts
92
+ * at the first match in sight. The current match is scrolled into the middle
93
+ * of its scroller unless it is already in sight, and what hides it until found
94
+ * is opened first. While a search is open, a change to the content searches
95
+ * again once it has been still for 150ms, staying on the current match, and
96
+ * reports through `found`.
97
+ *
98
+ * Nothing is painted where the API is missing, as on a server or in a test
99
+ * DOM, and the count is still right there.
100
+ */
101
+ export declare const textFinder: (root: Element, options?: TextFinderOptions) => Finder;
@@ -0,0 +1,330 @@
1
+ export const FIND_MATCH = 'helix-find-match';
2
+ export const FIND_CURRENT = 'helix-find-current';
3
+ export const findPattern = (query) => {
4
+ if (query.search === '') {
5
+ return undefined;
6
+ }
7
+ const source = query.regex ? query.search : query.search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8
+ try {
9
+ return new RegExp(query.wholeWord ? `\\b(?:${source})\\b` : source, query.caseSensitive ? 'gu' : 'giu');
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ };
15
+ export const findRanges = (text, query) => {
16
+ const pattern = findPattern(query);
17
+ if (!pattern) {
18
+ return [];
19
+ }
20
+ return [...text.matchAll(pattern)]
21
+ .filter((match) => match[0] !== '')
22
+ .map((match) => [match.index, match.index + match[0].length]);
23
+ };
24
+ const NEVER = 'script, style, template, noscript, textarea, select, [inert], [aria-hidden="true"], [hidden]:not([hidden="until-found"])';
25
+ const BETWEEN = '\u0000';
26
+ const flatParent = (node) => {
27
+ const slot = node.assignedSlot;
28
+ if (slot) {
29
+ return slot;
30
+ }
31
+ const parent = node.parentNode;
32
+ if (parent?.nodeType === Node.ELEMENT_NODE) {
33
+ return parent;
34
+ }
35
+ return parent !== null && 'host' in parent ? parent.host : null;
36
+ };
37
+ const revealers = (node) => {
38
+ const found = [];
39
+ let below = node;
40
+ for (let element = flatParent(node); element !== null; element = flatParent(element)) {
41
+ const closed = element.localName === 'details' &&
42
+ !element.open &&
43
+ !(below instanceof Element && below.localName === 'summary');
44
+ if (closed || element.getAttribute('hidden') === 'until-found') {
45
+ found.unshift(element);
46
+ }
47
+ below = element;
48
+ }
49
+ return found;
50
+ };
51
+ const seen = (element) => {
52
+ if (typeof element.checkVisibility !== 'function') {
53
+ for (let at = element; at !== null; at = flatParent(at)) {
54
+ const hidden = at.getAttribute('hidden');
55
+ if (hidden !== null && hidden !== 'until-found') {
56
+ return false;
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ if (element.checkVisibility({ visibilityProperty: true })) {
62
+ return true;
63
+ }
64
+ const outer = revealers(element)[0];
65
+ return (outer && flatParent(outer)?.checkVisibility({ visibilityProperty: true })) ?? false;
66
+ };
67
+ const INLINE = /^(?:inline|contents|ruby|$)/;
68
+ const blockOf = (text, root, inline) => {
69
+ const view = root.ownerDocument.defaultView;
70
+ for (let element = text.parentElement; element !== null && element !== root; element = element.parentElement) {
71
+ let flows = inline.get(element);
72
+ if (flows === undefined) {
73
+ flows = view ? INLINE.test(view.getComputedStyle(element).display) : false;
74
+ inline.set(element, flows);
75
+ }
76
+ if (!flows) {
77
+ return element;
78
+ }
79
+ }
80
+ return root;
81
+ };
82
+ const textsOf = (root, skip) => {
83
+ const nodes = [];
84
+ let joined = '';
85
+ if (root.closest(NEVER)) {
86
+ return { joined, nodes };
87
+ }
88
+ const never = skip === '' ? NEVER : `${NEVER}, ${skip}`;
89
+ const shown = new Map();
90
+ const inline = new Map();
91
+ const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, {
92
+ acceptNode: (node) => {
93
+ if (node.nodeType === Node.ELEMENT_NODE) {
94
+ const element = node;
95
+ if (element.matches(never)) {
96
+ return NodeFilter.FILTER_REJECT;
97
+ }
98
+ return element.localName === 'br' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
99
+ }
100
+ const parent = node.parentElement;
101
+ if (parent === null || node.nodeValue === '') {
102
+ return NodeFilter.FILTER_REJECT;
103
+ }
104
+ let visible = shown.get(parent);
105
+ if (visible === undefined) {
106
+ visible = seen(parent);
107
+ shown.set(parent, visible);
108
+ }
109
+ return visible ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
110
+ },
111
+ });
112
+ let block;
113
+ for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
114
+ if (node.nodeType === Node.ELEMENT_NODE) {
115
+ joined += BETWEEN;
116
+ continue;
117
+ }
118
+ const text = node;
119
+ const here = blockOf(text, root, inline);
120
+ if (block !== undefined && here !== block) {
121
+ joined += BETWEEN;
122
+ }
123
+ block = here;
124
+ nodes.push([text, joined.length]);
125
+ joined += text.data;
126
+ }
127
+ return { joined, nodes };
128
+ };
129
+ const placed = (nodes, at, end) => {
130
+ let low = 0;
131
+ let high = nodes.length - 1;
132
+ while (low < high) {
133
+ const middle = Math.ceil((low + high) / 2);
134
+ const from = nodes[middle]?.[1] ?? 0;
135
+ if (from < at || (!end && from === at)) {
136
+ low = middle;
137
+ }
138
+ else {
139
+ high = middle - 1;
140
+ }
141
+ }
142
+ const [node, from] = nodes[low];
143
+ return [node, at - from];
144
+ };
145
+ export const findTextRanges = (root, query, skip = '') => {
146
+ if (findPattern(query) === undefined) {
147
+ return [];
148
+ }
149
+ const { joined, nodes } = textsOf(root, skip);
150
+ return findRanges(joined, query)
151
+ .filter(([from, to]) => !joined.slice(from, to).includes(BETWEEN))
152
+ .map(([from, to]) => {
153
+ const range = root.ownerDocument.createRange();
154
+ range.setStart(...placed(nodes, from, false));
155
+ range.setEnd(...placed(nodes, to, true));
156
+ return range;
157
+ });
158
+ };
159
+ const painted = new Map();
160
+ const paint = (owner, ranges, current) => {
161
+ const registry = globalThis.CSS?.highlights;
162
+ if (registry === undefined) {
163
+ return;
164
+ }
165
+ if (ranges.length === 0) {
166
+ painted.delete(owner);
167
+ }
168
+ else {
169
+ painted.set(owner, { current, others: ranges.filter((range) => range !== current) });
170
+ }
171
+ const entries = [...painted.values()];
172
+ const layers = [
173
+ [FIND_MATCH, entries.flatMap((entry) => entry.others), 0],
174
+ [FIND_CURRENT, entries.flatMap((entry) => (entry.current ? [entry.current] : [])), 1],
175
+ ];
176
+ for (const [name, ranges, priority] of layers) {
177
+ if (ranges.length === 0) {
178
+ registry.delete(name);
179
+ }
180
+ else {
181
+ const highlight = new Highlight(...ranges);
182
+ highlight.priority = priority;
183
+ registry.set(name, highlight);
184
+ }
185
+ }
186
+ };
187
+ const against = (range, anchor) => {
188
+ try {
189
+ return range.compareBoundaryPoints(Range.START_TO_START, anchor);
190
+ }
191
+ catch {
192
+ return 1;
193
+ }
194
+ };
195
+ const firstInView = (ranges, root) => {
196
+ const top = Math.max(0, root.getBoundingClientRect().top);
197
+ const at = ranges.findIndex((range) => typeof range.getBoundingClientRect === 'function' &&
198
+ range.getBoundingClientRect().bottom > top);
199
+ return Math.max(at, 0);
200
+ };
201
+ const pick = (ranges, anchor, direction, root) => {
202
+ if (ranges.length === 0) {
203
+ return -1;
204
+ }
205
+ if (anchor === undefined) {
206
+ const first = firstInView(ranges, root);
207
+ return direction === 'previous' ? (first - 1 + ranges.length) % ranges.length : first;
208
+ }
209
+ const index = direction === 'previous'
210
+ ? ranges.findLastIndex((range) => against(range, anchor) < 0)
211
+ : ranges.findIndex((range) => direction === 'next' ? against(range, anchor) > 0 : against(range, anchor) >= 0);
212
+ if (index !== -1) {
213
+ return index;
214
+ }
215
+ return direction === 'previous' ? ranges.length - 1 : 0;
216
+ };
217
+ const scrollerOf = (element) => {
218
+ const view = element.ownerDocument.defaultView;
219
+ for (let at = flatParent(element); at !== null; at = flatParent(at)) {
220
+ if (at === element.ownerDocument.documentElement || at === element.ownerDocument.body) {
221
+ return null;
222
+ }
223
+ const overflow = view?.getComputedStyle(at).overflowY ?? '';
224
+ if (/auto|scroll/.test(overflow) && at.scrollHeight > at.clientHeight) {
225
+ return at;
226
+ }
227
+ }
228
+ return null;
229
+ };
230
+ const bringIntoView = (range) => {
231
+ const element = range.startContainer.parentElement;
232
+ if (element === null || typeof range.getBoundingClientRect !== 'function') {
233
+ return;
234
+ }
235
+ const scroller = scrollerOf(element);
236
+ const box = scroller?.getBoundingClientRect() ?? {
237
+ bottom: innerHeight,
238
+ left: 0,
239
+ right: innerWidth,
240
+ top: 0,
241
+ };
242
+ const rect = range.getBoundingClientRect();
243
+ if (rect.top >= box.top &&
244
+ rect.bottom <= box.bottom &&
245
+ rect.left >= box.left &&
246
+ rect.right <= box.right) {
247
+ return;
248
+ }
249
+ element.scrollIntoView?.({ behavior: 'instant', block: 'center', inline: 'nearest' });
250
+ const after = range.getBoundingClientRect();
251
+ if (scroller && (after.top < box.top || after.bottom > box.bottom)) {
252
+ scroller.scrollTop += after.top + after.height / 2 - (box.top + (box.bottom - box.top) / 2);
253
+ }
254
+ };
255
+ const reveal = (range) => {
256
+ const hiding = revealers(range.startContainer);
257
+ for (const element of hiding) {
258
+ if (element.localName === 'details') {
259
+ ;
260
+ element.open = true;
261
+ }
262
+ else {
263
+ element.dispatchEvent(new Event('beforematch', { bubbles: true }));
264
+ if (element.getAttribute('hidden') === 'until-found') {
265
+ element.removeAttribute('hidden');
266
+ }
267
+ }
268
+ }
269
+ return hiding.length > 0;
270
+ };
271
+ const SETTLE = 150;
272
+ export const textFinder = (root, options = {}) => {
273
+ const owner = {};
274
+ let ranges = [];
275
+ let current;
276
+ let query;
277
+ let observer;
278
+ let settling;
279
+ const search = (direction, show) => {
280
+ ranges = query ? findTextRanges(root, query, options.skip ?? '') : [];
281
+ const index = pick(ranges, current, direction, root);
282
+ current = ranges[index];
283
+ paint(owner, ranges, current);
284
+ const shown = current;
285
+ if (shown && show) {
286
+ if (reveal(shown)) {
287
+ setTimeout(() => bringIntoView(shown));
288
+ }
289
+ else {
290
+ bringIntoView(shown);
291
+ }
292
+ }
293
+ return { count: ranges.length, index };
294
+ };
295
+ const watch = () => {
296
+ if (observer !== undefined || typeof MutationObserver === 'undefined') {
297
+ return;
298
+ }
299
+ observer = new MutationObserver(() => {
300
+ clearTimeout(settling);
301
+ settling = setTimeout(() => {
302
+ if (query) {
303
+ options.found?.(search('first', false));
304
+ }
305
+ }, SETTLE);
306
+ });
307
+ observer.observe(root, {
308
+ attributeFilter: ['aria-hidden', 'hidden', 'inert'],
309
+ characterData: true,
310
+ childList: true,
311
+ subtree: true,
312
+ });
313
+ };
314
+ return {
315
+ end() {
316
+ observer?.disconnect();
317
+ observer = undefined;
318
+ clearTimeout(settling);
319
+ query = undefined;
320
+ ranges = [];
321
+ current = undefined;
322
+ paint(owner, ranges, current);
323
+ },
324
+ find(next, direction) {
325
+ query = next;
326
+ watch();
327
+ return search(direction, true);
328
+ },
329
+ };
330
+ };
package/dist/version.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * release, so the two never disagree; a spec beside this holds them to it.
7
7
  * Nothing else in the running code knows which release it is.
8
8
  */
9
- export declare const VERSION = "0.219.0";
9
+ export declare const VERSION = "0.220.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.219.0';
1
+ export const VERSION = '0.220.0';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-core",
3
3
  "description": "Helix element primitives: base classes, mixins, decorators, utilities.",
4
- "version": "0.219.0",
4
+ "version": "0.220.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -81,12 +81,12 @@
81
81
  "bugs": "https://github.com/project-fusion/fusion/issues",
82
82
  "dependencies": {
83
83
  "@floating-ui/dom": "^1.8.0",
84
- "@fusion.dev/helix-icons": "0.219.0",
84
+ "@fusion.dev/helix-icons": "0.220.0",
85
85
  "tslib": "^2.8.1"
86
86
  },
87
87
  "devDependencies": {
88
- "@fusion.dev/helix-cem": "0.219.0",
89
- "@fusion.dev/helix-testing": "0.219.0",
88
+ "@fusion.dev/helix-cem": "0.220.0",
89
+ "@fusion.dev/helix-testing": "0.220.0",
90
90
  "@lit-labs/ssr": "^4.1.0",
91
91
  "lit": "^3.2.1"
92
92
  },