Merge pull request #1379 from lightpanda-io/textarea_setDefaultValue
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled

Add TextArea.defaultValue  setter
This commit is contained in:
Pierre Tachoire
2026-01-18 17:12:49 +01:00
committed by GitHub
2 changed files with 113 additions and 19 deletions

View File

@@ -42,6 +42,34 @@
testing.expectEqual('initial text', $('#textarea1').defaultValue)
</script>
<script id="defaultValue_set">
{
const textarea = document.createElement('textarea')
testing.expectEqual('', textarea.defaultValue)
testing.expectEqual('', textarea.value)
// Setting defaultValue should update the text content
textarea.defaultValue = 'new default'
testing.expectEqual('new default', textarea.defaultValue)
testing.expectEqual('new default', textarea.value)
testing.expectEqual('new default', textarea.textContent)
// Setting value should not affect defaultValue
textarea.value = 'user input'
testing.expectEqual('new default', textarea.defaultValue)
testing.expectEqual('user input', textarea.value)
// Test setting defaultValue on element that already has content
const textarea2 = document.createElement('textarea')
textarea2.textContent = 'initial content'
testing.expectEqual('initial content', textarea2.defaultValue)
textarea2.defaultValue = 'modified default'
testing.expectEqual('modified default', textarea2.defaultValue)
testing.expectEqual('modified default', textarea2.textContent)
}
</script>
<script id="disabled_initial">
testing.expectEqual(false, $('#textarea1').disabled)
testing.expectEqual(true, $('#textarea3').disabled)
@@ -149,3 +177,55 @@
testing.expectFalse(textarea.outerHTML.includes('required'))
}
</script>
<script id="clone_basic">
{
const original = document.createElement('textarea')
original.defaultValue = 'default text'
testing.expectEqual('default text', original.value)
// Change the value
original.value = 'user modified'
testing.expectEqual('user modified', original.value)
testing.expectEqual('default text', original.defaultValue)
// Clone the textarea
const clone = original.cloneNode(true)
// Clone should have the runtime value copied
testing.expectEqual('user modified', clone.value)
testing.expectEqual('default text', clone.defaultValue)
}
</script>
<script id="clone_preserves_user_changes">
{
// Create a fresh element to avoid interfering with other tests
const original = document.createElement('textarea')
original.textContent = 'initial text'
testing.expectEqual('initial text', original.defaultValue)
testing.expectEqual('initial text', original.value)
// User modifies the value
original.value = 'user typed this'
testing.expectEqual('user typed this', original.value)
testing.expectEqual('initial text', original.defaultValue)
// Clone should preserve the user's changes
const clone = original.cloneNode(true)
testing.expectEqual('user typed this', clone.value)
testing.expectEqual('initial text', clone.defaultValue)
}
</script>
<script id="clone_empty_textarea">
{
const original = document.createElement('textarea')
testing.expectEqual('', original.value)
original.value = 'some content'
const clone = original.cloneNode(true)
testing.expectEqual('some content', clone.value)
}
</script>

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
// Copyright (C) 2023-2026 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
@@ -27,7 +27,6 @@ const Form = @import("Form.zig");
const TextArea = @This();
_proto: *HtmlElement,
_default_value: ?[]const u8 = null,
_value: ?[]const u8 = null,
pub fn asElement(self: *TextArea) *Element {
@@ -39,9 +38,12 @@ pub fn asConstElement(self: *const TextArea) *const Element {
pub fn asNode(self: *TextArea) *Node {
return self.asElement().asNode();
}
pub fn asConstNode(self: *const TextArea) *const Node {
return self.asConstElement().asConstNode();
}
pub fn getValue(self: *const TextArea) []const u8 {
return self._value orelse self._default_value orelse "";
return self._value orelse self.getDefaultValue();
}
pub fn setValue(self: *TextArea, value: []const u8, page: *Page) !void {
@@ -50,7 +52,29 @@ pub fn setValue(self: *TextArea, value: []const u8, page: *Page) !void {
}
pub fn getDefaultValue(self: *const TextArea) []const u8 {
return self._default_value orelse "";
const node = self.asConstNode();
if (node.firstChild()) |child| {
if (child.is(Node.CData.Text)) |txt| {
return txt.getWholeText();
}
}
return "";
}
pub fn setDefaultValue(self: *TextArea, value: []const u8, page: *Page) !void {
const owned = try page.dupeString(value);
const node = self.asNode();
if (node.firstChild()) |child| {
if (child.is(Node.CData.Text)) |txt| {
txt._proto._data = owned;
return;
}
}
// No text child exists, create one
const text_node = try page.createTextNode(owned);
_ = try node.appendChild(text_node, page);
}
pub fn getDisabled(self: *const TextArea) bool {
@@ -119,7 +143,7 @@ pub const JsApi = struct {
};
pub const value = bridge.accessor(TextArea.getValue, TextArea.setValue, .{});
pub const defaultValue = bridge.accessor(TextArea.getDefaultValue, null, .{});
pub const defaultValue = bridge.accessor(TextArea.getDefaultValue, TextArea.setDefaultValue, .{});
pub const disabled = bridge.accessor(TextArea.getDisabled, TextArea.setDisabled, .{});
pub const name = bridge.accessor(TextArea.getName, TextArea.setName, .{});
pub const required = bridge.accessor(TextArea.getRequired, TextArea.setRequired, .{});
@@ -127,20 +151,10 @@ pub const JsApi = struct {
};
pub const Build = struct {
const CData = @import("../../CData.zig");
pub fn complete(node: *Node, _: *const Page) !void {
var self = node.as(TextArea);
// Get default value from text content
if (node.firstChild()) |child| {
if (child.is(CData.Text)) |txt| {
self._default_value = txt.getWholeText();
}
}
// Current state starts equal to default
self._value = self._default_value;
pub fn cloned(source_element: *Element, cloned_element: *Element, _: *Page) !void {
const source = source_element.as(TextArea);
const clone = cloned_element.as(TextArea);
clone._value = source._value;
}
};