Skip to content

Conversation

@sensei-hacker
Copy link
Member

Summary

Implements Features 2 & 3 for JavaScript Programming debugging tools:

  • Feature 2 - Code Sync Status: Disables Save button when editor matches FC (no unsaved changes)
  • Feature 3 - Gvar Display: Shows live non-zero global variable values as inline hints next to inav.gvar[N] references

Dependencies

⚠️ This PR depends on #2539 (Active LC Highlighting - Feature 1) and should be merged after #2539.

This branch is based on feature/js-programming-debug-tools and adds Features 2 & 3 on top of Feature 1.

Changes

Feature 2 - Code Sync Status

  • Added updateSaveButtonState() function that manages Save button enabled/disabled state
  • Save button uses existing .disabled CSS class with pointer-events: none
  • Button is disabled when isDirty = false (code matches FC)
  • Called at 9 strategic points after operations affecting isDirty flag

Feature 3 - Gvar Display

  • Created new module js/transpiler/gvar_display.js using Monaco Content Widgets API
  • Implements GvarHintWidget class for inline text display
  • Shows format: // gvar[index] = value at end of line where gvar is referenced
  • Auto-updates every 500ms via MSP polling integration
  • Deduplicates - shows each gvar only once at first occurrence
  • Only displays non-zero values

Code Quality Improvements

  • Comprehensive code review performed using pr-review-toolkit
  • Added error handling to all Monaco widget operations (try-catch blocks)
  • Added error handling to MSP chainer exit point updates
  • Fixed cleanup bug (variable name mismatch)
  • Added console logging for debugging widget failures

Testing

Tested on Hardware

  • Connected to DAKEFPVH743PRO running INAV 9.0.0
  • Verified Feature 2:
    • ✅ Save button disabled when code loaded from FC
    • ✅ Save button enables when code is edited
    • ✅ Button click disabled via CSS pointer-events: none
  • Verified Feature 3:
    • ✅ Gvar hints display correctly: // gvar[0] = 32767
    • ✅ Positioned at end of line with proper spacing
    • ✅ Values update live (500ms polling)
    • ✅ Deduplication works (no duplicate hints)
    • ✅ Only non-zero values shown
    • ✅ Styling is subtle (0.65 opacity, italic, gray)

Code Review

Reviewed with pr-review-toolkit using multiple agents:

  • code-reviewer - General code quality
  • comment-analyzer - Comment accuracy
  • silent-failure-hunter - Error handling
  • code-simplifier - Complexity analysis

All critical issues addressed:

  • Added try-catch around Monaco operations
  • Added try-catch around MSP chainer updates
  • Fixed cleanup variable name bug

Files Changed

  • js/transpiler/gvar_display.js (new) - Gvar display module
  • tabs/javascript_programming.js - Integration and Save button state
  • tabs/javascript_programming.html - CSS for gvar hints

Screenshots

Gvar hints displaying inline with subtle styling, Save button correctly disabled when code matches FC.

Related Issues

Part of JavaScript Programming debugging tools suite.

Augment decompiler to track which Logic Conditions map to which lines
in generated JavaScript code. This enables real-time highlighting of
active conditions in the JavaScript Programming tab.

Key features:
- 3-pass mapping algorithm handles simple, compound, and nested conditions
- Compound conditions (a && b) correctly map all sub-LCs to same line
- Activator chains propagate line numbers to child LCs
- Hoisted variables and sticky/timer patterns tracked
- Returns lcToLineMapping in decompile() result

Part of Feature 1: Active LC Highlighting (Phase 1/5)
Implement real-time status polling and gutter decoration updates in the
JavaScript Programming tab to show which Logic Conditions are currently
active/true.

Key features:
- Status polling every 100ms using MSPChainer
- updateActiveHighlighting() filters true LCs and applies gutter markers
- clearActiveHighlighting() when code is dirty (unsaved changes)
- Proper cleanup on tab switch/disconnect
- isDirty check prevents highlighting stale code

Part of Feature 1: Active LC Highlighting (Phase 2/5)
Implement CSS and Monaco editor configuration for green checkmark gutter
markers that indicate active/true Logic Conditions.

Key changes:
- Add .lc-active-true CSS class with SVG green checkmark icon
- Add Monaco gutter margin background styling
- Enable glyphMargin: true in Monaco editor options
- Set up proper cursor and sizing for gutter decorations

Part of Feature 1: Active LC Highlighting (Phase 3/5)
Fix 'Cannot read properties of null' error in updateActiveHighlighting()
by adding proper null checks for FC.LOGIC_CONDITIONS_STATUS and
FC.LOGIC_CONDITIONS before accessing .get().

This prevents errors during tab initialization when FC data is still loading.
The onChange handler was firing after setValue() during load, causing
isDirty to be set to true even after we cleared it. This prevented the
highlighting from ever appearing because updateActiveHighlighting()
returns early when isDirty is true.

Fixed by using setTimeout() to clear isDirty after the setValue() change
event has been processed.
Previous approach tried to find LCs by parsing the generated code for
/* LC X */ comments, but normal if-statements don't have these comments.

New approach:
- Track LC index and line content during code generation
- After adding boilerplate, search for the tracked lines in final code
- Map LC index to actual line numbers in final output

This ensures all if-statements and their associated LCs get mapped
correctly for the active highlighting feature.
Track what's being searched for and what's being found to diagnose
why the LC-to-line mapping is empty.
This will help us diagnose why the green checkmarks aren't appearing
by logging:
- When the function is called
- If isDirty is blocking it
- What the LC-to-line mapping is
- If FC data is available
- Which LCs are TRUE
- What lines should be highlighted
- If decorations are created
FC.LOGIC_CONDITIONS_STATUS.get() requires a condition index parameter
and returns a single value. We need getAll() to get the entire status array.

This was causing 'FC data is null' errors and preventing any highlighting
from appearing.
This completes the active LC highlighting feature with two major improvements:

1. FALSE condition indicators: Gray hollow circles (○) display when conditions
   evaluate to FALSE, complementing the existing green checkmarks for TRUE
   conditions. Mixed states (TRUE and FALSE on same line) show green checkmark.

2. Transpiler-side line tracking: LC-to-line mappings are now generated during
   transpilation, providing immediate visual feedback after "Transpile" or
   "Save to FC" without requiring "Load from FC" roundtrip. Correctly adjusts
   for auto-added import statement offset.

Technical changes:
- Add lineOffset tracking in codegen to account for prepended import lines
- Store currentSourceLine context during statement generation
- Return lcToLineMapping in transpiler result
- Update tab to use transpiler mapping immediately after transpile/save
- Change polling interval from 100ms to 500ms to reduce MSP load (2Hz vs 10Hz)
- Reorder checks: verify FC data availability before isDirty state
- Clean up excessive debug logging for production readiness

Testing:
- Verified circles appear on correct lines after transpile
- Tested TRUE/FALSE/MIXED states display properly
- Confirmed decompiler mapping replaces transpiler mapping on load
- Reviewed with inav-code-review agent - all critical issues resolved
Fixes all 6 medium-priority issues identified by qodo-merge bot:
1. Clear stale decorations when loading code from FC
2. Clear mapping/decorations when loading default code
3. Add in-flight guard to prevent overlapping MSP polling requests
4. Remove duplicate intervals before adding new one
5. Improve type safety with Array.isArray() checks for MSP data

Code organization improvements:
- Extract highlighting logic to new module js/transpiler/lc_highlighting.js
- Reduce tab file from 928 to 893 lines (-35 lines)
- Create 5 testable, pure functions: categorizeLCsByStatus(),
  mapLCsToLines(), createMonacoDecorations(), applyDecorations(),
  clearDecorations()
- Better separation of concerns (tab orchestrates, module implements)
- Improved code maintainability and testability
Implement visual indicator showing when JavaScript editor content matches
flight controller storage vs when changes exist locally.

Key features:
- Save button disabled when isDirty=false (code matches FC)
- Save button enabled when isDirty=true (unsaved changes)
- updateSaveButtonState() called at all isDirty change points
- Uses existing .disabled CSS styling for visual feedback

Part of Feature 2: Code Sync Status
…ing tab

Feature 2 - Code Sync Status:
- Disable Save button when editor matches FC (isDirty = false)
- Enable Save button when code is modified (isDirty = true)
- Uses existing .disabled CSS class with pointer-events: none

Feature 3 - Gvar Display:
- Display live non-zero global variable values as inline hints
- Format: // gvar[index] = value
- Position at end of line where gvar is referenced
- Deduplicate - show each gvar only once at first occurrence
- Auto-update at 500ms intervals via MSP polling
- Implemented using Monaco Content Widgets API

Implementation details:
- Created js/transpiler/gvar_display.js module for gvar functionality
- Added updateSaveButtonState() to manage Save button state
- Added updateGvarDisplay() for real-time gvar value display
- Integrated with existing MSPChainer for efficient polling
- CSS styling: opacity 0.65, italic, subtle gray color
After code review, added critical error handling to prevent silent failures:
- Monaco widget operations now wrapped in try-catch blocks
- MSP chainer exit point updates protected with error handling
- Fixed cleanup bug (gvarDecorations -> gvarWidgets)
- Added console logging for debugging widget failures

These changes ensure the gvar display feature degrades gracefully
instead of breaking the polling loop if Monaco operations fail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant