Skip to content

fix: contract jsinput html_file asset URLs to /static/ on save (LP-704)#106

Merged
djoseph-apphelix merged 1 commit into
release-ulmofrom
djoseph/LP-704
Jul 8, 2026
Merged

fix: contract jsinput html_file asset URLs to /static/ on save (LP-704)#106
djoseph-apphelix merged 1 commit into
release-ulmofrom
djoseph/LP-704

Conversation

@djoseph-apphelix

@djoseph-apphelix djoseph-apphelix commented Jul 7, 2026

Copy link
Copy Markdown
Member

Description

Fixes LP-704 (frontend layer): the editor bakes course-pinned absolute asset URLs into JSInput problems on save, breaking them after a course re-run or export/import.

Studio's GET API expands portable /static/<name> references into absolute asset-v1:<Org>+<Course>+<Run>+... URLs pinned to the current course, and the save path persists whatever the editor posts. setAssetToStaticUrl (src/editors/sharedComponents/TinyMceWidget/hooks.ts) is the editor's contraction step, but its split regex only recognizes src= and href= attributes — JSInput's html_file= passes through untouched, so the expanded absolute URL gets saved. After a re-run, the URL still points at the original course and the problem breaks (this is the failure Harvard reported).

The fix

  • Add html_file=" / html_file=&quot; to the attribute-splitting regex in setAssetToStaticUrl, so JSInput asset references are contracted back to /static/<name> on save like image/link references already are.
  • Fix the pre-existing href=&quot token, which was missing its trailing ;: &quot; is the complete HTML entity, so the token matched one character short, left a leading ; on the next split segment, and &quot;-encoded href asset URLs were never contracted.
  • Guard and escape the lmsEndpointUrl host-stripping regex: some call sites (RawEditor, TextEditor) invoke setAssetToStaticUrl without lmsEndpointUrl, which previously built /undefined/g and silently deleted the literal text "undefined" from saved content; the URL's regex metacharacters (.) are now escaped as well.

Testing

  • 5 new tests in hooks.test.js: a JSInput html_file with an expanded asset URL is rewritten to /static/<name> on save (plain-quoted, &quot;-encoded, and LMS-absolute https://<lms>/asset-v1:... forms); a &quot;-encoded href asset URL is likewise contracted; and content containing the literal text "undefined" survives a save without lmsEndpointUrl.
  • Verified on devstack: saving a JSInput problem no longer bakes the course id into html_file.

Screenshots

Before

Screenshot 2026-07-08 at 1 38 19 PM

After

Screenshot 2026-07-08 at 1 43 05 PM

Companion server-side fix: edx/edx-platform#377

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an authoring-time portability regression where JSInput html_file asset URLs (expanded to course-pinned /asset-v1:... references by the Studio GET API) were being persisted on save instead of being contracted back to portable /static/<name> URLs.

Changes:

  • Extend setAssetToStaticUrl’s attribute-splitting logic to recognize JSInput html_file="..." and html_file=&quot;...&quot; so those URLs are contracted on save.
  • Add unit tests to validate html_file contraction behavior for both plain-quoted and &quot;-encoded attributes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/editors/sharedComponents/TinyMceWidget/hooks.ts Updates the URL contraction splitter to include JSInput html_file attributes.
src/editors/sharedComponents/TinyMceWidget/hooks.test.js Adds tests asserting JSInput html_file asset URLs are rewritten to /static/... on save.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let content = editorValue.replace(regExLmsEndpointUrl, '');

const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot)/g) : [];
const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot|html_file="|html_file=&quot;)/g) : [];
Comment thread src/editors/sharedComponents/TinyMceWidget/hooks.test.js
Copilot AI review requested due to automatic review settings July 7, 2026 13:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +513 to +516
const regExLmsEndpointUrl = RegExp(lmsEndpointUrl, 'g');
let content = editorValue.replace(regExLmsEndpointUrl, '');

const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot)/g) : [];
const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot;|html_file="|html_file=&quot;)/g) : [];
Copilot AI review requested due to automatic review settings July 7, 2026 13:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +513 to +516
const regExLmsEndpointUrl = RegExp(lmsEndpointUrl, 'g');
let content = editorValue.replace(regExLmsEndpointUrl, '');

const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot)/g) : [];
const assetSrcs = typeof content === 'string' ? content.split(/(src="|src=&quot;|href="|href=&quot;|html_file="|html_file=&quot;)/g) : [];

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread src/editors/sharedComponents/TinyMceWidget/hooks.ts
@djoseph-apphelix
djoseph-apphelix merged commit dddb09d into release-ulmo Jul 8, 2026
5 checks passed
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