@salesforcedevs/docs-components 1.17.8-hover-edit → 1.17.11-hover-edit
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.
package/package.json
CHANGED
|
@@ -19,17 +19,28 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
19
19
|
private selectionStart: number = 0;
|
|
20
20
|
private selectionEnd: number = 0;
|
|
21
21
|
private initialPopoverStyle: string = ""; // Store initial position
|
|
22
|
+
private mutationObserver: MutationObserver | null = null;
|
|
23
|
+
private lastMouseX: number = 0;
|
|
24
|
+
private lastMouseY: number = 0;
|
|
22
25
|
|
|
23
26
|
connectedCallback() {
|
|
24
27
|
console.log('TextSelectionSearch: Component connected');
|
|
25
28
|
console.log('TextSelectionSearch: Document ready state:', document.readyState);
|
|
26
29
|
console.log('TextSelectionSearch: Current page URL:', window.location.href);
|
|
27
30
|
this.setupTextSelectionListener();
|
|
31
|
+
this.setupContentObserver();
|
|
32
|
+
|
|
33
|
+
// Additional initialization for spec-based references
|
|
34
|
+
if (this.isSpecBasedReferencePage()) {
|
|
35
|
+
console.log('TextSelectionSearch: Detected spec-based reference page, setting up additional listeners');
|
|
36
|
+
this.setupSpecBasedReferenceHandling();
|
|
37
|
+
}
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
disconnectedCallback() {
|
|
31
41
|
console.log('TextSelectionSearch: Component disconnected');
|
|
32
42
|
this.removeTextSelectionListener();
|
|
43
|
+
this.removeContentObserver();
|
|
33
44
|
}
|
|
34
45
|
|
|
35
46
|
// Setup text selection listener
|
|
@@ -37,7 +48,11 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
37
48
|
console.log('TextSelectionSearch: Setting up text selection listeners');
|
|
38
49
|
try {
|
|
39
50
|
// Use capture phase to ensure we get the events
|
|
40
|
-
document.addEventListener("mouseup", (event) =>
|
|
51
|
+
document.addEventListener("mouseup", (event) => {
|
|
52
|
+
this.lastMouseX = event.clientX;
|
|
53
|
+
this.lastMouseY = event.clientY;
|
|
54
|
+
this.handleTextSelection(event);
|
|
55
|
+
}, true);
|
|
41
56
|
document.addEventListener("keyup", (event) => this.handleTextSelection(event), true);
|
|
42
57
|
console.log('TextSelectionSearch: Event listeners attached successfully');
|
|
43
58
|
} catch (error) {
|
|
@@ -56,6 +71,84 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
73
|
|
|
74
|
+
// Setup observer to detect when content is dynamically loaded
|
|
75
|
+
setupContentObserver() {
|
|
76
|
+
console.log('TextSelectionSearch: Setting up content observer');
|
|
77
|
+
try {
|
|
78
|
+
this.mutationObserver = new MutationObserver((mutations) => {
|
|
79
|
+
let shouldReinitialize = false;
|
|
80
|
+
|
|
81
|
+
for (const mutation of mutations) {
|
|
82
|
+
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
|
83
|
+
// Check if any added nodes contain text content
|
|
84
|
+
for (const node of Array.from(mutation.addedNodes)) {
|
|
85
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
86
|
+
const element = node as Element;
|
|
87
|
+
|
|
88
|
+
// Check for spec-based reference content (.api-documentation)
|
|
89
|
+
if (element.classList && element.classList.contains('api-documentation')) {
|
|
90
|
+
console.log('TextSelectionSearch: Detected .api-documentation container');
|
|
91
|
+
shouldReinitialize = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Check for doc-amf-topic component
|
|
96
|
+
if (element.tagName && element.tagName.toLowerCase() === 'doc-amf-topic') {
|
|
97
|
+
console.log('TextSelectionSearch: Detected doc-amf-topic component');
|
|
98
|
+
shouldReinitialize = true;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check for shadow DOM content in spec-based references
|
|
103
|
+
if (this.isSpecBasedReferencePage() && element.shadowRoot) {
|
|
104
|
+
console.log('TextSelectionSearch: Detected shadow DOM content');
|
|
105
|
+
shouldReinitialize = true;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Check for common content containers
|
|
110
|
+
if (element.querySelector && (
|
|
111
|
+
element.querySelector('p, h1, h2, h3, h4, h5, h6, li, td, th, div') ||
|
|
112
|
+
element.matches('p, h1, h2, h3, h4, h5, h6, li, td, th, div')
|
|
113
|
+
)) {
|
|
114
|
+
shouldReinitialize = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (shouldReinitialize) {
|
|
123
|
+
console.log('TextSelectionSearch: Content detected, reinitializing listeners');
|
|
124
|
+
// Small delay to ensure content is fully rendered
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
this.setupTextSelectionListener();
|
|
127
|
+
}, 200); // Increased delay for spec-based references
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Observe the entire document for content changes
|
|
132
|
+
this.mutationObserver.observe(document.body, {
|
|
133
|
+
childList: true,
|
|
134
|
+
subtree: true
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
console.log('TextSelectionSearch: Content observer set up successfully');
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error('TextSelectionSearch: Error setting up content observer:', error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
removeContentObserver() {
|
|
144
|
+
console.log('TextSelectionSearch: Removing content observer');
|
|
145
|
+
if (this.mutationObserver) {
|
|
146
|
+
this.mutationObserver.disconnect();
|
|
147
|
+
this.mutationObserver = null;
|
|
148
|
+
console.log('TextSelectionSearch: Content observer removed successfully');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
59
152
|
// Handle text selection
|
|
60
153
|
handleTextSelection(event?: Event) {
|
|
61
154
|
// If popover is visible, completely ignore all text selection events
|
|
@@ -97,6 +190,31 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
97
190
|
this.selectedText = selection.toString().trim();
|
|
98
191
|
console.log('TextSelectionSearch: Selected text:', this.selectedText);
|
|
99
192
|
|
|
193
|
+
// For spec-based references, check if selection is within the API documentation container
|
|
194
|
+
if (this.isSpecBasedReferencePage()) {
|
|
195
|
+
const apiDocContainer = document.querySelector('.api-documentation');
|
|
196
|
+
if (apiDocContainer) {
|
|
197
|
+
const range = selection.getRangeAt(0);
|
|
198
|
+
const rect = range.getBoundingClientRect();
|
|
199
|
+
const containerRect = apiDocContainer.getBoundingClientRect();
|
|
200
|
+
|
|
201
|
+
// Check if the selection is within the API documentation container
|
|
202
|
+
const isWithinContainer = (
|
|
203
|
+
rect.top >= containerRect.top &&
|
|
204
|
+
rect.bottom <= containerRect.bottom &&
|
|
205
|
+
rect.left >= containerRect.left &&
|
|
206
|
+
rect.right <= containerRect.right
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
console.log('TextSelectionSearch: Selection within API container:', isWithinContainer);
|
|
210
|
+
|
|
211
|
+
if (!isWithinContainer) {
|
|
212
|
+
console.log('TextSelectionSearch: Selection outside API container, ignoring');
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
100
218
|
if (this.selectedText.length > 0) {
|
|
101
219
|
this.showPopover();
|
|
102
220
|
}
|
|
@@ -111,24 +229,28 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
111
229
|
return;
|
|
112
230
|
}
|
|
113
231
|
|
|
114
|
-
|
|
115
|
-
const rect =
|
|
116
|
-
|
|
232
|
+
// Use a simpler, more reliable positioning approach
|
|
233
|
+
const rect = selection.getRangeAt(0).getBoundingClientRect();
|
|
117
234
|
console.log('TextSelectionSearch: Selection rect:', rect);
|
|
118
|
-
console.log('TextSelectionSearch: Window dimensions:', window.innerWidth, window.innerHeight);
|
|
119
|
-
console.log('TextSelectionSearch: Scroll position:', window.scrollX, window.scrollY);
|
|
120
|
-
console.log('TextSelectionSearch: Document height:', document.documentElement.scrollHeight);
|
|
121
235
|
|
|
122
|
-
//
|
|
236
|
+
// Check if we're on a spec-based reference page
|
|
237
|
+
const isSpecBased = this.isSpecBasedReferencePage();
|
|
238
|
+
console.log('TextSelectionSearch: Is spec-based reference:', isSpecBased);
|
|
239
|
+
|
|
240
|
+
// Use mouse position as fallback for better positioning
|
|
241
|
+
const mouseX = this.lastMouseX || rect.left + rect.width / 2;
|
|
242
|
+
const mouseY = this.lastMouseY || rect.top;
|
|
243
|
+
|
|
244
|
+
console.log('TextSelectionSearch: Using mouse position:', mouseX, mouseY);
|
|
245
|
+
|
|
246
|
+
// Calculate popover position
|
|
247
|
+
const popoverLeft = Math.max(10, Math.min(window.innerWidth - 360, mouseX - 175)); // Center on mouse
|
|
123
248
|
let popoverTop: number;
|
|
124
|
-
const popoverLeft = Math.max(10, Math.min(window.innerWidth - 360, rect.left + (rect.width / 2) - 180));
|
|
125
249
|
|
|
126
250
|
if (this.popoverPosition === "top") {
|
|
127
|
-
//
|
|
128
|
-
popoverTop = Math.max(10, rect.top - 200); // 200px above selection
|
|
251
|
+
popoverTop = Math.max(10, mouseY - 220); // Above mouse cursor
|
|
129
252
|
} else {
|
|
130
|
-
//
|
|
131
|
-
popoverTop = Math.min(window.innerHeight - 250, rect.bottom + 20);
|
|
253
|
+
popoverTop = Math.min(window.innerHeight - 250, mouseY + 20); // Below mouse cursor
|
|
132
254
|
}
|
|
133
255
|
|
|
134
256
|
// Ensure the popover doesn't go off-screen
|
|
@@ -139,10 +261,15 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
139
261
|
popoverTop = window.innerHeight - 250;
|
|
140
262
|
}
|
|
141
263
|
|
|
142
|
-
this.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
264
|
+
this.setPopoverPosition(popoverTop, popoverLeft);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Set the popover position and show it
|
|
268
|
+
setPopoverPosition(top: number, left: number) {
|
|
269
|
+
this.popoverStyle = `position: fixed; top: ${top}px; left: ${left}px; z-index: 9999; width: 350px;`;
|
|
270
|
+
this.initialPopoverStyle = this.popoverStyle;
|
|
271
|
+
console.log('TextSelectionSearch: Final popover style:', this.popoverStyle);
|
|
272
|
+
console.log('TextSelectionSearch: Final position - top:', top, 'left:', left);
|
|
146
273
|
|
|
147
274
|
this.isVisible = true;
|
|
148
275
|
this.isHidden = false;
|
|
@@ -277,4 +404,43 @@ export default class TextSelectionSearch extends LightningElement {
|
|
|
277
404
|
get searchButtonDisabled() {
|
|
278
405
|
return this.isLoading || !this.searchQuery.trim();
|
|
279
406
|
}
|
|
407
|
+
|
|
408
|
+
// Check if current page is a spec-based reference
|
|
409
|
+
isSpecBasedReferencePage(): boolean {
|
|
410
|
+
const url = window.location.href;
|
|
411
|
+
const hasMetaParam = url.includes('?meta=');
|
|
412
|
+
const isReferencePage = url.includes('/references/');
|
|
413
|
+
console.log('TextSelectionSearch: URL analysis - hasMetaParam:', hasMetaParam, 'isReferencePage:', isReferencePage);
|
|
414
|
+
return hasMetaParam && isReferencePage;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Additional setup for spec-based references
|
|
418
|
+
setupSpecBasedReferenceHandling() {
|
|
419
|
+
// Wait for the page to be fully loaded
|
|
420
|
+
if (document.readyState === 'loading') {
|
|
421
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
422
|
+
this.initializeForSpecBasedReference();
|
|
423
|
+
});
|
|
424
|
+
} else {
|
|
425
|
+
this.initializeForSpecBasedReference();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
initializeForSpecBasedReference() {
|
|
430
|
+
console.log('TextSelectionSearch: Initializing for spec-based reference');
|
|
431
|
+
|
|
432
|
+
// Wait for the .api-documentation container to appear
|
|
433
|
+
const checkForApiDocumentation = () => {
|
|
434
|
+
const apiDocContainer = document.querySelector('.api-documentation');
|
|
435
|
+
if (apiDocContainer) {
|
|
436
|
+
console.log('TextSelectionSearch: Found .api-documentation container, setting up listeners');
|
|
437
|
+
this.setupTextSelectionListener();
|
|
438
|
+
} else {
|
|
439
|
+
console.log('TextSelectionSearch: .api-documentation container not found yet, retrying...');
|
|
440
|
+
setTimeout(checkForApiDocumentation, 500);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
checkForApiDocumentation();
|
|
445
|
+
}
|
|
280
446
|
}
|