Skip to content

luci-base: form.js: fix stripTags NotFoundError and modify source node - #8936

Open
jjm2473 wants to merge 2 commits into
openwrt:masterfrom
jjm2473:pr-master/fix-striptags
Open

luci-base: form.js: fix stripTags NotFoundError and modify source node#8936
jjm2473 wants to merge 2 commits into
openwrt:masterfrom
jjm2473:pr-master/fix-striptags

Conversation

@jjm2473

@jjm2473 jjm2473 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Pull request details

Description

This PR addresses two issues:

  1. NotFoundError:
    For example s='<a><br></a>', then x=dom.parse('<div><a><br></a></div>'), this br is not a direct child node of x, the subsequent call x.replaceChild(document.createTextNode('\n'), br) will result in an error:
Uncaught (in promise) NotFoundError: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
  at eval (form.js:312:6)
  at NodeList.forEach (<anonymous>)
  at ClassConstructor.stripTags (form.js:311:28)
  at ClassConstructor.renderFrame (form.js:4434:30)
  1. modify source node
    stripTags modifies the source node, causing switch port status missing <br> on first render.
    Clone source node as AI suggests: luci-mod-network: switch: fix port status missing <br> on first render #8937 (comment)

Screenshot or video of changes (if applicable)

Maintainer (preferred)

@systemcrash


Tested on

OpenWrt version: iStoreOS 25.12.5 2026081215
LuCI version: LuCI istoreos-25.12 branch 26.195.42598~4a1ef8c
Web browser(s): Chrome (151.0.7922.76)


Checklist

  • (Nice to have) Includes what Issue it closes (e.g. openwrt/luci#issue-number).
  • (Nice to have) Includes what it depends on (e.g. openwrt/packages#pr-number in sister repo).

@openwrt openwrt Bot added the not following guidelines Pull request does not follow formatting guidelines label Aug 12, 2026
@jjm2473
jjm2473 force-pushed the pr-master/fix-striptags branch from b8ff99d to da2a65c Compare August 12, 2026 14:56
@jjm2473 jjm2473 changed the title luci-base: form.js: fix stripTags error when param is a string contai… luci-base: form.js: fix stripTags NotFoundError Aug 12, 2026
@jjm2473
jjm2473 force-pushed the pr-master/fix-striptags branch from da2a65c to 61436bb Compare August 12, 2026 15:00
@openwrt openwrt Bot removed the not following guidelines Pull request does not follow formatting guidelines label Aug 12, 2026

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed 1 new commit; one inline simplification suggested. The commit message accurately describes the change, and the underlying NotFoundError diagnosis is correct.


Generated by Claude Code

Comment on lines +312 to +315
if (br.parentElement)
br.parentElement.replaceChild(document.createTextNode('\n'), br);
else
x.replaceChild(document.createTextNode('\n'), br);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The branch is unnecessary — br.parentNode is the correct target in every case and makes the fallback redundant.

br always comes from x.querySelectorAll('br'), so it is always a descendant of x and always has a parent node. Two situations exist:

  • x is an element (the dom.parse(
    ${s}
    ) path, or an element passed in via dom.elem(s)): the parent is an element, so parentElement === parentNode.
  • x is a DocumentFragment and the <br> is a direct child of it: parentElement is null — this is the only case the else reaches — and parentNode is the fragment, i.e. exactly what x.replaceChild() uses. Note dom.elem() only tests for nodeType, so a fragment does reach here.

Using parentNode unconditionally covers both, and matches how the rest of the tree does node replacement (e.g. cbi.js:366, tools/network.js:1383).``

Suggested change
if (br.parentElement)
br.parentElement.replaceChild(document.createTextNode('\n'), br);
else
x.replaceChild(document.createTextNode('\n'), br);
br.parentNode.replaceChild(document.createTextNode('\n'), br);

Generated by Claude Code

For example `s='<a><br></a>'`, then `x=dom.parse('<div><a><br></a></div>')`,
this `br` is not a direct child node of `x`,
the subsequent call `x.replaceChild(document.createTextNode('\n'), br)` will result in an error:

```
Uncaught (in promise) NotFoundError: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
at eval (form.js:312:6)
at NodeList.forEach (<anonymous>)
at ClassConstructor.stripTags (form.js:311:28)
at ClassConstructor.renderFrame (form.js:4434:30)
```

Signed-off-by: Liangbin Lian <jjm2473@gmail.com>
@jjm2473
jjm2473 force-pushed the pr-master/fix-striptags branch from 61436bb to f02fc9d Compare August 13, 2026 02:19
@openwrt openwrt Bot added the not following guidelines Pull request does not follow formatting guidelines label Aug 13, 2026
`stripTags` modifies the source node, causing switch port status missing `<br>` on first render.

Clone source node as AI suggests: openwrt#8937 (comment)

Signed-off-by: Liangbin Lian <jjm2473@gmail.com>
@jjm2473
jjm2473 force-pushed the pr-master/fix-striptags branch from f02fc9d to 619ce76 Compare August 13, 2026 02:26
@openwrt openwrt Bot removed the not following guidelines Pull request does not follow formatting guidelines label Aug 13, 2026
@jjm2473 jjm2473 changed the title luci-base: form.js: fix stripTags NotFoundError luci-base: form.js: fix stripTags NotFoundError and modify source node Aug 13, 2026

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed 2 new commits (the branch was force-pushed, so 61436bb was rewritten as 19a5954, which adopts the br.parentNode simplification from the previous review).

Both changes look correct:

  • 19a5954br.parentNode.replaceChild() is right for every case, since br always comes from x.querySelectorAll('br') and therefore always has a parent, whether x is an element or a DocumentFragment.
  • 619ce76cloneNode(true) on the dom.elem(s) branch is the right scope for the mutation fix: only that branch receives a caller-owned node, while the dom.parse() branch already builds a throwaway tree. textContent on the detached clone is unaffected by the clone.

Both commit messages match their diffs. One nit inline about the PR description.


Generated by Claude Code

Comment thread modules/luci-base/htdocs/luci-static/resources/form.js
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.

2 participants