@acorex/cdk 22.2.16 → 22.2.17
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.
|
@@ -31,6 +31,8 @@ class AXOutlineContainerDirective {
|
|
|
31
31
|
...(ngDevMode ? [{ debugName: "scrollTop" }] : /* istanbul ignore next */ []));
|
|
32
32
|
this.outlineItems = signal([], /* @ts-ignore */
|
|
33
33
|
...(ngDevMode ? [{ debugName: "outlineItems" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.lastScrollSpyIndex = 0;
|
|
35
|
+
this.heldActiveIndex = null;
|
|
34
36
|
this.scrollableElement = computed(() => {
|
|
35
37
|
const scrollableElementId = this.scrollableElementId();
|
|
36
38
|
if (scrollableElementId) {
|
|
@@ -51,12 +53,12 @@ class AXOutlineContainerDirective {
|
|
|
51
53
|
this.scrollableElement().style.scrollBehavior = 'smooth';
|
|
52
54
|
}
|
|
53
55
|
this.zone.runOutsideAngular(() => {
|
|
54
|
-
const scrollable = this.
|
|
56
|
+
const scrollable = this.resolveScrollEventTarget();
|
|
55
57
|
fromEvent(scrollable, 'scroll')
|
|
56
|
-
.pipe(this.unsubscriber.takeUntilDestroy, map(() => this.
|
|
58
|
+
.pipe(this.unsubscriber.takeUntilDestroy, map(() => this.readScrollTop()))
|
|
57
59
|
.subscribe((scrollTop) => {
|
|
58
60
|
this.scrollTop.set(scrollTop);
|
|
59
|
-
this.scrollChanged(scrollTop);
|
|
61
|
+
this.zone.run(() => this.scrollChanged(scrollTop));
|
|
60
62
|
});
|
|
61
63
|
this.mutationObserver = new MutationObserver((mutationsList) => {
|
|
62
64
|
const relevantMutation = mutationsList.some((mutation) => mutation.type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0));
|
|
@@ -68,12 +70,36 @@ class AXOutlineContainerDirective {
|
|
|
68
70
|
childList: true,
|
|
69
71
|
subtree: true,
|
|
70
72
|
});
|
|
73
|
+
this.bindUserScrollIntent(scrollable);
|
|
71
74
|
});
|
|
75
|
+
fromEvent(this.el.nativeElement, 'click', { capture: true })
|
|
76
|
+
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
77
|
+
.subscribe((event) => {
|
|
78
|
+
if (event instanceof MouseEvent) {
|
|
79
|
+
this.handleInContentOutlineLinkClick(event);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const view = this.document.defaultView;
|
|
83
|
+
if (view) {
|
|
84
|
+
fromEvent(view, 'hashchange')
|
|
85
|
+
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
86
|
+
.subscribe(() => {
|
|
87
|
+
const id = decodeURIComponent(view.location.hash?.slice(1) ?? '');
|
|
88
|
+
if (!id || !this.outlineItems().some((item) => item.id === id)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.heldActiveIndex = null;
|
|
92
|
+
const index = this.outlineItems().findIndex((item) => item.id === id);
|
|
93
|
+
this.lastScrollSpyIndex = index;
|
|
94
|
+
this.applyActiveIndex(index);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
72
97
|
this.mutationSubject
|
|
73
98
|
.pipe(debounceTime(this.MUTATION_DEBOUNCE_TIME), this.unsubscriber.takeUntilDestroy)
|
|
74
99
|
.subscribe(() => {
|
|
75
100
|
this.refreshOutlineItems();
|
|
76
101
|
});
|
|
102
|
+
this.zone.run(() => this.scrollChanged(this.readScrollTop()));
|
|
77
103
|
});
|
|
78
104
|
}
|
|
79
105
|
#anr;
|
|
@@ -87,68 +113,236 @@ class AXOutlineContainerDirective {
|
|
|
87
113
|
this.refreshOutlineItems();
|
|
88
114
|
}
|
|
89
115
|
}
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
scrollToItem(id) {
|
|
117
|
+
this.scrollToItemFromHash(true, id);
|
|
118
|
+
}
|
|
119
|
+
resolveScrollEventTarget() {
|
|
120
|
+
const scrollable = this.scrollableElement();
|
|
121
|
+
if (scrollable === this.document.documentElement || scrollable.tagName === 'HTML') {
|
|
122
|
+
return this.document.defaultView ?? scrollable;
|
|
123
|
+
}
|
|
124
|
+
return scrollable;
|
|
125
|
+
}
|
|
126
|
+
readScrollTop() {
|
|
127
|
+
const scrollable = this.scrollableElement();
|
|
128
|
+
if (scrollable === this.document.documentElement || scrollable.tagName === 'HTML') {
|
|
129
|
+
return this.document.defaultView?.scrollY ?? scrollable.scrollTop;
|
|
130
|
+
}
|
|
131
|
+
return scrollable.scrollTop;
|
|
132
|
+
}
|
|
133
|
+
handleInContentOutlineLinkClick(event) {
|
|
134
|
+
const target = event.target;
|
|
135
|
+
if (!(target instanceof Element)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const anchor = target.closest('a');
|
|
139
|
+
if (!anchor || anchor.classList.contains('ax-outline-hash-link')) {
|
|
140
|
+
if (anchor?.classList.contains('ax-outline-hash-link')) {
|
|
141
|
+
const id = this.getOutlineIdFromHref(anchor.getAttribute('href'));
|
|
142
|
+
if (id) {
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
this.scrollToItem(id);
|
|
106
145
|
}
|
|
107
146
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const id = this.getOutlineIdFromHref(anchor.getAttribute('href'));
|
|
150
|
+
if (!id || !this.outlineItems().some((item) => item.id === id)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
this.scrollToItem(id);
|
|
155
|
+
}
|
|
156
|
+
scrollToItemFromHash(scrollToTarget, explicitId) {
|
|
157
|
+
const id = explicitId ?? decodeURIComponent(this.document.defaultView?.location.hash?.slice(1) ?? '');
|
|
158
|
+
if (!id) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const item = this.outlineItems().find((entry) => entry.id === id);
|
|
162
|
+
if (!item) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const activeIndex = this.outlineItems().findIndex((entry) => entry.id === id);
|
|
166
|
+
if (activeIndex < 0) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.heldActiveIndex = activeIndex;
|
|
170
|
+
this.lastScrollSpyIndex = activeIndex;
|
|
171
|
+
this.applyActiveIndex(activeIndex);
|
|
172
|
+
if (!scrollToTarget) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.syncLocationHash(id);
|
|
176
|
+
const offset = this.activationOffset();
|
|
177
|
+
const scrollable = this.scrollableElement();
|
|
178
|
+
const isWindow = scrollable === this.document.documentElement ||
|
|
179
|
+
scrollable.tagName === 'HTML' ||
|
|
180
|
+
this.resolveScrollEventTarget() === this.document.defaultView;
|
|
181
|
+
const itemRect = item.el.getBoundingClientRect();
|
|
182
|
+
if (isWindow) {
|
|
183
|
+
const top = itemRect.top + (this.document.defaultView?.scrollY ?? 0) - offset;
|
|
184
|
+
this.document.defaultView?.scrollTo({
|
|
185
|
+
top: Math.max(0, top),
|
|
186
|
+
behavior: this.smoothScroll() ? 'smooth' : 'auto',
|
|
187
|
+
});
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const scrollableRect = scrollable.getBoundingClientRect();
|
|
191
|
+
const top = scrollable.scrollTop + (itemRect.top - scrollableRect.top) - offset;
|
|
192
|
+
const maxScrollTop = Math.max(0, scrollable.scrollHeight - scrollable.clientHeight);
|
|
193
|
+
scrollable.scrollTo({
|
|
194
|
+
top: Math.max(0, Math.min(top, maxScrollTop)),
|
|
195
|
+
behavior: this.smoothScroll() ? 'smooth' : 'auto',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
releaseHeldActiveIndex() {
|
|
199
|
+
if (this.heldActiveIndex === null) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
this.stopOngoingSmoothScroll();
|
|
203
|
+
this.heldActiveIndex = null;
|
|
204
|
+
this.scrollChanged(this.readScrollTop());
|
|
205
|
+
}
|
|
206
|
+
stopOngoingSmoothScroll() {
|
|
207
|
+
const scrollable = this.scrollableElement();
|
|
208
|
+
const isWindow = scrollable === this.document.documentElement ||
|
|
209
|
+
scrollable.tagName === 'HTML' ||
|
|
210
|
+
this.resolveScrollEventTarget() === this.document.defaultView;
|
|
211
|
+
if (isWindow) {
|
|
212
|
+
const view = this.document.defaultView;
|
|
213
|
+
view?.scrollTo({ top: view.scrollY, behavior: 'auto' });
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
scrollable.scrollTo({ top: scrollable.scrollTop, behavior: 'auto' });
|
|
217
|
+
}
|
|
218
|
+
getOutlineIdFromHref(href) {
|
|
219
|
+
if (!href || !href.includes('#')) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
const id = decodeURIComponent(href.split('#')[1] ?? '');
|
|
223
|
+
return id || null;
|
|
224
|
+
}
|
|
225
|
+
syncLocationHash(id) {
|
|
226
|
+
const view = this.document.defaultView;
|
|
227
|
+
if (!view || view.location.hash === `#${id}`) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
view.history.pushState(null, '', `#${id}`);
|
|
231
|
+
}
|
|
232
|
+
scrollChanged(scrollTop) {
|
|
233
|
+
if (this.heldActiveIndex !== null) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const activeIndex = this.resolveActiveIndex(scrollTop);
|
|
237
|
+
if (activeIndex === this.lastScrollSpyIndex) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.lastScrollSpyIndex = activeIndex;
|
|
241
|
+
this.applyActiveIndex(activeIndex);
|
|
242
|
+
}
|
|
243
|
+
bindUserScrollIntent(scrollable) {
|
|
244
|
+
const releaseHold = () => {
|
|
245
|
+
this.zone.run(() => this.releaseHeldActiveIndex());
|
|
246
|
+
};
|
|
247
|
+
fromEvent(scrollable, 'wheel', { passive: true }).pipe(this.unsubscriber.takeUntilDestroy).subscribe(releaseHold);
|
|
248
|
+
fromEvent(scrollable, 'touchmove', { passive: true })
|
|
249
|
+
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
250
|
+
.subscribe(releaseHold);
|
|
251
|
+
fromEvent(scrollable, 'pointerdown', { passive: true })
|
|
252
|
+
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
253
|
+
.subscribe(releaseHold);
|
|
254
|
+
fromEvent(scrollable, 'keydown')
|
|
255
|
+
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
256
|
+
.subscribe((event) => {
|
|
257
|
+
if (!(event instanceof KeyboardEvent)) {
|
|
258
|
+
return;
|
|
118
259
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
activeIndex = i;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
const lastReachableIndex = firstUnreachableIndex - 1;
|
|
126
|
-
const zoneStart = lastReachableIndex >= 0 ? prevItems[lastReachableIndex].scrollY - offset : 0;
|
|
127
|
-
const zoneRange = maxScrollTop - zoneStart;
|
|
128
|
-
if (zoneRange <= 0) {
|
|
129
|
-
activeIndex = this.activateLastAtBottom()
|
|
130
|
-
? prevItems.length - 1
|
|
131
|
-
: Math.max(0, lastReachableIndex);
|
|
132
|
-
}
|
|
133
|
-
else if (scrollTop >= zoneStart) {
|
|
134
|
-
// Map the remaining scroll range across the last reachable item and all
|
|
135
|
-
// unreachable trailing items so short end sections are not skipped.
|
|
136
|
-
const progress = Math.min(1, Math.max(0, (scrollTop - zoneStart) / zoneRange));
|
|
137
|
-
const startIndex = Math.max(0, lastReachableIndex);
|
|
138
|
-
const span = prevItems.length - 1 - startIndex;
|
|
139
|
-
if (progress >= 1 || (isAtBottom && this.activateLastAtBottom())) {
|
|
140
|
-
activeIndex = prevItems.length - 1;
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
activeIndex = startIndex + Math.floor(progress * span);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
260
|
+
const scrollKeys = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End', ' '];
|
|
261
|
+
if (scrollKeys.includes(event.key)) {
|
|
262
|
+
releaseHold();
|
|
146
263
|
}
|
|
147
|
-
return prevItems.map((item, index) => ({
|
|
148
|
-
...item,
|
|
149
|
-
active: index === activeIndex,
|
|
150
|
-
}));
|
|
151
264
|
});
|
|
265
|
+
}
|
|
266
|
+
resolveActiveIndex(scrollTop) {
|
|
267
|
+
const prevItems = this.outlineItems();
|
|
268
|
+
if (prevItems.length === 0) {
|
|
269
|
+
return -1;
|
|
270
|
+
}
|
|
271
|
+
if (prevItems.length === 1) {
|
|
272
|
+
return 0;
|
|
273
|
+
}
|
|
274
|
+
const scrollable = this.scrollableElement();
|
|
275
|
+
const offset = this.activationOffset();
|
|
276
|
+
const maxScrollTop = Math.max(0, scrollable.scrollHeight - scrollable.clientHeight);
|
|
277
|
+
const scrollableRect = scrollable.getBoundingClientRect();
|
|
278
|
+
const activationScrollTops = prevItems.map((item) => {
|
|
279
|
+
const itemTop = item.el.getBoundingClientRect().top;
|
|
280
|
+
return scrollTop + (itemTop - scrollableRect.top) - offset;
|
|
281
|
+
});
|
|
282
|
+
const count = prevItems.length;
|
|
283
|
+
if (this.activateLastAtBottom() && maxScrollTop > 0 && scrollTop >= maxScrollTop - 1) {
|
|
284
|
+
return count - 1;
|
|
285
|
+
}
|
|
286
|
+
let thresholdIndex = 0;
|
|
287
|
+
for (let i = 0; i < count; i++) {
|
|
288
|
+
if (activationScrollTops[i] <= scrollTop) {
|
|
289
|
+
thresholdIndex = i;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const slotIndex = this.resolveByScrollSlots(scrollTop, activationScrollTops, maxScrollTop);
|
|
293
|
+
if (slotIndex <= thresholdIndex) {
|
|
294
|
+
return thresholdIndex;
|
|
295
|
+
}
|
|
296
|
+
const minSlot = Math.max(1, maxScrollTop / Math.max(count * 6, 1));
|
|
297
|
+
const slotActivation = activationScrollTops[slotIndex];
|
|
298
|
+
if (scrollTop >= slotActivation - minSlot) {
|
|
299
|
+
return slotIndex;
|
|
300
|
+
}
|
|
301
|
+
return thresholdIndex;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Maps scroll position to the active outline item. Sections with little content often
|
|
305
|
+
* have overlapping activation thresholds; each section gets a minimum scroll slot so
|
|
306
|
+
* short blocks are not skipped while scrolling.
|
|
307
|
+
*/
|
|
308
|
+
resolveByScrollSlots(scrollTop, activationScrollTops, maxScrollTop) {
|
|
309
|
+
const count = activationScrollTops.length;
|
|
310
|
+
if (maxScrollTop <= 0) {
|
|
311
|
+
return 0;
|
|
312
|
+
}
|
|
313
|
+
const minSlot = Math.max(1, maxScrollTop / Math.max(count * 6, 1));
|
|
314
|
+
const weights = [];
|
|
315
|
+
for (let i = 0; i < count; i++) {
|
|
316
|
+
const sectionStart = Math.max(0, Math.min(activationScrollTops[i], maxScrollTop));
|
|
317
|
+
let sectionEnd = maxScrollTop;
|
|
318
|
+
if (i < count - 1) {
|
|
319
|
+
sectionEnd = Math.max(sectionStart, Math.min(activationScrollTops[i + 1], maxScrollTop));
|
|
320
|
+
}
|
|
321
|
+
weights.push(Math.max(minSlot, sectionEnd - sectionStart));
|
|
322
|
+
}
|
|
323
|
+
const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);
|
|
324
|
+
const scaledPosition = (scrollTop / maxScrollTop) * totalWeight;
|
|
325
|
+
let consumed = 0;
|
|
326
|
+
for (let i = 0; i < count; i++) {
|
|
327
|
+
consumed += weights[i];
|
|
328
|
+
if (scaledPosition <= consumed || i === count - 1) {
|
|
329
|
+
return i;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return count - 1;
|
|
333
|
+
}
|
|
334
|
+
applyActiveIndex(activeIndex) {
|
|
335
|
+
if (activeIndex < 0) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const current = this.outlineItems();
|
|
339
|
+
if (current.length > 0 && current.every((item, index) => item.active === (index === activeIndex))) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this.outlineItems.update((prevItems) => prevItems.map((item, index) => ({
|
|
343
|
+
...item,
|
|
344
|
+
active: index === activeIndex,
|
|
345
|
+
})));
|
|
152
346
|
this.outlineItems$.next(this.outlineItems());
|
|
153
347
|
}
|
|
154
348
|
setOutlineItems() {
|
|
@@ -168,7 +362,7 @@ class AXOutlineContainerDirective {
|
|
|
168
362
|
const htmlEl = el;
|
|
169
363
|
let fragment = htmlEl.id;
|
|
170
364
|
if (!fragment) {
|
|
171
|
-
const textContentForId = htmlEl.textContent?.trim() ?? '';
|
|
365
|
+
const textContentForId = htmlEl.textContent?.trim() ?? '';
|
|
172
366
|
if (textContentForId) {
|
|
173
367
|
fragment = `${textContentForId.toLowerCase().replace(/\s+/g, '-')}`;
|
|
174
368
|
let counter = 1;
|
|
@@ -181,7 +375,7 @@ class AXOutlineContainerDirective {
|
|
|
181
375
|
else {
|
|
182
376
|
fragment = `ax-outline-${Math.random().toString(36).slice(2, 7)}`;
|
|
183
377
|
}
|
|
184
|
-
htmlEl.id = fragment;
|
|
378
|
+
htmlEl.id = fragment;
|
|
185
379
|
}
|
|
186
380
|
htmlEl.style.scrollMargin = `${this.activationOffset()}px`;
|
|
187
381
|
const existingLink = htmlEl.querySelector('a.ax-outline-hash-link');
|
|
@@ -193,8 +387,7 @@ class AXOutlineContainerDirective {
|
|
|
193
387
|
anchor.textContent = '#';
|
|
194
388
|
anchor.href = `${window.location.pathname}${window.location.search}#${fragment}`;
|
|
195
389
|
anchor.classList.add('ax-outline-hash-link');
|
|
196
|
-
|
|
197
|
-
anchor.style.paddingInlineStart = '0.5rem'; // Adjust as needed
|
|
390
|
+
anchor.style.paddingInlineStart = '0.5rem';
|
|
198
391
|
anchor.style.opacity = '0';
|
|
199
392
|
anchor.style.transition = 'opacity 0.2s ease-in-out';
|
|
200
393
|
anchor.style.cursor = 'pointer';
|
|
@@ -206,7 +399,10 @@ class AXOutlineContainerDirective {
|
|
|
206
399
|
htmlEl.addEventListener('mouseleave', leaveListener);
|
|
207
400
|
htmlEl.appendChild(anchor);
|
|
208
401
|
if (this.copyUrlOnClick()) {
|
|
209
|
-
anchor.addEventListener('click', async () => {
|
|
402
|
+
anchor.addEventListener('click', async (event) => {
|
|
403
|
+
event.preventDefault();
|
|
404
|
+
event.stopPropagation();
|
|
405
|
+
this.scrollToItem(fragment);
|
|
210
406
|
try {
|
|
211
407
|
await this.clipboardService.copy(anchor.href);
|
|
212
408
|
}
|
|
@@ -217,7 +413,6 @@ class AXOutlineContainerDirective {
|
|
|
217
413
|
}
|
|
218
414
|
}
|
|
219
415
|
const parentId = htmlEl.getAttribute('data-parent') ?? undefined;
|
|
220
|
-
// Calculate position relative to the scrollable element
|
|
221
416
|
const scrollableElement = this.scrollableElement();
|
|
222
417
|
const scrollableRect = scrollableElement?.getBoundingClientRect() ?? { top: 0 };
|
|
223
418
|
const elementRect = htmlEl.getBoundingClientRect();
|
|
@@ -233,7 +428,15 @@ class AXOutlineContainerDirective {
|
|
|
233
428
|
})
|
|
234
429
|
.sort((a, b) => a.scrollY - b.scrollY);
|
|
235
430
|
this.outlineItems.set(outlineItems);
|
|
236
|
-
|
|
431
|
+
const hashId = decodeURIComponent(this.document.defaultView?.location.hash?.slice(1) ?? '');
|
|
432
|
+
if (hashId && outlineItems.some((item) => item.id === hashId)) {
|
|
433
|
+
const hashIndex = outlineItems.findIndex((item) => item.id === hashId);
|
|
434
|
+
this.lastScrollSpyIndex = hashIndex;
|
|
435
|
+
this.applyActiveIndex(hashIndex);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
this.scrollChanged(this.readScrollTop());
|
|
439
|
+
}
|
|
237
440
|
if (this.mutationObserver) {
|
|
238
441
|
this.mutationObserver.observe(this.el.nativeElement, {
|
|
239
442
|
childList: true,
|
|
@@ -271,7 +474,7 @@ class AXOutlineItemDirective {
|
|
|
271
474
|
if (!this.id()) {
|
|
272
475
|
const textContent = this.el.nativeElement.textContent.trim();
|
|
273
476
|
if (textContent) {
|
|
274
|
-
newId = `${textContent.replace(/\s+/g, '-')}`;
|
|
477
|
+
newId = `${textContent.toLowerCase().replace(/\s+/g, '-')}`;
|
|
275
478
|
}
|
|
276
479
|
else {
|
|
277
480
|
newId = `${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-cdk-outline.mjs","sources":["../../../../packages/cdk/outline/src/lib/outline-container.directive.ts","../../../../packages/cdk/outline/src/lib/outline-item.directive.ts","../../../../packages/cdk/outline/src/acorex-cdk-outline.ts"],"sourcesContent":["import { AXClipBoardService } from '@acorex/cdk/clipboard';\nimport { AXUnsubscriber } from '@acorex/core/utils';\nimport { isPlatformBrowser, DOCUMENT } from '@angular/common';\nimport {\n afterNextRender,\n AfterViewInit,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { BehaviorSubject, debounceTime, fromEvent, map, Subject } from 'rxjs';\n\nexport type outlineItemType = {\n id: string;\n el: HTMLElement;\n active: boolean;\n scrollY: number;\n parentId?: string;\n hasAnchor: boolean;\n};\n\n@Directive({\n selector: '[axOutlineContainer]',\n exportAs: 'axOutlineContainer',\n providers: [AXUnsubscriber, AXClipBoardService],\n})\nexport class AXOutlineContainerDirective implements OnDestroy, AfterViewInit {\n private zone = inject(NgZone);\n private platformId = inject(PLATFORM_ID);\n private document = inject(DOCUMENT);\n private el = inject(ElementRef<HTMLElement>);\n private unsubscriber = inject(AXUnsubscriber);\n private clipboardService = inject(AXClipBoardService);\n\n target = input<string>();\n smoothScroll = input(true);\n showHashItem = input(false);\n activationOffset = input(16);\n copyUrlOnClick = input(false);\n activateLastAtBottom = input(true);\n scrollableElementId = input<string | null>(null);\n\n private scrollTop = signal(0);\n private outlineItems = signal<outlineItemType[]>([]);\n\n private scrollableElement = computed(() => {\n const scrollableElementId = this.scrollableElementId();\n if (scrollableElementId) {\n return this.document.getElementById(scrollableElementId) ?? this.el.nativeElement;\n }\n return this.el.nativeElement;\n });\n\n private mutationSubject = new Subject<void>();\n private readonly MUTATION_DEBOUNCE_TIME = 150;\n private mutationObserver: MutationObserver | undefined;\n outlineItems$ = new BehaviorSubject<outlineItemType[]>([]);\n\n #anr = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n if (this.smoothScroll()) {\n this.scrollableElement().style.overflow = 'auto';\n this.scrollableElement().style.scrollBehavior = 'smooth';\n }\n\n this.zone.runOutsideAngular(() => {\n const scrollable = this.scrollableElement().tagName === 'HTML' ? window : this.scrollableElement();\n fromEvent(scrollable, 'scroll')\n .pipe(\n this.unsubscriber.takeUntilDestroy,\n map(() => this.scrollableElement().scrollTop),\n )\n .subscribe((scrollTop) => {\n this.scrollTop.set(scrollTop);\n this.scrollChanged(scrollTop);\n });\n\n this.mutationObserver = new MutationObserver((mutationsList) => {\n const relevantMutation = mutationsList.some(\n (mutation) =>\n mutation.type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0),\n );\n if (relevantMutation) {\n this.mutationSubject.next();\n }\n });\n\n this.mutationObserver.observe(this.el.nativeElement, {\n childList: true,\n subtree: true,\n });\n });\n\n this.mutationSubject\n .pipe(debounceTime(this.MUTATION_DEBOUNCE_TIME), this.unsubscriber.takeUntilDestroy)\n .subscribe(() => {\n this.refreshOutlineItems();\n });\n });\n\n ngOnDestroy(): void {\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n }\n\n ngAfterViewInit() {\n if (isPlatformBrowser(this.platformId)) {\n this.refreshOutlineItems();\n }\n }\n\n private scrollChanged(scrollTop: number) {\n this.outlineItems.update((prevItems) => {\n if (prevItems.length === 0) return prevItems;\n\n const scrollable = this.scrollableElement();\n const maxScrollTop = Math.max(0, scrollable.scrollHeight - scrollable.clientHeight);\n const offset = this.activationOffset();\n const isAtBottom = maxScrollTop > 0 && scrollTop >= maxScrollTop - 1;\n\n // Items whose activation threshold sits beyond maxScrollTop can never become\n // active via normal scroll comparison. Jumping straight to the last item at\n // the bottom (previous behavior) skipped those intermediate sections.\n let firstUnreachableIndex = prevItems.length;\n for (let i = 0; i < prevItems.length; i++) {\n if (prevItems[i].scrollY - offset > maxScrollTop) {\n firstUnreachableIndex = i;\n break;\n }\n }\n\n let activeIndex = -1;\n\n if (firstUnreachableIndex === prevItems.length) {\n for (let i = 0; i < prevItems.length; i++) {\n if (scrollTop >= prevItems[i].scrollY - offset) {\n activeIndex = i;\n }\n }\n if (isAtBottom && this.activateLastAtBottom()) {\n activeIndex = prevItems.length - 1;\n }\n } else {\n for (let i = 0; i < firstUnreachableIndex; i++) {\n if (scrollTop >= prevItems[i].scrollY - offset) {\n activeIndex = i;\n }\n }\n\n const lastReachableIndex = firstUnreachableIndex - 1;\n const zoneStart = lastReachableIndex >= 0 ? prevItems[lastReachableIndex].scrollY - offset : 0;\n const zoneRange = maxScrollTop - zoneStart;\n\n if (zoneRange <= 0) {\n activeIndex = this.activateLastAtBottom()\n ? prevItems.length - 1\n : Math.max(0, lastReachableIndex);\n } else if (scrollTop >= zoneStart) {\n // Map the remaining scroll range across the last reachable item and all\n // unreachable trailing items so short end sections are not skipped.\n const progress = Math.min(1, Math.max(0, (scrollTop - zoneStart) / zoneRange));\n const startIndex = Math.max(0, lastReachableIndex);\n const span = prevItems.length - 1 - startIndex;\n\n if (progress >= 1 || (isAtBottom && this.activateLastAtBottom())) {\n activeIndex = prevItems.length - 1;\n } else {\n activeIndex = startIndex + Math.floor(progress * span);\n }\n }\n }\n\n return prevItems.map((item, index) => ({\n ...item,\n active: index === activeIndex,\n }));\n });\n this.outlineItems$.next(this.outlineItems());\n }\n\n private setOutlineItems() {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n\n setTimeout(() => {\n const targets = this.target() ? [...this.el.nativeElement.querySelectorAll(this.target())] : [];\n targets.push(...this.el.nativeElement.querySelectorAll('[data-ax-outline-item=\"true\"]'));\n const uniqueTargets = new Set(targets);\n\n const outlineItems = Array.from(uniqueTargets)\n .filter((el) => el.getAttribute('data-ax-outline-item') !== 'false')\n .map((el) => {\n const htmlEl = el as HTMLElement;\n let fragment = htmlEl.id;\n if (!fragment) {\n const textContentForId = htmlEl.textContent?.trim() ?? ''; // Read text BEFORE adding/modifying for hash\n if (textContentForId) {\n fragment = `${textContentForId.toLowerCase().replace(/\\s+/g, '-')}`;\n let counter = 1;\n const originalFragment = fragment;\n while (this.document.getElementById(fragment)) {\n fragment = `${originalFragment}-${counter}`;\n counter++;\n }\n } else {\n fragment = `ax-outline-${Math.random().toString(36).slice(2, 7)}`;\n }\n htmlEl.id = fragment; // Set the ID on the element\n }\n\n htmlEl.style.scrollMargin = `${this.activationOffset()}px`;\n\n const existingLink = htmlEl.querySelector('a.ax-outline-hash-link');\n if (existingLink) {\n existingLink.remove();\n }\n\n if (this.showHashItem() && isPlatformBrowser(this.platformId)) {\n const anchor = this.document.createElement('a');\n anchor.textContent = '#';\n anchor.href = `${window.location.pathname}${window.location.search}#${fragment}`;\n anchor.classList.add('ax-outline-hash-link');\n\n // Styling for the hash link\n anchor.style.paddingInlineStart = '0.5rem'; // Adjust as needed\n anchor.style.opacity = '0';\n anchor.style.transition = 'opacity 0.2s ease-in-out';\n anchor.style.cursor = 'pointer';\n anchor.setAttribute('aria-hidden', 'true');\n anchor.setAttribute('fragment', fragment);\n\n const enterListener = () => (anchor.style.opacity = '1');\n const leaveListener = () => (anchor.style.opacity = '0');\n\n htmlEl.addEventListener('mouseenter', enterListener);\n htmlEl.addEventListener('mouseleave', leaveListener);\n\n htmlEl.appendChild(anchor);\n\n if (this.copyUrlOnClick()) {\n anchor.addEventListener('click', async () => {\n try {\n await this.clipboardService.copy(anchor.href);\n } catch (err) {\n console.error('Failed to copy outline URL:', err);\n }\n });\n }\n }\n\n const parentId = htmlEl.getAttribute('data-parent') ?? undefined;\n\n // Calculate position relative to the scrollable element\n const scrollableElement = this.scrollableElement();\n const scrollableRect = scrollableElement?.getBoundingClientRect() ?? { top: 0 };\n const elementRect = htmlEl.getBoundingClientRect();\n const relativeScrollY = elementRect.top - scrollableRect.top + (scrollableElement?.scrollTop ?? 0);\n\n return {\n el: htmlEl,\n id: fragment,\n active: false,\n parentId: parentId,\n scrollY: relativeScrollY,\n hasAnchor: this.showHashItem(),\n };\n })\n .sort((a, b) => a.scrollY - b.scrollY);\n\n this.outlineItems.set(outlineItems);\n this.scrollChanged(this.scrollTop());\n\n if (this.mutationObserver) {\n this.mutationObserver.observe(this.el.nativeElement, {\n childList: true,\n subtree: true,\n });\n }\n });\n }\n\n public refreshOutlineItems() {\n this.setOutlineItems();\n }\n}\n","import { afterNextRender, Directive, ElementRef, inject, input } from '@angular/core';\n\n@Directive({\n selector: '[axOutlineItem]',\n exportAs: 'axOutlineItem',\n})\nexport class AXOutlineItemDirective {\n private el = inject(ElementRef);\n\n id = input<string>();\n disabled = input(false);\n\n #anr = afterNextRender(() => {\n const element = this.el.nativeElement as HTMLElement;\n element.setAttribute('data-ax-outline-item', this.disabled() ? 'false' : 'true');\n\n let newId;\n if (!this.id()) {\n const textContent = this.el.nativeElement.textContent.trim();\n if (textContent) {\n newId = `${textContent.replace(/\\s+/g, '-')}`;\n } else {\n newId = `${Math.random().toString(36).slice(2, 7)}`;\n }\n this.el.nativeElement.id = newId;\n }\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acorex-cdk-outline.mjs","sources":["../../../../packages/cdk/outline/src/lib/outline-container.directive.ts","../../../../packages/cdk/outline/src/lib/outline-item.directive.ts","../../../../packages/cdk/outline/src/acorex-cdk-outline.ts"],"sourcesContent":["import { AXClipBoardService } from '@acorex/cdk/clipboard';\nimport { AXUnsubscriber } from '@acorex/core/utils';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport {\n afterNextRender,\n AfterViewInit,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n NgZone,\n OnDestroy,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { BehaviorSubject, debounceTime, fromEvent, map, Subject } from 'rxjs';\n\nexport type outlineItemType = {\n id: string;\n el: HTMLElement;\n active: boolean;\n scrollY: number;\n parentId?: string;\n hasAnchor: boolean;\n};\n\n@Directive({\n selector: '[axOutlineContainer]',\n exportAs: 'axOutlineContainer',\n providers: [AXUnsubscriber, AXClipBoardService],\n})\nexport class AXOutlineContainerDirective implements OnDestroy, AfterViewInit {\n private zone = inject(NgZone);\n private platformId = inject(PLATFORM_ID);\n private document = inject(DOCUMENT);\n private el = inject(ElementRef<HTMLElement>);\n private unsubscriber = inject(AXUnsubscriber);\n private clipboardService = inject(AXClipBoardService);\n\n target = input<string>();\n smoothScroll = input(true);\n showHashItem = input(false);\n activationOffset = input(16);\n copyUrlOnClick = input(false);\n activateLastAtBottom = input(true);\n scrollableElementId = input<string | null>(null);\n\n private scrollTop = signal(0);\n private outlineItems = signal<outlineItemType[]>([]);\n private lastScrollSpyIndex = 0;\n private heldActiveIndex: number | null = null;\n\n private scrollableElement = computed(() => {\n const scrollableElementId = this.scrollableElementId();\n if (scrollableElementId) {\n return this.document.getElementById(scrollableElementId) ?? this.el.nativeElement;\n }\n return this.el.nativeElement;\n });\n\n private mutationSubject = new Subject<void>();\n private readonly MUTATION_DEBOUNCE_TIME = 150;\n private mutationObserver: MutationObserver | undefined;\n outlineItems$ = new BehaviorSubject<outlineItemType[]>([]);\n\n #anr = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n if (this.smoothScroll()) {\n this.scrollableElement().style.overflow = 'auto';\n this.scrollableElement().style.scrollBehavior = 'smooth';\n }\n\n this.zone.runOutsideAngular(() => {\n const scrollable = this.resolveScrollEventTarget();\n fromEvent(scrollable, 'scroll')\n .pipe(\n this.unsubscriber.takeUntilDestroy,\n map(() => this.readScrollTop()),\n )\n .subscribe((scrollTop) => {\n this.scrollTop.set(scrollTop);\n this.zone.run(() => this.scrollChanged(scrollTop));\n });\n\n this.mutationObserver = new MutationObserver((mutationsList) => {\n const relevantMutation = mutationsList.some(\n (mutation) =>\n mutation.type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0),\n );\n if (relevantMutation) {\n this.mutationSubject.next();\n }\n });\n\n this.mutationObserver.observe(this.el.nativeElement, {\n childList: true,\n subtree: true,\n });\n\n this.bindUserScrollIntent(scrollable);\n });\n\n fromEvent(this.el.nativeElement, 'click', { capture: true })\n .pipe(this.unsubscriber.takeUntilDestroy)\n .subscribe((event) => {\n if (event instanceof MouseEvent) {\n this.handleInContentOutlineLinkClick(event);\n }\n });\n\n const view = this.document.defaultView;\n if (view) {\n fromEvent(view, 'hashchange')\n .pipe(this.unsubscriber.takeUntilDestroy)\n .subscribe(() => {\n const id = decodeURIComponent(view.location.hash?.slice(1) ?? '');\n if (!id || !this.outlineItems().some((item) => item.id === id)) {\n return;\n }\n this.heldActiveIndex = null;\n const index = this.outlineItems().findIndex((item) => item.id === id);\n this.lastScrollSpyIndex = index;\n this.applyActiveIndex(index);\n });\n }\n\n this.mutationSubject\n .pipe(debounceTime(this.MUTATION_DEBOUNCE_TIME), this.unsubscriber.takeUntilDestroy)\n .subscribe(() => {\n this.refreshOutlineItems();\n });\n\n this.zone.run(() => this.scrollChanged(this.readScrollTop()));\n });\n\n ngOnDestroy(): void {\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n }\n\n ngAfterViewInit() {\n if (isPlatformBrowser(this.platformId)) {\n this.refreshOutlineItems();\n }\n }\n\n scrollToItem(id: string): void {\n this.scrollToItemFromHash(true, id);\n }\n\n private resolveScrollEventTarget(): EventTarget {\n const scrollable = this.scrollableElement();\n if (scrollable === this.document.documentElement || scrollable.tagName === 'HTML') {\n return this.document.defaultView ?? scrollable;\n }\n return scrollable;\n }\n\n private readScrollTop(): number {\n const scrollable = this.scrollableElement();\n if (scrollable === this.document.documentElement || scrollable.tagName === 'HTML') {\n return this.document.defaultView?.scrollY ?? scrollable.scrollTop;\n }\n return scrollable.scrollTop;\n }\n\n private handleInContentOutlineLinkClick(event: MouseEvent): void {\n const target = event.target;\n if (!(target instanceof Element)) {\n return;\n }\n\n const anchor = target.closest('a');\n if (!anchor || anchor.classList.contains('ax-outline-hash-link')) {\n if (anchor?.classList.contains('ax-outline-hash-link')) {\n const id = this.getOutlineIdFromHref(anchor.getAttribute('href'));\n if (id) {\n event.preventDefault();\n this.scrollToItem(id);\n }\n }\n return;\n }\n\n const id = this.getOutlineIdFromHref(anchor.getAttribute('href'));\n if (!id || !this.outlineItems().some((item) => item.id === id)) {\n return;\n }\n\n event.preventDefault();\n this.scrollToItem(id);\n }\n\n private scrollToItemFromHash(scrollToTarget: boolean, explicitId?: string): void {\n const id = explicitId ?? decodeURIComponent(this.document.defaultView?.location.hash?.slice(1) ?? '');\n if (!id) {\n return;\n }\n\n const item = this.outlineItems().find((entry) => entry.id === id);\n if (!item) {\n return;\n }\n\n const activeIndex = this.outlineItems().findIndex((entry) => entry.id === id);\n if (activeIndex < 0) {\n return;\n }\n\n this.heldActiveIndex = activeIndex;\n this.lastScrollSpyIndex = activeIndex;\n this.applyActiveIndex(activeIndex);\n\n if (!scrollToTarget) {\n return;\n }\n\n this.syncLocationHash(id);\n\n const offset = this.activationOffset();\n const scrollable = this.scrollableElement();\n const isWindow =\n scrollable === this.document.documentElement ||\n scrollable.tagName === 'HTML' ||\n this.resolveScrollEventTarget() === this.document.defaultView;\n const itemRect = item.el.getBoundingClientRect();\n\n if (isWindow) {\n const top = itemRect.top + (this.document.defaultView?.scrollY ?? 0) - offset;\n this.document.defaultView?.scrollTo({\n top: Math.max(0, top),\n behavior: this.smoothScroll() ? 'smooth' : 'auto',\n });\n return;\n }\n\n const scrollableRect = scrollable.getBoundingClientRect();\n const top = scrollable.scrollTop + (itemRect.top - scrollableRect.top) - offset;\n const maxScrollTop = Math.max(0, scrollable.scrollHeight - scrollable.clientHeight);\n scrollable.scrollTo({\n top: Math.max(0, Math.min(top, maxScrollTop)),\n behavior: this.smoothScroll() ? 'smooth' : 'auto',\n });\n }\n\n private releaseHeldActiveIndex(): void {\n if (this.heldActiveIndex === null) {\n return;\n }\n\n this.stopOngoingSmoothScroll();\n this.heldActiveIndex = null;\n this.scrollChanged(this.readScrollTop());\n }\n\n private stopOngoingSmoothScroll(): void {\n const scrollable = this.scrollableElement();\n const isWindow =\n scrollable === this.document.documentElement ||\n scrollable.tagName === 'HTML' ||\n this.resolveScrollEventTarget() === this.document.defaultView;\n\n if (isWindow) {\n const view = this.document.defaultView;\n view?.scrollTo({ top: view.scrollY, behavior: 'auto' });\n return;\n }\n\n scrollable.scrollTo({ top: scrollable.scrollTop, behavior: 'auto' });\n }\n\n private getOutlineIdFromHref(href: string | null): string | null {\n if (!href || !href.includes('#')) {\n return null;\n }\n const id = decodeURIComponent(href.split('#')[1] ?? '');\n return id || null;\n }\n\n private syncLocationHash(id: string): void {\n const view = this.document.defaultView;\n if (!view || view.location.hash === `#${id}`) {\n return;\n }\n view.history.pushState(null, '', `#${id}`);\n }\n\n private scrollChanged(scrollTop: number) {\n if (this.heldActiveIndex !== null) {\n return;\n }\n\n const activeIndex = this.resolveActiveIndex(scrollTop);\n if (activeIndex === this.lastScrollSpyIndex) {\n return;\n }\n\n this.lastScrollSpyIndex = activeIndex;\n this.applyActiveIndex(activeIndex);\n }\n\n private bindUserScrollIntent(scrollable: EventTarget): void {\n const releaseHold = () => {\n this.zone.run(() => this.releaseHeldActiveIndex());\n };\n\n fromEvent(scrollable, 'wheel', { passive: true }).pipe(this.unsubscriber.takeUntilDestroy).subscribe(releaseHold);\n\n fromEvent(scrollable, 'touchmove', { passive: true })\n .pipe(this.unsubscriber.takeUntilDestroy)\n .subscribe(releaseHold);\n\n fromEvent(scrollable, 'pointerdown', { passive: true })\n .pipe(this.unsubscriber.takeUntilDestroy)\n .subscribe(releaseHold);\n\n fromEvent(scrollable, 'keydown')\n .pipe(this.unsubscriber.takeUntilDestroy)\n .subscribe((event) => {\n if (!(event instanceof KeyboardEvent)) {\n return;\n }\n const scrollKeys = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End', ' '];\n if (scrollKeys.includes(event.key)) {\n releaseHold();\n }\n });\n }\n\n private resolveActiveIndex(scrollTop: number): number {\n const prevItems = this.outlineItems();\n if (prevItems.length === 0) {\n return -1;\n }\n if (prevItems.length === 1) {\n return 0;\n }\n\n const scrollable = this.scrollableElement();\n const offset = this.activationOffset();\n const maxScrollTop = Math.max(0, scrollable.scrollHeight - scrollable.clientHeight);\n const scrollableRect = scrollable.getBoundingClientRect();\n const activationScrollTops = prevItems.map((item) => {\n const itemTop = item.el.getBoundingClientRect().top;\n return scrollTop + (itemTop - scrollableRect.top) - offset;\n });\n\n const count = prevItems.length;\n if (this.activateLastAtBottom() && maxScrollTop > 0 && scrollTop >= maxScrollTop - 1) {\n return count - 1;\n }\n\n let thresholdIndex = 0;\n for (let i = 0; i < count; i++) {\n if (activationScrollTops[i] <= scrollTop) {\n thresholdIndex = i;\n }\n }\n\n const slotIndex = this.resolveByScrollSlots(scrollTop, activationScrollTops, maxScrollTop);\n if (slotIndex <= thresholdIndex) {\n return thresholdIndex;\n }\n\n const minSlot = Math.max(1, maxScrollTop / Math.max(count * 6, 1));\n const slotActivation = activationScrollTops[slotIndex];\n if (scrollTop >= slotActivation - minSlot) {\n return slotIndex;\n }\n\n return thresholdIndex;\n }\n\n /**\n * Maps scroll position to the active outline item. Sections with little content often\n * have overlapping activation thresholds; each section gets a minimum scroll slot so\n * short blocks are not skipped while scrolling.\n */\n private resolveByScrollSlots(scrollTop: number, activationScrollTops: number[], maxScrollTop: number): number {\n const count = activationScrollTops.length;\n if (maxScrollTop <= 0) {\n return 0;\n }\n\n const minSlot = Math.max(1, maxScrollTop / Math.max(count * 6, 1));\n const weights: number[] = [];\n\n for (let i = 0; i < count; i++) {\n const sectionStart = Math.max(0, Math.min(activationScrollTops[i], maxScrollTop));\n let sectionEnd = maxScrollTop;\n if (i < count - 1) {\n sectionEnd = Math.max(sectionStart, Math.min(activationScrollTops[i + 1], maxScrollTop));\n }\n weights.push(Math.max(minSlot, sectionEnd - sectionStart));\n }\n\n const totalWeight = weights.reduce((sum, weight) => sum + weight, 0);\n const scaledPosition = (scrollTop / maxScrollTop) * totalWeight;\n\n let consumed = 0;\n for (let i = 0; i < count; i++) {\n consumed += weights[i];\n if (scaledPosition <= consumed || i === count - 1) {\n return i;\n }\n }\n\n return count - 1;\n }\n\n private applyActiveIndex(activeIndex: number): void {\n if (activeIndex < 0) {\n return;\n }\n\n const current = this.outlineItems();\n if (current.length > 0 && current.every((item, index) => item.active === (index === activeIndex))) {\n return;\n }\n\n this.outlineItems.update((prevItems) =>\n prevItems.map((item, index) => ({\n ...item,\n active: index === activeIndex,\n })),\n );\n this.outlineItems$.next(this.outlineItems());\n }\n\n private setOutlineItems() {\n if (!isPlatformBrowser(this.platformId)) {\n return;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n\n setTimeout(() => {\n const targets = this.target() ? [...this.el.nativeElement.querySelectorAll(this.target())] : [];\n targets.push(...this.el.nativeElement.querySelectorAll('[data-ax-outline-item=\"true\"]'));\n const uniqueTargets = new Set(targets);\n\n const outlineItems = Array.from(uniqueTargets)\n .filter((el) => el.getAttribute('data-ax-outline-item') !== 'false')\n .map((el) => {\n const htmlEl = el as HTMLElement;\n let fragment = htmlEl.id;\n if (!fragment) {\n const textContentForId = htmlEl.textContent?.trim() ?? '';\n if (textContentForId) {\n fragment = `${textContentForId.toLowerCase().replace(/\\s+/g, '-')}`;\n let counter = 1;\n const originalFragment = fragment;\n while (this.document.getElementById(fragment)) {\n fragment = `${originalFragment}-${counter}`;\n counter++;\n }\n } else {\n fragment = `ax-outline-${Math.random().toString(36).slice(2, 7)}`;\n }\n htmlEl.id = fragment;\n }\n\n htmlEl.style.scrollMargin = `${this.activationOffset()}px`;\n\n const existingLink = htmlEl.querySelector('a.ax-outline-hash-link');\n if (existingLink) {\n existingLink.remove();\n }\n\n if (this.showHashItem() && isPlatformBrowser(this.platformId)) {\n const anchor = this.document.createElement('a');\n anchor.textContent = '#';\n anchor.href = `${window.location.pathname}${window.location.search}#${fragment}`;\n anchor.classList.add('ax-outline-hash-link');\n\n anchor.style.paddingInlineStart = '0.5rem';\n anchor.style.opacity = '0';\n anchor.style.transition = 'opacity 0.2s ease-in-out';\n anchor.style.cursor = 'pointer';\n anchor.setAttribute('aria-hidden', 'true');\n anchor.setAttribute('fragment', fragment);\n\n const enterListener = () => (anchor.style.opacity = '1');\n const leaveListener = () => (anchor.style.opacity = '0');\n\n htmlEl.addEventListener('mouseenter', enterListener);\n htmlEl.addEventListener('mouseleave', leaveListener);\n\n htmlEl.appendChild(anchor);\n\n if (this.copyUrlOnClick()) {\n anchor.addEventListener('click', async (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.scrollToItem(fragment);\n try {\n await this.clipboardService.copy(anchor.href);\n } catch (err) {\n console.error('Failed to copy outline URL:', err);\n }\n });\n }\n }\n\n const parentId = htmlEl.getAttribute('data-parent') ?? undefined;\n\n const scrollableElement = this.scrollableElement();\n const scrollableRect = scrollableElement?.getBoundingClientRect() ?? { top: 0 };\n const elementRect = htmlEl.getBoundingClientRect();\n const relativeScrollY = elementRect.top - scrollableRect.top + (scrollableElement?.scrollTop ?? 0);\n\n return {\n el: htmlEl,\n id: fragment,\n active: false,\n parentId: parentId,\n scrollY: relativeScrollY,\n hasAnchor: this.showHashItem(),\n };\n })\n .sort((a, b) => a.scrollY - b.scrollY);\n\n this.outlineItems.set(outlineItems);\n\n const hashId = decodeURIComponent(this.document.defaultView?.location.hash?.slice(1) ?? '');\n if (hashId && outlineItems.some((item) => item.id === hashId)) {\n const hashIndex = outlineItems.findIndex((item) => item.id === hashId);\n this.lastScrollSpyIndex = hashIndex;\n this.applyActiveIndex(hashIndex);\n } else {\n this.scrollChanged(this.readScrollTop());\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.observe(this.el.nativeElement, {\n childList: true,\n subtree: true,\n });\n }\n });\n }\n\n public refreshOutlineItems() {\n this.setOutlineItems();\n }\n}\n","import { afterNextRender, Directive, ElementRef, inject, input } from '@angular/core';\n\n@Directive({\n selector: '[axOutlineItem]',\n exportAs: 'axOutlineItem',\n})\nexport class AXOutlineItemDirective {\n private el = inject(ElementRef);\n\n id = input<string>();\n disabled = input(false);\n\n #anr = afterNextRender(() => {\n const element = this.el.nativeElement as HTMLElement;\n element.setAttribute('data-ax-outline-item', this.disabled() ? 'false' : 'true');\n\n let newId;\n if (!this.id()) {\n const textContent = this.el.nativeElement.textContent.trim();\n if (textContent) {\n newId = `${textContent.toLowerCase().replace(/\\s+/g, '-')}`;\n } else {\n newId = `${Math.random().toString(36).slice(2, 7)}`;\n }\n this.el.nativeElement.id = newId;\n }\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -27,6 +27,8 @@ declare class AXOutlineContainerDirective implements OnDestroy, AfterViewInit {
|
|
|
27
27
|
scrollableElementId: _angular_core.InputSignal<string>;
|
|
28
28
|
private scrollTop;
|
|
29
29
|
private outlineItems;
|
|
30
|
+
private lastScrollSpyIndex;
|
|
31
|
+
private heldActiveIndex;
|
|
30
32
|
private scrollableElement;
|
|
31
33
|
private mutationSubject;
|
|
32
34
|
private readonly MUTATION_DEBOUNCE_TIME;
|
|
@@ -34,7 +36,25 @@ declare class AXOutlineContainerDirective implements OnDestroy, AfterViewInit {
|
|
|
34
36
|
outlineItems$: BehaviorSubject<outlineItemType[]>;
|
|
35
37
|
ngOnDestroy(): void;
|
|
36
38
|
ngAfterViewInit(): void;
|
|
39
|
+
scrollToItem(id: string): void;
|
|
40
|
+
private resolveScrollEventTarget;
|
|
41
|
+
private readScrollTop;
|
|
42
|
+
private handleInContentOutlineLinkClick;
|
|
43
|
+
private scrollToItemFromHash;
|
|
44
|
+
private releaseHeldActiveIndex;
|
|
45
|
+
private stopOngoingSmoothScroll;
|
|
46
|
+
private getOutlineIdFromHref;
|
|
47
|
+
private syncLocationHash;
|
|
37
48
|
private scrollChanged;
|
|
49
|
+
private bindUserScrollIntent;
|
|
50
|
+
private resolveActiveIndex;
|
|
51
|
+
/**
|
|
52
|
+
* Maps scroll position to the active outline item. Sections with little content often
|
|
53
|
+
* have overlapping activation thresholds; each section gets a minimum scroll slot so
|
|
54
|
+
* short blocks are not skipped while scrolling.
|
|
55
|
+
*/
|
|
56
|
+
private resolveByScrollSlots;
|
|
57
|
+
private applyActiveIndex;
|
|
38
58
|
private setOutlineItems;
|
|
39
59
|
refreshOutlineItems(): void;
|
|
40
60
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXOutlineContainerDirective, never>;
|