Skip to content

Merge Beta feature into Main#515

Merged
makermelissa merged 30 commits into
mainfrom
beta
Jun 17, 2026
Merged

Merge Beta feature into Main#515
makermelissa merged 30 commits into
mainfrom
beta

Conversation

@makermelissa

@makermelissa makermelissa commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Merges beta feature work into main; conflicts resolved by Copilot.

makermelissa-piclaw and others added 28 commits April 23, 2026 10:43
- Guard connectionStep() in updateConnected() behind connectDialog.isOpen()
  to prevent 'Modal has not been opened yet' crash when BLE disconnects
  during file write operations (fixes #377)
- Store bound event handlers in constructor and reuse them so
  removeEventListener actually removes the old listener
- Fix advertisement listener cleanup in connectToBluetoothDevice()
…rash

Fix BLE disconnect crash and event listener leaks
CodeMirror 6 dropped the simple extra_keywords mechanism that CM5 had,
so instead of forking @codemirror/lang-python we layer a small
ViewPlugin on top of the existing Python syntax tree. It walks the
visible tree, finds VariableName nodes whose text matches a known
CircuitPython core module or common Adafruit library, and tags them
with a tok-cp-module class so the theme can color them distinctly.

This avoids:
- Forking lang-python and tracking upstream changes
- Re-tokenizing strings/comments (we only mark identifier nodes)
- Adding any per-keystroke parsing cost (decoration set is rebuilt
  only on doc/viewport/tree changes)

Adds a magenta accent (#FF79C6) for .tok-cp-module in the editor
theme so CircuitPython modules pop out from regular Python identifiers.

Closes #363
Drops the hand-curated list of adafruit_* community libraries in favour
of a startsWith("adafruit_") check. New Adafruit CircuitPython libraries
will be highlighted automatically as they ship, with no maintenance
needed in this file. The core CircuitPython module set still uses an
explicit allowlist because those names don't share a distinguishing
prefix.
The CircuitPython Community Bundle ships ~10 libraries with a
`circuitpython_` prefix (circuitpython_csv, circuitpython_schedule,
circuitpython_functools, etc.). Same prefix-match approach as
adafruit_*: new community libraries are highlighted automatically.
Refreshed CIRCUITPYTHON_CORE_MODULES against the current contents of
adafruit/circuitpython:shared-bindings/. Added 15 modules that have
landed since the initial list was written: audiodelays, audiofilters,
audiofreeverb, audiospeed, aurora_epaper, camera, fourwire, gnss,
i2cioexpander, lvfontio, mcp4822, mipidsi, ps2io, qspibus, rclcpy.

Removed the deprecated paralleldisplay alias (paralleldisplaybus is the
modern name and is already listed) and the stray lsm6ds entry, which
isn't a shared binding and isn't in the community bundle either.

Standard-Python modules that CircuitPython also exposes (math, os, time,
random, struct, hashlib, ipaddress, locale, __future__) are intentionally
left out so we don't recolour those names in plain Python code.
Underscore-prefixed internal bindings (_bleio etc.) are also omitted;
users reach for the adafruit_ wrappers, which the prefix wildcard
already matches.
These are early Adafruit-maintained libraries that predate the
adafruit_ naming convention, not community-bundle modules.
When an identifier matches both classHighlighter's VariableName tag
and our CircuitPython overlay, CodeMirror renders nested mark spans.
The inner span (closer to the text) is what the browser uses for
`color`, and it's chosen by decoration precedence \u2014 so without an
explicit precedence wrapper, the syntax highlighter's blue stayed on
top and `neopixel` rendered the same color as any other variable.

Wrapping the ViewPlugin with Prec.highest puts the tok-cp-module span
inside the tok-variableName span, letting the pink override the blue
without touching the CSS or using !important.
…n-highlight

Add CircuitPython module highlighting overlay
Match the Arduino IDE Serial Plotter input format so sketches that
print 'label:value' pairs separated by tabs (or commas/spaces) are
plotted with the labels shown in the legend instead of confusing the
parser. Each labeled series is tracked by name across frames so the
order can vary, and a per-frame padding pass keeps the x-axis aligned
when not every series reports on every line.

Existing tuple, list, and plain CSV formats continue to work
unchanged. The default color palette is also expanded from 3 colors
to 16 so plots with many series remain legible.

Fixes #457
- Drop pale tints, gray, and brown from palette since they wash out on
  the dark theme's #777 plotter background.
- Pull legend label color from --terminal-text-color so it contrasts
  with the active theme instead of being hardcoded black.
…value-labeled-plotter-data

Support Arduino-style labeled multi-value plotter data
Adds js/common/firmware-check.js, a small helper that:
- Parses CircuitPython version strings (stable + alpha/beta/rc pre-releases,
  including '-dirty' build suffixes) into a comparable structure.
- Fetches the latest stable and the latest dev pre-release of CircuitPython
  from the adafruit/circuitpython GitHub releases API (cached per page load).
- Computes which updates are worth surfacing for the device's current version,
  following the rules from #357:
    * If the user is on a development release, suggest a newer stable and/or
      a newer dev release when available.
    * If the user is on a stable release, suggest a newer stable and/or any
      newer dev release.

Both DiscoveryModal and DeviceInfoModal now render those suggestions under
the device info table with a link to the board's circuitpython.org download
page (which only lists firmware that is actually built for that board).

The container collapses when there is nothing to show, and any failure of
the GitHub API call is non-fatal and silently leaves the dialog unchanged.
Previously, only the Web workflow opened the Device Info / Discovery
dialog automatically after connecting. USB and BLE users had to click
the Info button to see the firmware-update suggestion added in this PR.

This change moves the post-connect 'show info' trigger into loadEditor()
so all three workflows (Web / USB / BLE) behave the same way: connect
once, see the dialog, see the firmware-update suggestion if any.

To avoid spamming the dialog on silent reconnects, a one-shot flag
(shownDeviceInfoForCurrentSession) tracks whether we've already shown
it for the current connection; the flag is reset in disconnectCallback
so a fresh connect always re-shows the dialog. The dialog is opened
fire-and-forget so it doesn't block the rest of the post-connect flow.

Removes the now-redundant explicit showInfo() calls in checkConnected()
and the URL-backend bootstrap path.
In USBWorkflow.onConnected, loadEditor() was being called BEFORE
super.onConnected() set _connected = CONNSTATE.connected. The new
post-connect Device Info dialog trigger gates on connectionStatus(),
which requires _connected == connected, so the dialog never opened
for USB users.

Reorder so super.onConnected() (which both flips the state flag and
closes the connect dialog) runs first, then loadEditor() runs with
connectionStatus() true. Also drop the redundant explicit
connectDialog.close() call -- super.onConnected already closes it.
Pick a CodeMirror 6 language extension based on the opened file's
extension instead of hard-wiring the editor to Python. Python files
keep the existing CircuitPython module highlight overlay; other
recognized extensions just get the matching CodeMirror language
plugin so users get color coding when editing config and data
files commonly stored on CircuitPython devices.

Newly handled extensions: .json, .html/.htm, .css, .js, .xml, .md.
Anything else (.txt, .toml, .ini, .inf, etc.) falls back to plain
text, which is still an improvement over Python parsing being run
on a non-Python file.

Refs #361
- Move the per-file language extension into a CodeMirror Compartment
  so we can reconfigure the language plugin without rebuilding the
  editor state. Save As to a different extension (code.py ->
  test.html) now picks up the new language immediately, instead of
  staying on whatever language was active when the file was first
  loaded.
- Replace hardcoded editor token colors with CSS variables and
  provide light-theme overrides. The editor previously hardcoded
  color: #ddd as the default text color and used a palette tuned
  only for the dark background, so HTML tag names and other tokens
  that fall back to the default color (or only had pale colors)
  were nearly invisible on the light theme's #f8f8f8 background.
- Style .tok-typeName explicitly so HTML/XML tag names color in
  both themes instead of falling through to the editor default.

Refs #361
The previous attempt hooked the language refresh into saveFileContents
and compared the new path against workflow.currentFilename. But
workflow.saveFileAs() in workflows/workflow.js sets
this.currentFilename = path BEFORE delegating to saveFile ->
saveFileContents, so by the time we ran our check the two were
already equal and the language never got reconfigured.

Move the trigger into setFilename, which is the single chokepoint
all filename changes route through (Open, New, Save As, backend
load), and track the editor's current language path on a module
local instead. Skip the reconfigure when the new path resolves to
the same language plugin so we don't churn parser state on Save
within the same extension.

Refs #361
…nguage-color-coding

Add syntax highlighting for additional file types
…re-update-check

Suggest firmware updates and auto-open device info post-connect
@makermelissa

Copy link
Copy Markdown
Collaborator Author

@copilot resolve the merge conflicts in this pull request

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploying web-editor with  Cloudflare Pages  Cloudflare Pages

Latest commit: 21b94e4
Status: ✅  Deploy successful!
Preview URL: https://e95a4c2b.web-editor-2j8.pages.dev

View logs

Copilot AI commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Done. Resolved the merge conflicts in js/script.js and js/workflows/ble.js (commit 21b94e4).

js/script.js:

  • Kept main's saveInFlight re-entrancy guard at the start of saveFileContents, with the enhanced comment from beta for the if (path !== currentFilename) check inside the try block
  • Kept main's disconnectCallback comment about saveInFlight intentionally not being reset, while also preserving beta's shownDeviceInfoForCurrentSession = false reset (since that variable still exists in the merged code)

js/workflows/ble.js:

  • Kept main's comprehensive constructor additions (silent reconnect tracking, properly named cached bound handlers, _pendingAdvAborts set) and the new helper methods (markMutatingOp, _wasMutatingOpRecent, awaitPostOpReconnect)
  • Kept main's _onSerialReceiveBound naming and _onDisconnectedBound naming throughout
  • Kept main's onAdvertisementReceived approach (local function + advHandled guard + abortController.signal) in connectToBluetoothDevice

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.

3 participants