Skip to content

Implement JavaScript Text constructor#249

Merged
github-actions[bot] merged 1 commit intomainfrom
fix/text-constructor
Feb 2, 2026
Merged

Implement JavaScript Text constructor#249
github-actions[bot] merged 1 commit intomainfrom
fix/text-constructor

Conversation

@stroiman
Copy link
Member

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 29, 2026

Walkthrough

The changes implement Text constructor support in the DOM scripting layer. This includes modifying constructor validation logic to use dynamic checks instead of hard-coded exceptions, adding CreateText and CreateTextData utility functions, creating a TextConstructor generic function, and registering the Text constructor in the window realm configuration. Supporting tests and test utilities are also added, including a new testText function to verify Text node construction functionality.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether the description relates to the changeset. Provide a pull request description that explains the motivation, implementation approach, or any testing performed for the Text constructor implementation.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Implement JavaScript Text constructor' clearly and concisely summarizes the main change in the changeset, which is adding support for the JavaScript Text constructor.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Comment on lines +48 to +57
for cons := range d.IdlInterface.InternalSpec.Constructors() {
// I can't find documenation; but constructors with [HTMLContructor]
// extended attribute are not constructable; i.e., they throw an
// "invalid constructor" TypeError
for _, attr := range cons.ExtAttrs {
if attr.Name == "HTMLConstructor" {
return false
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Search for webref/idl Interface struct definition and HTMLConstructor representation
rg -n "type Interface struct" -g '*.go' -A 20

Repository: gost-dom/browser

Length of output: 42


🏁 Script executed:

# Search for HTMLConstructor usage in the codebase
rg -n "HTMLConstructor" -g '*.*'

Repository: gost-dom/browser

Length of output: 158


🏁 Script executed:

# Search for how constructors are handled and checked
rg -n "AllowConstructor" -g '*.go' -B 5 -A 10

Repository: gost-dom/browser

Length of output: 4229


🏁 Script executed:

# Look at webref package structure
find . -name "*.go" -path "*/webref*" -type f | head -20

Repository: gost-dom/browser

Length of output: 42


🏁 Script executed:

# Search for ExtAttrs patterns related to Interface or Constructors
rg -n "ExtAttrs" -g '*.go' | head -30

Repository: gost-dom/browser

Length of output: 158


🏁 Script executed:

# Find webref package imports and dependencies
rg -n "webref" -g '*.go' | head -20

Repository: gost-dom/browser

Length of output: 1856


🏁 Script executed:

# Check go.mod for webref dependency
cat go.mod | grep -i webref

Repository: gost-dom/browser

Length of output: 42


🏁 Script executed:

# Search for InternalSpec definition
rg -n "InternalSpec" -g '*.go' -A 5 | head -40

Repository: gost-dom/browser

Length of output: 1160


🏁 Script executed:

# Check the IdlInterface type definition
rg -n "type IdlInterface" -g '*.go' -A 10

Repository: gost-dom/browser

Length of output: 3961


🏁 Script executed:

# Search for where Interface and its ExtAttrs are used
rg -n "\.ExtAttrs" -g '*.go'

Repository: gost-dom/browser

Length of output: 158


🏁 Script executed:

# Look for InternalSpec field definition in IdlInterface or related files
rg -n "InternalSpec" -g '*.go' -B 3 -A 3

Repository: gost-dom/browser

Length of output: 1263


🏁 Script executed:

# Check the full IdlInterface struct definition including any embedded fields
cat -n internal/code-gen/interfaces/idl_interface.go | sed -n '18,35p'

Repository: gost-dom/browser

Length of output: 711


🏁 Script executed:

# Search for where IdlInterface is embedded or created to understand its relationship with webref
rg -n "IdlInterface.*{" -g '*.go' -A 10 | head -50

Repository: gost-dom/browser

Length of output: 153


🏁 Script executed:

# Look for webref idl.Interface usage to understand the data model
rg -n "idl\.Interface" -g '*.go' | head -20

Repository: gost-dom/browser

Length of output: 1934


🌐 Web query:

github.com/gost-dom/webref idl.Interface HTMLConstructor extended attribute

💡 Result:

[HTMLConstructor] is not a Web IDL standard extended attribute; it’s defined by the HTML Standard and is only valid on interfaces (no args; must not be combined with [Constructor]/[NoInterfaceObject], etc.) [1]. The Web IDL Standard’s own list of interface-level extended attributes does not include HTMLConstructor [4].

In github.com/gost-dom/webref v0.5.7, the high-level idl.Interface type doesn’t expose interface extended attributes like HTMLConstructor (it contains things like inheritance, members, iterable types, constructors, etc.) [2]. Those “raw” extended attributes are instead available via the legacy JSON model, which includes extAttrs as []legacy.ExtAttr on types like legacy.ExtendedName [3].


🌐 Web query:

webref idl Interface ExtAttrs extended attributes structure

💡 Result:

Web IDL: where interface ExtAttrs (extended attributes) live

In the Web IDL grammar, extended attributes appear as an ExtendedAttributeList: a square‑bracketed, comma‑separated list placed before the thing being annotated (including an interface). The spec defines it as an annotation mechanism and gives the core productions, e.g. ExtendedAttributeList[] or empty. (webidl.spec.whatwg.org)

Example (interface-level ext attrs):

[Exposed=Window, SecureContext]
interface Foo { };

“Structure” in practice (WebIDL2 / WebRef parser AST)

Tools like WebIDL2 (commonly used by WebRef pipelines) represent those interface extended attributes on the parsed node as an extAttrs array. Each item is an object like: (chromium.googlesource.com)

{
  "name": "Exposed",
  "arguments": null,
  "type": "extended-attribute",
  "rhs": { "type": "identifier-list", "value": ["Window", "Worker"] }
}

Field meanings (per WebIDL2 docs): (chromium.googlesource.com)

  • name: extended attribute name
  • type: "extended-attribute"
  • rhs: present when there’s a right-hand side (e.g. =Window or =(Window,Worker)), with type like "identifier" / "identifier-list"
  • arguments: argument list if present (e.g. [Foo(x)]), otherwise null (empty list is [], absent is null)

Citations:


🌐 Web query:

"HTMLConstructor" Web IDL interface vs constructor extended attribute

💡 Result:

There isn’t a Web IDL interface named HTMLConstructor in the platform specs; [HTMLConstructor] is an IDL extended attribute defined by the HTML Standard for HTML element interfaces.

[Constructor] (Web IDL)

  • A generic Web IDL mechanism: putting [Constructor] on an interface makes the interface object “constructable” (has [[Construct]]), with the argument list you declare. (w3.org)

[HTMLConstructor] (HTML Standard)

  • A special-case hook for HTML elements (needed for custom elements): it marks that the interface object’s call/construct behavior follows the HTML element constructor algorithm (not a normal Web IDL constructor). (wicg.github.io)
  • Constraints: it takes no arguments, appears only on interfaces, only once, and must not be combined with [Constructor] (or [NoInterfaceObject]). (wicg.github.io)
  • Engine docs summarize the intent similarly: “HTML Elements have special constructor behavior”; cannot be annotated with [Constructor]. (chromium.googlesource.com)

Practical takeaway

  • Use [Constructor] for “normal” constructable Web IDL types.
  • Use [HTMLConstructor] only for HTML element interfaces, where construction must integrate with the HTML/custom-elements construction rules (and therefore is intentionally not expressed as a normal Web IDL [Constructor]). (wicg.github.io)

Citations:


The [HTMLConstructor] check is incomplete: it appears at the interface level, not constructor level.

Per the HTML Standard, [HTMLConstructor] is an interface-level extended attribute only (never on constructors). The current code checks constructor-level ExtAttrs, which won't catch interface-level [HTMLConstructor] declarations. Additionally, webref's public idl.Interface API does not expose interface extended attributes, making it impossible to verify this constraint with the current data model. An interface-level check is needed, or the data model must be extended to provide access to interface ExtAttrs.

Comment on lines +12 to +18
func testText(t *testing.T, e html.ScriptEngine) {
w := browsertest.InitWindow(t, e)
res := w.MustEval("new Text('Text content')")
_, ok := res.(dom.Text)
if !assert.True(t, ok) {
t.Logf("Not text: %T", res)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add an assertion for constructor argument wiring.
Right now the test only checks the type; asserting the data would validate that the constructor uses the provided string.

Proposed test enhancement
-	res := w.MustEval("new Text('Text content')")
-	_, ok := res.(dom.Text)
-	if !assert.True(t, ok) {
-		t.Logf("Not text: %T", res)
-	}
+	res := w.MustEval("new Text('Text content')")
+	text, ok := res.(dom.Text)
+	if assert.True(t, ok) {
+		assert.Equal(t, "Text content", text.Data())
+	} else {
+		t.Logf("Not text: %T", res)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func testText(t *testing.T, e html.ScriptEngine) {
w := browsertest.InitWindow(t, e)
res := w.MustEval("new Text('Text content')")
_, ok := res.(dom.Text)
if !assert.True(t, ok) {
t.Logf("Not text: %T", res)
}
func testText(t *testing.T, e html.ScriptEngine) {
w := browsertest.InitWindow(t, e)
res := w.MustEval("new Text('Text content')")
text, ok := res.(dom.Text)
if assert.True(t, ok) {
assert.Equal(t, "Text content", text.Data())
} else {
t.Logf("Not text: %T", res)
}

@github-actions github-actions bot merged commit c77d39b into main Feb 2, 2026
5 checks passed
@github-actions github-actions bot deleted the fix/text-constructor branch February 2, 2026 19:09
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