@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.
@@ -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] Match clicked:', matchData);
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
- offset += col + (e.offsetX / matchEl.offsetWidth * matchEl.textContent.length);
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();