Skip to content

Jquery free components#1282

Open
bnmnetp wants to merge 15 commits into
mainfrom
jquery-free-activecode
Open

Jquery free components#1282
bnmnetp wants to merge 15 commits into
mainfrom
jquery-free-activecode

Conversation

@bnmnetp

@bnmnetp bnmnetp commented Jul 5, 2026

Copy link
Copy Markdown
Member

No description provided.

bnmnetp and others added 15 commits July 3, 2026 13:34
Convert the entire activecode family (activecode.js, livecode.js,
audiotour.js, timed_activecode.js, activecode_html/js/sql.js,
acfactory.js) and common/js/runestonebase.js to plain DOM APIs.

Key replacements:
- jQuery UI resizable -> CSS resize:both (.ac-resizable) + ResizeObserver
- jQuery UI slider history scrubber -> native <input type="range">
- Bootstrap .modal() grade summary -> native <dialog>
- sync $.ajax in the Skulpt file reader -> sync XHR (hook can't await)
- jQuery.Deferred in activecode_sql -> externally-resolved Promise
- DOMNodeInserted mutation event -> MutationObserver
- new common/js/domutil.js: getDataValue() replicates jQuery .data()
  type coercion; toggleDisplay() replaces .toggle()

Add a vitest + jsdom test harness (npm test) with 39 passing tests:
characterization tests written against the jQuery implementation first,
then held green through the refactor and run with no jQuery defined.
test-support/jquery-globals.js provides $ for tests of not-yet-converted
components; converted components' tests must not import it.

Verified in-browser against the PTXSB book: all activecodes render,
skulpt runs, scrubber and resize work, no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
Convert parsons.js, parsonsBlock.js, parsonsLine.js, settledBlock.js,
placeholderBlock.js and timedparsons.js to plain DOM APIs. The drag
machinery was already Hammer.js; jQuery was only used for DOM
manipulation, $.animate tweens and $.inArray.

- add outerWidth/outerHeight and a rAF-based animate() tween (numeric
  and color properties) to common/js/domutil.js
- data-* option parsing now uses getDataValue for jQuery .data() type
  coercion
- component instantiation listens for runestone:login-complete via
  document.addEventListener like other converted components
- add a 48-test characterization suite (runestone/parsons/test) written
  against the jQuery implementation first, then verified against the
  jQuery-free version; the suite does not load the jquery-globals shim,
  proving the component no longer touches jQuery

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
shortanswer was already jQuery-free; its tests lock that in. timeddnd.js
loses its four jQuery call sites. Also fixes checkCorrectTimed, which
referenced this.dragPairArray -- renamed to premiseArray in the 12/30/24
rewrite -- and threw whenever a timed exam graded an untouched dragndrop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
The WeBWorK server's JS still fires runestone_ww_check through the
page's jQuery, so listener registration goes through window.jQuery when
the page provides it (with a native fallback); a dedicated interop test
covers both dispatch styles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
Tab switching used to be delegated to Bootstrap 3's jQuery tab plugin
via data-toggle attributes; the component now handles clicks itself and
runs the CodeMirror-refresh/Disqus-click logic that lived in the
shown.bs.tab handler.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
The partner picker falls back to the native multi-select that select2
was enhancing. The group-size limit is now actually enforced at submit
time: the old check read group.len (always undefined), so only
select2's UI cap ever limited selections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
The toggle_current bookkeeping moves from jQuery's expando data store
to data attributes on the selector element.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
The post-exam autograder call moves from jQuery.ajax to fetch
(extracted as submitAutograde so it is testable), and the beforeunload
guard is now a tracked native listener. The vendored pytutor bundle is
stubbed in vitest config: it is sloppy-mode code that Vite's strict ESM
transform rejects, and timed.js pulls it in via activecode/livecode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
- renderComponent.js: native DOM parsing/insertion; renderOneComponent's
  timed-assessment guard now actually inspects the passed div (it used
  $(this) with an undefined this, so it never skipped anything).
- presenter_mode.js: full native rewrite. Fixes exercise navigation,
  which threw a strict-mode ReferenceError in getActiveExercise, and
  guards the never-assigned presenterCssLink that broke leaving
  presenter mode. Dead configureCodelens/loadPresenterCss removed.
- user-highlights.js: jQuery.ajax (one call synchronous) becomes fetch;
  nav-drawer animations use the domutil animate helper.
- webpack.index.js: native listeners/queries for its own wiring.
- jquery.idle-timer.js deleted (imported but never invoked anywhere);
  jquery.highlight.js deleted (no importers at all).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
showEval-0.10.0.js (Al Sweigart's jQuery-free rewrite with rAF fade and
width helpers) replaces showEval.js, wrapped in the Runestone component
contract from the old 0.9.1-based file: RunestoneBase, ## annotations,
per-question next/reset buttons, event logging, login-complete wiring,
and the component factory. Characterization tests were written against
the jQuery version first and pass unchanged against the replacement.
The standalone slate variant referenced by PreTeXt interactives stays
deployed on the CDN under its versioned name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
Covers the architecture (Vite/RTK Query/URL-driven routing, the two
state generations, how FastAPI serves the built bundle) and a
getting-started guide for programmers: edit/run loop, layout crib
sheet, conventions, testing, and checklists for common tasks like
adding an exercise-type editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
autodoc's getattr() introspection touches @declared_attr descriptors on
the non-mapped mixin classes in db.models, which SQLAlchemy warns about.
Filter just that message in conf.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFLtaVStyfvhuXsTtkHztA
Copilot AI review requested due to automatic review settings July 5, 2026 19:53
@bnmnetp bnmnetp requested review from ascholerChemeketa and removed request for Copilot July 5, 2026 19:53
@bnmnetp

bnmnetp commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

I walked through all the pages on the sample book and it looks good to me. Found (and fixed) just one issue after Fable had done its work. It would be great to have someone else take this for a spin.

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