Maintenance 9.x to master#2635
Conversation
**Problem:**
When decompiling logic conditions with activator hoisting and a stored
variable map, all spaces between words were being replaced with custom
variable names (e.g., "const min" became "constmin", comments like
"INAV JavaScript Programming" became "INAVminJavaScriptminProgramming").
**Root Cause:**
In decompiler.js applyCustomVariableNames() at line 293, the code was
storing entire objects from hoistedActivatorVars instead of extracting
the varName string:
const entry = { varName: 'cond1', scopeLcIndex: -1 }
When this object was used in a template literal to build a regex pattern:
`\\b${entry}\\b` → `\\b[object Object]\\b`
In regex, `[object Object]` is a CHARACTER CLASS that matches any single
character from the set: {o,b,j,e,c,t,space,O}. This caused the regex
pattern `\\b[object Object]\\b` to match spaces between word boundaries,
replacing them with the custom variable name.
**Fix:**
Changed line 293-294 to extract the .varName property:
- Before: lcIndexToGeneratedName.set(lcIndex, generatedName);
- After: lcIndexToGeneratedName.set(lcIndex, entry.varName);
This ensures the regex replacement uses the actual variable name string
instead of "[object Object]" character class.
**Files Changed:**
- js/transpiler/transpiler/decompiler.js
**Testing:**
Verified with test cases showing the fix prevents space replacement in
both code and comments.
The motor direction selector (normal/reverse) was only partially hidden for fixed wing and other non-multirotor platforms because the jQuery selector targeted the label rather than the container div. Add an ID to the container and target it directly so the entire fieldset is hidden.
Replace the split two-panel layout (left: enable/position, right: slot config) with self-contained collapsible cards in the left panel. Each card has an enable toggle, preview text, and expand/collapse in the header, with slot configuration in the card body. Key changes: - Split the 28-option flat type dropdown into a 7-option source select (None, Text, Icon static/GV/LC, Global Variable, Logic Condition) plus a 12-option format select shown only for GV/LC sources - Progressive disclosure: configured cards expanded with blue border, first unconfigured expanded, rest collapsed - Hidden original type selects preserve save/load compatibility with existing fillCustomElementsValues() and customElementGetDataForRow() - Cards rebuild on every updateFields() call (layout switch, search) - Right panel custom element section hidden
- Transpose table columns to stacked rows: each slot gets its own row
with [source select] [value input] side by side
- Visibility select gets its own row at bottom
- Replace table/tr/td structure with flexbox div rows (.ce-slot-row)
- Fix card header preview: generate plain-text summary instead of using
OSD font characters (FONT.symbol) which render as boxes in HTML
- Fix invisible inputs: add 'settings' class to card body for borders
- Update customElementsInitCallback to use card data-ce-index instead
of closest('tr').data('row') since table structure is removed
Replace bare number input for Icon (static/GV/LC) with a clickable preview button that opens a popup grid of all 255 OSD font characters. User clicks a glyph tile to select it. The selected icon shows as an inline preview image with its character number.
Unit-converted values like "328.08 ft" (from 100m) and "9842.52 ft" (from 3000m) showed excessive decimal precision. Add a smartRound() function that removes unnecessary decimals when rounding changes the value by less than 1%, and snaps to nearby round numbers (e.g. 999→1000) when within 0.1%. Applies to all data-unit converted settings inputs and OSD distance alarm display.
Settings.configureInputs() populates the radio buttons asynchronously via MSP, but the mixer preset change handler fires synchronously during init, before those requests complete. As a result updateMotorDirection() read an unpopulated radio button and always rendered the normal (non-reversed) SVG. Re-run updateMotorDirection() after settingsPromise resolves so the arrow reflects the actual FC setting. Fixes iNavFlight/inav#11316
- Add Angle Hold (mode 16) to flight mode operand types in classic programming tab (logicConditionOperantTypes.js). Firmware defines LOGIC_CONDITION_OPERAND_FLIGHT_MODE_ANGLEHOLD = 16 but it was missing from the UI, preventing users from selecting it as a flight mode operand. - Add OPERATION_NAMES[56] (Override Min Ground Speed) to inav_constants.js. OPERATION.OVERRIDE_MIN_GROUND_SPEED = 56 was present but the human-readable name was missing, causing 'unknown_operation_56' in warning messages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On initial tab load, $mixerPreset.trigger('change') calls
updateMotorDirection() synchronously before Settings.configureInputs()
has populated the motor_direction_inverted radio buttons via async MSP
requests. This meant the default (props-in) image was always shown even
when the FC had reversed motor direction configured.
Fix: accept the settingsPromise passed by Settings.processHtml and
re-run updateMotorDirection() once it resolves, so the correct image
is shown after the settings values arrive. The change event handlers
are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The help icon next to the Use Pilot Logo toggle was placed before the label in DOM order with float:right and an i18n_title pointing at the unrelated osd_use_large_pilot_logo_help string. Clicking the icon toggled the switch and hovering showed the wrong (or no) tooltip, because the icon sat inside the toggle's visual click area and never opened Settings.md#osd_use_pilot_logo. Move the helpicon out after the toggle's label, matching the pattern used by other working help icons in the configurator (e.g. failsafe Minimum Distance toggle), and point the tooltip at osdElement_PILOT_LOGO_HELP, which actually describes osd_use_pilot_logo. Fixes #2523
osd: fix help link for Use Pilot Logo toggle
Converts .content_toolbar from float: right buttons to a flex container, giving proper left/right button group separation on firmware_flasher and cli tabs without inline styles or undefined utility classes. - .content_toolbar: display flex, justify-content flex-end, padding with box-sizing border-box - .content_toolbar > div: flex row with gap for button groups - .toolbar-left: margin-right auto to push sibling group to the right - cli.html: replace float:left inline style and undefined pull-right class with toolbar-left - firmware_flasher.html: add toolbar-left to flash group so backup buttons align right Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
handleReconnect() stored reopenTab inconsistently: the boolean=true
path stored the <li> element, while most tab callers passed the <a>
element directly. onValidFirmware then called $('a', reopenTab).trigger()
which finds nothing when reopenTab is already an <a>, so no tab was
navigated to after reconnect.
This left li.tab_landing still marked active from the disconnect phase.
GUI.updateActivatedTab() later re-triggered its click, but allowedTabs
was by then set to connected mode (no 'landing'), producing the
"You need to upgrade your firmware before you can use the Welcome tab"
error.
Fix by normalising reopenTab to always be the <a> element at storage
time in handleReconnect(), covering the boolean path, the element path
(handles both <a> and <li> callers including cliTab.exit), and the
false/null path. onValidFirmware then simply calls .trigger('click')
directly on the stored anchor.
If the user clicks Save while Settings.configureInputs() is still loading settings asynchronously, some inputs may not yet have their data-setting-info populated (set only after the FC responds to each getSetting request). processInput() returns null for such inputs. Guard against null to skip unpopulated inputs rather than crashing with "Cannot read properties of null (reading 'setting')".
If an MSP response for a setting is malformed or truncated (e.g. RangeError reading a uint16 from a too-short DataView), the error propagated as an uncaught promise rejection and left the input in the DOM without setting-info. Catch errors per-setting in configureInputs and remove the input's container, matching the existing behaviour for settings that don't exist on the FC.
When getSetting fails (e.g. malformed MSP response), emit a console error so the problem is visible for diagnosis rather than silently removing the input from the DOM. Root cause of the MSPV2_SETTING inconsistency was an LTO bug in the firmware (fixed in inav/src/main/fc/settings.c). The catch here is kept as a safety net for unexpected failures, but now surfaces them.
- Replace synchronous recursion with while loop in pickAndSaveSingleInput to avoid stack growth when many inputs have null settingPairs - Add null guard to live change handler to close the same class of bug that pickAndSaveSingleInput was fixed for
FC.CONFIG.profile/mixer_profile/battery_profile are reset to -1 by FC.resetState() on disconnect. The first status poll after reconnect transitions -1 → actual_value, which was wrongly treated as a runtime profile change, triggering updateActivatedTab() and re-initializing the tab while settings were still loading async (causing DataView out-of-bounds errors on in-flight MSP responses). Guard against the -1 sentinel so only genuine in-session profile changes (real_value → different_real_value) reload the tab.
…ab-error fix: reopen correct tab after Save and Reboot
…ramework-constants fix: sync JS programming framework constants with firmware
…tion-arrow-on-load Fix mixer tab motor direction arrow not reflecting Props Out on load
…replacement-bug Fix JS Programming decompiler: prevent space replacement with variable names
…d-wing Hide motor direction radio box for non-multirotor platforms
…t-enable-toggle OSD: Make custom elements UI more intuitive
Advanced Tuning tab always had a latent show/hide bug: processHtml() checks FC.isAirplane()/isMultirotor() to show the correct section, but never requested MIXER_CONFIG itself. If platformType was still -1 (the resetState() default), both isAirplane() and isMultirotor() return false and the else branch renders both sections simultaneously. Fix by adding an MSPChainer that fetches loadMixerConfig before calling load_html(), matching the pattern already used in pid_tuning.js and mixer.js. This ensures platformType is populated with the real FC value before processHtml() makes visibility decisions.
Add smart rounding for unit-converted display values
…d-on-load mixer: fix preview image not showing reversed on page load
fixed usb descriptor len mismatch on some chips
Submit foxeer m10q model fix to maintenance-9.x
fix autocomplete after disconnecting FC
toolbar: replace float-based layout with flexbox
…ixed-craft-type fix(advanced-tuning): load mixer config before rendering tab
fix: The Alignment Tool's sliders are not linked to the Value fields
master to 9 (oops)
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Branch Targeting SuggestionYou've targeted the
If This is an automated suggestion to help route contributions to the appropriate branch. |
|



No description provided.