mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-15 15:58:57 +00:00
Merge pull request #1252 from lightpanda-io/ignore-comment
improve a little bit Element.innerText
This commit is contained in:
@@ -7,6 +7,9 @@
|
|||||||
This is a <br>
|
This is a <br>
|
||||||
text
|
text
|
||||||
</div>
|
</div>
|
||||||
|
<p id=d3><span>Hello</span> <span>World</span></p>
|
||||||
|
<p id=d4><span>Hello</span>
|
||||||
|
<span>World</span></p>
|
||||||
|
|
||||||
<script id=innerHTML>
|
<script id=innerHTML>
|
||||||
const d1 = $('#d1');
|
const d1 = $('#d1');
|
||||||
@@ -170,7 +173,7 @@
|
|||||||
testing.expectEqual('new content', d1.innerText);
|
testing.expectEqual('new content', d1.innerText);
|
||||||
testing.expectEqual(null, $('#link2'));
|
testing.expectEqual(null, $('#link2'));
|
||||||
|
|
||||||
// TODO innerText is not rendered correctly for now.
|
testing.expectEqual("This is a\ntext", d2.innerText);
|
||||||
//testing.expectEqual("This is a\ntext", d2.innerText);
|
testing.expectEqual("Hello World", $('#d3').innerText);
|
||||||
testing.expectEqual(" This is a \n text ", d2.innerText);
|
testing.expectEqual("Hello World", $('#d4').innerText);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ pub const RenderOpts = struct {
|
|||||||
};
|
};
|
||||||
// Replace successives whitespaces with one withespace.
|
// Replace successives whitespaces with one withespace.
|
||||||
// Trims left and right according to the options.
|
// Trims left and right according to the options.
|
||||||
pub fn render(self: *const CData, writer: *std.io.Writer, opts: RenderOpts) !void {
|
// Returns true if the string ends with a trimmed whitespace.
|
||||||
|
pub fn render(self: *const CData, writer: *std.io.Writer, opts: RenderOpts) !bool {
|
||||||
var start: usize = 0;
|
var start: usize = 0;
|
||||||
var prev_w: ?bool = null;
|
var prev_w: ?bool = null;
|
||||||
var is_w: bool = undefined;
|
var is_w: bool = undefined;
|
||||||
@@ -110,11 +111,15 @@ pub fn render(self: *const CData, writer: *std.io.Writer, opts: RenderOpts) !voi
|
|||||||
// If the string contains only whitespaces, don't write it.
|
// If the string contains only whitespaces, don't write it.
|
||||||
if (start > 0 and opts.trim_right == false) {
|
if (start > 0 and opts.trim_right == false) {
|
||||||
try writer.writeByte(' ');
|
try writer.writeByte(' ');
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// last chunk is non whitespaces.
|
// last chunk is non whitespaces.
|
||||||
try writer.writeAll(s[start..]);
|
try writer.writeAll(s[start..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setData(self: *CData, value: ?[]const u8, page: *Page) !void {
|
pub fn setData(self: *CData, value: ?[]const u8, page: *Page) !void {
|
||||||
@@ -288,19 +293,20 @@ test "WebApi: CData.render" {
|
|||||||
const TestCase = struct {
|
const TestCase = struct {
|
||||||
value: []const u8,
|
value: []const u8,
|
||||||
expected: []const u8,
|
expected: []const u8,
|
||||||
|
result: bool = false,
|
||||||
opts: RenderOpts = .{},
|
opts: RenderOpts = .{},
|
||||||
};
|
};
|
||||||
|
|
||||||
const test_cases = [_]TestCase{
|
const test_cases = [_]TestCase{
|
||||||
.{ .value = " ", .expected = "" },
|
.{ .value = " ", .expected = "", .result = true },
|
||||||
.{ .value = " ", .expected = "", .opts = .{ .trim_left = false, .trim_right = false } },
|
.{ .value = " ", .expected = "", .opts = .{ .trim_left = false, .trim_right = false }, .result = true },
|
||||||
.{ .value = "foo bar", .expected = "foo bar" },
|
.{ .value = "foo bar", .expected = "foo bar" },
|
||||||
.{ .value = "foo bar", .expected = "foo bar" },
|
.{ .value = "foo bar", .expected = "foo bar" },
|
||||||
.{ .value = " foo bar", .expected = "foo bar" },
|
.{ .value = " foo bar", .expected = "foo bar" },
|
||||||
.{ .value = "foo bar ", .expected = "foo bar" },
|
.{ .value = "foo bar ", .expected = "foo bar", .result = true },
|
||||||
.{ .value = " foo bar ", .expected = "foo bar" },
|
.{ .value = " foo bar ", .expected = "foo bar", .result = true },
|
||||||
.{ .value = "foo\n\tbar", .expected = "foo bar" },
|
.{ .value = "foo\n\tbar", .expected = "foo bar" },
|
||||||
.{ .value = "\tfoo bar baz \t\n yeah\r\n", .expected = "foo bar baz yeah" },
|
.{ .value = "\tfoo bar baz \t\n yeah\r\n", .expected = "foo bar baz yeah", .result = true },
|
||||||
.{ .value = " foo bar", .expected = " foo bar", .opts = .{ .trim_left = false } },
|
.{ .value = " foo bar", .expected = " foo bar", .opts = .{ .trim_left = false } },
|
||||||
.{ .value = "foo bar ", .expected = "foo bar ", .opts = .{ .trim_right = false } },
|
.{ .value = "foo bar ", .expected = "foo bar ", .opts = .{ .trim_right = false } },
|
||||||
.{ .value = " foo bar ", .expected = " foo bar ", .opts = .{ .trim_left = false, .trim_right = false } },
|
.{ .value = " foo bar ", .expected = " foo bar ", .opts = .{ .trim_left = false, .trim_right = false } },
|
||||||
@@ -317,8 +323,9 @@ test "WebApi: CData.render" {
|
|||||||
._data = test_case.value,
|
._data = test_case.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
try cdata.render(&buffer.writer, test_case.opts);
|
const result = try cdata.render(&buffer.writer, test_case.opts);
|
||||||
|
|
||||||
try std.testing.expectEqualStrings(test_case.expected, buffer.written());
|
try std.testing.expectEqualStrings(test_case.expected, buffer.written());
|
||||||
|
try std.testing.expect(result == test_case.result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,21 +228,46 @@ pub fn getNamespaceURI(self: *const Element) []const u8 {
|
|||||||
// innerText represents the **rendered** text content of a node and its
|
// innerText represents the **rendered** text content of a node and its
|
||||||
// descendants.
|
// descendants.
|
||||||
pub fn getInnerText(self: *Element, writer: *std.Io.Writer) !void {
|
pub fn getInnerText(self: *Element, writer: *std.Io.Writer) !void {
|
||||||
|
var state = innerTextState{};
|
||||||
|
return try self._getInnerText(writer, &state);
|
||||||
|
}
|
||||||
|
const innerTextState = struct {
|
||||||
|
pre_w: bool = false,
|
||||||
|
trim_left: bool = true,
|
||||||
|
};
|
||||||
|
fn _getInnerText(self: *Element, writer: *std.Io.Writer, state: *innerTextState) !void {
|
||||||
var it = self.asNode().childrenIterator();
|
var it = self.asNode().childrenIterator();
|
||||||
while (it.next()) |child| {
|
while (it.next()) |child| {
|
||||||
switch (child._type) {
|
switch (child._type) {
|
||||||
.element => |e| switch (e._type) {
|
.element => |e| switch (e._type) {
|
||||||
.html => |he| switch (he._type) {
|
.html => |he| switch (he._type) {
|
||||||
.br => try writer.writeByte('\n'),
|
.br => {
|
||||||
.script, .style, .template => continue,
|
try writer.writeByte('\n');
|
||||||
else => try e.getInnerText(writer), // TODO check if elt is hidden.
|
state.pre_w = false; // prevent a next pre space.
|
||||||
|
state.trim_left = true;
|
||||||
|
},
|
||||||
|
.script, .style, .template => {
|
||||||
|
state.pre_w = false; // prevent a next pre space.
|
||||||
|
state.trim_left = true;
|
||||||
|
},
|
||||||
|
else => try e._getInnerText(writer, state), // TODO check if elt is hidden.
|
||||||
},
|
},
|
||||||
.svg => {},
|
.svg => {},
|
||||||
},
|
},
|
||||||
.cdata => |c| switch (c._type) {
|
.cdata => |c| switch (c._type) {
|
||||||
.comment => continue,
|
.comment => {
|
||||||
.text => try c.render(writer, .{ .trim_right = false, .trim_left = false }),
|
state.pre_w = false; // prevent a next pre space.
|
||||||
.cdata_section => try writer.writeAll(c._data),
|
state.trim_left = true;
|
||||||
|
},
|
||||||
|
.text => {
|
||||||
|
if (state.pre_w) try writer.writeByte(' ');
|
||||||
|
state.pre_w = try c.render(writer, .{ .trim_left = state.trim_left });
|
||||||
|
// if we had a pre space, trim left next one.
|
||||||
|
state.trim_left = state.pre_w;
|
||||||
|
},
|
||||||
|
// CDATA sections should not be used within HTML. They are
|
||||||
|
// considered comments and are not displayed.
|
||||||
|
.cdata_section => {},
|
||||||
},
|
},
|
||||||
.document => {},
|
.document => {},
|
||||||
.document_type => {},
|
.document_type => {},
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
const log = @import("../../../../log.zig");
|
const log = @import("../../../../log.zig");
|
||||||
const js = @import("../../../js/js.zig");
|
const js = @import("../../../js/js.zig");
|
||||||
@@ -93,6 +94,10 @@ pub fn getNoModule(self: *const Script) bool {
|
|||||||
return self.asConstElement().getAttributeSafe("nomodule") != null;
|
return self.asConstElement().getAttributeSafe("nomodule") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setInnerText(self: *Script, text: []const u8, page: *Page) !void {
|
||||||
|
try self.asNode().setTextContent(text, page);
|
||||||
|
}
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
pub const bridge = js.Bridge(Script);
|
pub const bridge = js.Bridge(Script);
|
||||||
|
|
||||||
@@ -107,6 +112,12 @@ pub const JsApi = struct {
|
|||||||
pub const onload = bridge.accessor(Script.getOnLoad, Script.setOnLoad, .{});
|
pub const onload = bridge.accessor(Script.getOnLoad, Script.setOnLoad, .{});
|
||||||
pub const onerror = bridge.accessor(Script.getOnError, Script.setOnError, .{});
|
pub const onerror = bridge.accessor(Script.getOnError, Script.setOnError, .{});
|
||||||
pub const noModule = bridge.accessor(Script.getNoModule, null, .{});
|
pub const noModule = bridge.accessor(Script.getNoModule, null, .{});
|
||||||
|
pub const innerText = bridge.accessor(_innerText, Script.setInnerText, .{});
|
||||||
|
fn _innerText(self: *Script, page: *const Page) ![]const u8 {
|
||||||
|
var buf = std.Io.Writer.Allocating.init(page.call_arena);
|
||||||
|
try self.asNode().getTextContent(&buf.writer);
|
||||||
|
return buf.written();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Build = struct {
|
pub const Build = struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user