@trustquery/browser 0.2.6 → 0.2.8
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/dist/trustquery.js +160 -3
- package/dist/trustquery.js.map +1 -1
- package/package.json +1 -1
- package/src/InteractionHandler.js +48 -2
- package/src/TrustQuery.js +112 -1
package/dist/trustquery.js
CHANGED
|
@@ -1506,16 +1506,42 @@ class InteractionHandler {
|
|
|
1506
1506
|
const behavior = matchEl.getAttribute('data-behavior');
|
|
1507
1507
|
const matchData = this.getMatchData(matchEl);
|
|
1508
1508
|
|
|
1509
|
-
console.log('[InteractionHandler]
|
|
1509
|
+
console.log('[InteractionHandler] ===== CLICK EVENT START =====');
|
|
1510
|
+
console.log('[InteractionHandler] Click details:', {
|
|
1511
|
+
behavior: behavior,
|
|
1512
|
+
matchText: matchData.text,
|
|
1513
|
+
eventType: e.type,
|
|
1514
|
+
target: e.target.tagName,
|
|
1515
|
+
currentTarget: e.currentTarget.tagName,
|
|
1516
|
+
button: e.button,
|
|
1517
|
+
buttons: e.buttons,
|
|
1518
|
+
clientX: e.clientX,
|
|
1519
|
+
clientY: e.clientY,
|
|
1520
|
+
offsetX: e.offsetX,
|
|
1521
|
+
offsetY: e.offsetY
|
|
1522
|
+
});
|
|
1523
|
+
console.log('[InteractionHandler] Match element:', {
|
|
1524
|
+
textContent: matchEl.textContent,
|
|
1525
|
+
offsetWidth: matchEl.offsetWidth,
|
|
1526
|
+
offsetHeight: matchEl.offsetHeight,
|
|
1527
|
+
attributes: {
|
|
1528
|
+
'data-line': matchEl.getAttribute('data-line'),
|
|
1529
|
+
'data-col': matchEl.getAttribute('data-col'),
|
|
1530
|
+
'data-behavior': behavior
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
console.log('[InteractionHandler] Active element before click:', document.activeElement.tagName, document.activeElement.id || '(no id)');
|
|
1510
1534
|
|
|
1511
1535
|
// For non-interactive elements (bubbles), manually pass click to textarea
|
|
1512
1536
|
if (behavior !== 'dropdown' && behavior !== 'action') {
|
|
1537
|
+
console.log('[InteractionHandler] Non-interactive match - manually focusing textarea');
|
|
1513
1538
|
e.preventDefault();
|
|
1514
1539
|
e.stopPropagation();
|
|
1515
1540
|
|
|
1516
1541
|
// Focus textarea and position cursor at click location
|
|
1517
1542
|
if (this.options.textarea) {
|
|
1518
1543
|
this.options.textarea.focus();
|
|
1544
|
+
console.log('[InteractionHandler] Textarea focused. Active element now:', document.activeElement.tagName, document.activeElement.id || '(no id)');
|
|
1519
1545
|
|
|
1520
1546
|
// Get the character offset by finding the match position
|
|
1521
1547
|
const line = parseInt(matchEl.getAttribute('data-line'));
|
|
@@ -1527,15 +1553,33 @@ class InteractionHandler {
|
|
|
1527
1553
|
for (let i = 0; i < line; i++) {
|
|
1528
1554
|
offset += lines[i].length + 1; // +1 for newline
|
|
1529
1555
|
}
|
|
1530
|
-
|
|
1556
|
+
const clickOffsetInMatch = (e.offsetX / matchEl.offsetWidth * matchEl.textContent.length);
|
|
1557
|
+
offset += col + clickOffsetInMatch;
|
|
1558
|
+
|
|
1559
|
+
console.log('[InteractionHandler] Cursor positioning:', {
|
|
1560
|
+
line: line,
|
|
1561
|
+
col: col,
|
|
1562
|
+
clickOffsetInMatch: clickOffsetInMatch,
|
|
1563
|
+
finalOffset: offset,
|
|
1564
|
+
textareaValue: this.options.textarea.value,
|
|
1565
|
+
textareaValueLength: this.options.textarea.value.length
|
|
1566
|
+
});
|
|
1531
1567
|
|
|
1532
1568
|
// Set cursor position
|
|
1533
1569
|
this.options.textarea.setSelectionRange(offset, offset);
|
|
1570
|
+
|
|
1571
|
+
console.log('[InteractionHandler] Selection set:', {
|
|
1572
|
+
selectionStart: this.options.textarea.selectionStart,
|
|
1573
|
+
selectionEnd: this.options.textarea.selectionEnd,
|
|
1574
|
+
selectedText: this.options.textarea.value.substring(this.options.textarea.selectionStart, this.options.textarea.selectionEnd)
|
|
1575
|
+
});
|
|
1534
1576
|
}
|
|
1535
1577
|
|
|
1578
|
+
console.log('[InteractionHandler] ===== CLICK EVENT END (non-interactive) =====');
|
|
1536
1579
|
return; // Don't process further for bubbles
|
|
1537
1580
|
}
|
|
1538
1581
|
|
|
1582
|
+
console.log('[InteractionHandler] Interactive match - handling dropdown/action');
|
|
1539
1583
|
// Prevent default for interactive elements (dropdown/action)
|
|
1540
1584
|
e.preventDefault();
|
|
1541
1585
|
e.stopPropagation();
|
|
@@ -1559,6 +1603,8 @@ class InteractionHandler {
|
|
|
1559
1603
|
if (this.options.onWordClick && !(behavior === 'dropdown' && this.dropdownManager.activeDropdownMatch === matchEl)) {
|
|
1560
1604
|
this.options.onWordClick(matchData);
|
|
1561
1605
|
}
|
|
1606
|
+
|
|
1607
|
+
console.log('[InteractionHandler] ===== CLICK EVENT END (interactive) =====');
|
|
1562
1608
|
}
|
|
1563
1609
|
|
|
1564
1610
|
/**
|
|
@@ -2974,12 +3020,121 @@ class TrustQuery {
|
|
|
2974
3020
|
this.overlay.scrollLeft = this.textarea.scrollLeft;
|
|
2975
3021
|
});
|
|
2976
3022
|
|
|
3023
|
+
// Keyboard event logging for debugging selection issues
|
|
3024
|
+
this.textarea.addEventListener('keydown', (e) => {
|
|
3025
|
+
const isCmdOrCtrl = e.metaKey || e.ctrlKey;
|
|
3026
|
+
const isSelectAll = (e.metaKey || e.ctrlKey) && e.key === 'a';
|
|
3027
|
+
|
|
3028
|
+
if (isCmdOrCtrl || isSelectAll) {
|
|
3029
|
+
console.log('[TrustQuery] ===== KEYBOARD EVENT =====');
|
|
3030
|
+
console.log('[TrustQuery] Key pressed:', {
|
|
3031
|
+
key: e.key,
|
|
3032
|
+
code: e.code,
|
|
3033
|
+
metaKey: e.metaKey,
|
|
3034
|
+
ctrlKey: e.ctrlKey,
|
|
3035
|
+
shiftKey: e.shiftKey,
|
|
3036
|
+
altKey: e.altKey,
|
|
3037
|
+
isSelectAll: isSelectAll
|
|
3038
|
+
});
|
|
3039
|
+
console.log('[TrustQuery] Active element:', document.activeElement.tagName, document.activeElement.id || '(no id)');
|
|
3040
|
+
console.log('[TrustQuery] Textarea state BEFORE:', {
|
|
3041
|
+
value: this.textarea.value,
|
|
3042
|
+
valueLength: this.textarea.value.length,
|
|
3043
|
+
selectionStart: this.textarea.selectionStart,
|
|
3044
|
+
selectionEnd: this.textarea.selectionEnd,
|
|
3045
|
+
selectedText: this.textarea.value.substring(this.textarea.selectionStart, this.textarea.selectionEnd)
|
|
3046
|
+
});
|
|
3047
|
+
|
|
3048
|
+
if (isSelectAll) {
|
|
3049
|
+
// Log state after select all (use setTimeout to let browser process the event)
|
|
3050
|
+
setTimeout(() => {
|
|
3051
|
+
console.log('[TrustQuery] Textarea state AFTER CMD+A:', {
|
|
3052
|
+
selectionStart: this.textarea.selectionStart,
|
|
3053
|
+
selectionEnd: this.textarea.selectionEnd,
|
|
3054
|
+
selectedText: this.textarea.value.substring(this.textarea.selectionStart, this.textarea.selectionEnd),
|
|
3055
|
+
selectedLength: this.textarea.selectionEnd - this.textarea.selectionStart
|
|
3056
|
+
});
|
|
3057
|
+
console.log('[TrustQuery] ===== KEYBOARD EVENT END =====');
|
|
3058
|
+
}, 0);
|
|
3059
|
+
} else {
|
|
3060
|
+
console.log('[TrustQuery] ===== KEYBOARD EVENT END =====');
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
});
|
|
3064
|
+
|
|
3065
|
+
// Selection change event
|
|
3066
|
+
this.textarea.addEventListener('select', (e) => {
|
|
3067
|
+
console.log('[TrustQuery] ===== SELECTION CHANGE EVENT =====');
|
|
3068
|
+
console.log('[TrustQuery] Selection:', {
|
|
3069
|
+
selectionStart: this.textarea.selectionStart,
|
|
3070
|
+
selectionEnd: this.textarea.selectionEnd,
|
|
3071
|
+
selectedText: this.textarea.value.substring(this.textarea.selectionStart, this.textarea.selectionEnd),
|
|
3072
|
+
selectedLength: this.textarea.selectionEnd - this.textarea.selectionStart
|
|
3073
|
+
});
|
|
3074
|
+
});
|
|
3075
|
+
|
|
3076
|
+
// Context menu event - prevent keyboard-triggered context menu
|
|
3077
|
+
this.textarea.addEventListener('contextmenu', (e) => {
|
|
3078
|
+
console.log('[TrustQuery] ===== CONTEXTMENU EVENT =====');
|
|
3079
|
+
console.log('[TrustQuery] Context menu triggered:', {
|
|
3080
|
+
type: e.type,
|
|
3081
|
+
isTrusted: e.isTrusted,
|
|
3082
|
+
button: e.button,
|
|
3083
|
+
buttons: e.buttons,
|
|
3084
|
+
clientX: e.clientX,
|
|
3085
|
+
clientY: e.clientY,
|
|
3086
|
+
ctrlKey: e.ctrlKey,
|
|
3087
|
+
metaKey: e.metaKey,
|
|
3088
|
+
target: e.target.tagName
|
|
3089
|
+
});
|
|
3090
|
+
|
|
3091
|
+
// Prevent context menu if triggered by keyboard (button === -1)
|
|
3092
|
+
// This prevents the macOS context menu from opening after CMD+A
|
|
3093
|
+
if (e.button === -1 && e.buttons === 0) {
|
|
3094
|
+
console.log('[TrustQuery] Preventing keyboard-triggered context menu');
|
|
3095
|
+
e.preventDefault();
|
|
3096
|
+
e.stopPropagation();
|
|
3097
|
+
return;
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
console.log('[TrustQuery] Allowing mouse-triggered context menu');
|
|
3101
|
+
});
|
|
3102
|
+
|
|
3103
|
+
// Also prevent context menu on overlay (it interferes with text selection)
|
|
3104
|
+
this.overlay.addEventListener('contextmenu', (e) => {
|
|
3105
|
+
console.log('[TrustQuery] ===== CONTEXTMENU EVENT ON OVERLAY =====');
|
|
3106
|
+
console.log('[TrustQuery] Context menu on overlay - preventing');
|
|
3107
|
+
|
|
3108
|
+
// Always prevent context menu on overlay
|
|
3109
|
+
// The overlay should be transparent to user interactions
|
|
3110
|
+
e.preventDefault();
|
|
3111
|
+
e.stopPropagation();
|
|
3112
|
+
});
|
|
3113
|
+
|
|
2977
3114
|
// Focus/blur events - add/remove focus class
|
|
2978
|
-
this.textarea.addEventListener('focus', () => {
|
|
3115
|
+
this.textarea.addEventListener('focus', (e) => {
|
|
3116
|
+
console.log('[TrustQuery] ===== FOCUS EVENT =====');
|
|
3117
|
+
console.log('[TrustQuery] Textarea focused. Active element:', document.activeElement.tagName, document.activeElement.id || '(no id)');
|
|
3118
|
+
console.log('[TrustQuery] Current selection:', {
|
|
3119
|
+
selectionStart: this.textarea.selectionStart,
|
|
3120
|
+
selectionEnd: this.textarea.selectionEnd
|
|
3121
|
+
});
|
|
2979
3122
|
this.wrapper.classList.add('tq-focused');
|
|
2980
3123
|
});
|
|
2981
3124
|
|
|
2982
3125
|
this.textarea.addEventListener('blur', (e) => {
|
|
3126
|
+
console.log('[TrustQuery] ===== BLUR EVENT =====');
|
|
3127
|
+
console.log('[TrustQuery] Textarea blurred. Related target:', e.relatedTarget?.tagName || '(none)');
|
|
3128
|
+
console.log('[TrustQuery] Blur event details:', {
|
|
3129
|
+
type: e.type,
|
|
3130
|
+
isTrusted: e.isTrusted,
|
|
3131
|
+
eventPhase: e.eventPhase,
|
|
3132
|
+
target: e.target.tagName,
|
|
3133
|
+
currentTarget: e.currentTarget.tagName
|
|
3134
|
+
});
|
|
3135
|
+
console.log('[TrustQuery] Stack trace at blur:');
|
|
3136
|
+
console.trace();
|
|
3137
|
+
|
|
2983
3138
|
// Close dropdown when textarea loses focus (unless interacting with dropdown)
|
|
2984
3139
|
if (this.interactionHandler) {
|
|
2985
3140
|
// Use setTimeout to let the new focus target be set and check if clicking on dropdown
|
|
@@ -2990,6 +3145,8 @@ class TrustQuery {
|
|
|
2990
3145
|
activeElement.closest('.tq-dropdown') // Check if clicking anywhere in dropdown
|
|
2991
3146
|
);
|
|
2992
3147
|
|
|
3148
|
+
console.log('[TrustQuery] After blur - active element:', activeElement?.tagName || '(none)', 'isDropdownRelated:', isDropdownRelated);
|
|
3149
|
+
|
|
2993
3150
|
// Only close if not interacting with dropdown
|
|
2994
3151
|
if (!isDropdownRelated) {
|
|
2995
3152
|
this.interactionHandler.hideDropdown();
|