Skip to content

Commit 11485d2

Browse files
Merge pull request #962 from lightpanda-io/compareBoundaryPoints
Add Range.compareBoundaryPoints
2 parents 1a9d4af + 8bb2158 commit 11485d2

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

src/browser/dom/range.zig

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ pub const Interfaces = .{
3232

3333
pub const AbstractRange = struct {
3434
collapsed: bool,
35-
end_container: *parser.Node,
35+
end_node: *parser.Node,
3636
end_offset: u32,
37-
start_container: *parser.Node,
37+
start_node: *parser.Node,
3838
start_offset: u32,
3939

4040
pub fn updateCollapsed(self: *AbstractRange) void {
@@ -47,15 +47,15 @@ pub const AbstractRange = struct {
4747
}
4848

4949
pub fn get_endContainer(self: *const AbstractRange) !NodeUnion {
50-
return Node.toInterface(self.end_container);
50+
return Node.toInterface(self.end_node);
5151
}
5252

5353
pub fn get_endOffset(self: *const AbstractRange) u32 {
5454
return self.end_offset;
5555
}
5656

5757
pub fn get_startContainer(self: *const AbstractRange) !NodeUnion {
58-
return Node.toInterface(self.start_container);
58+
return Node.toInterface(self.start_node);
5959
}
6060

6161
pub fn get_startOffset(self: *const AbstractRange) u32 {
@@ -69,15 +69,20 @@ pub const Range = struct {
6969

7070
proto: AbstractRange,
7171

72+
pub const _START_TO_START = 0;
73+
pub const _START_TO_END = 1;
74+
pub const _END_TO_END = 2;
75+
pub const _END_TO_START = 3;
76+
7277
// The Range() constructor returns a newly created Range object whose start
7378
// and end is the global Document object.
7479
// https://developer.mozilla.org/en-US/docs/Web/API/Range/Range
7580
pub fn constructor(page: *Page) Range {
7681
const proto: AbstractRange = .{
7782
.collapsed = true,
78-
.end_container = parser.documentHTMLToNode(page.window.document),
83+
.end_node = parser.documentHTMLToNode(page.window.document),
7984
.end_offset = 0,
80-
.start_container = parser.documentHTMLToNode(page.window.document),
85+
.start_node = parser.documentHTMLToNode(page.window.document),
8186
.start_offset = 0,
8287
};
8388

@@ -87,11 +92,11 @@ pub const Range = struct {
8792
pub fn _setStart(self: *Range, node: *parser.Node, offset_: i32) !void {
8893
try ensureValidOffset(node, offset_);
8994
const offset: u32 = @intCast(offset_);
90-
const position = compare(node, offset, self.proto.start_container, self.proto.start_offset) catch |err| switch (err) {
95+
const position = compare(node, offset, self.proto.start_node, self.proto.start_offset) catch |err| switch (err) {
9196
error.WrongDocument => blk: {
9297
// allow a node with a different root than the current, or
9398
// a disconnected one. Treat it as if it's "after", so that
94-
// we also update the end_offset and end_container.
99+
// we also update the end_offset and end_node.
95100
break :blk 1;
96101
},
97102
else => return err,
@@ -101,34 +106,34 @@ pub const Range = struct {
101106
// if we're setting the node after the current start, the end must
102107
// be set too.
103108
self.proto.end_offset = offset;
104-
self.proto.end_container = node;
109+
self.proto.end_node = node;
105110
}
106-
self.proto.start_container = node;
111+
self.proto.start_node = node;
107112
self.proto.start_offset = offset;
108113
self.proto.updateCollapsed();
109114
}
110115

111116
pub fn _setStartBefore(self: *Range, node: *parser.Node) !void {
112117
const parent, const index = try getParentAndIndex(node);
113-
self.proto.start_container = parent;
118+
self.proto.start_node = parent;
114119
self.proto.start_offset = index;
115120
}
116121

117122
pub fn _setStartAfter(self: *Range, node: *parser.Node) !void {
118123
const parent, const index = try getParentAndIndex(node);
119-
self.proto.start_container = parent;
124+
self.proto.start_node = parent;
120125
self.proto.start_offset = index + 1;
121126
}
122127

123128
pub fn _setEnd(self: *Range, node: *parser.Node, offset_: i32) !void {
124129
try ensureValidOffset(node, offset_);
125130
const offset: u32 = @intCast(offset_);
126131

127-
const position = compare(node, offset, self.proto.start_container, self.proto.start_offset) catch |err| switch (err) {
132+
const position = compare(node, offset, self.proto.start_node, self.proto.start_offset) catch |err| switch (err) {
128133
error.WrongDocument => blk: {
129134
// allow a node with a different root than the current, or
130135
// a disconnected one. Treat it as if it's "before", so that
131-
// we also update the end_offset and end_container.
136+
// we also update the end_offset and end_node.
132137
break :blk -1;
133138
},
134139
else => return err,
@@ -138,23 +143,23 @@ pub const Range = struct {
138143
// if we're setting the node before the current start, the start
139144
// must be set too.
140145
self.proto.start_offset = offset;
141-
self.proto.start_container = node;
146+
self.proto.start_node = node;
142147
}
143148

144-
self.proto.end_container = node;
149+
self.proto.end_node = node;
145150
self.proto.end_offset = offset;
146151
self.proto.updateCollapsed();
147152
}
148153

149154
pub fn _setEndBefore(self: *Range, node: *parser.Node) !void {
150155
const parent, const index = try getParentAndIndex(node);
151-
self.proto.end_container = parent;
156+
self.proto.end_node = parent;
152157
self.proto.end_offset = index;
153158
}
154159

155160
pub fn _setEndAfter(self: *Range, node: *parser.Node) !void {
156161
const parent, const index = try getParentAndIndex(node);
157-
self.proto.end_container = parent;
162+
self.proto.end_node = parent;
158163
self.proto.end_offset = index + 1;
159164
}
160165

@@ -166,9 +171,9 @@ pub const Range = struct {
166171
}
167172

168173
pub fn _selectNodeContents(self: *Range, node: *parser.Node) !void {
169-
self.proto.start_container = node;
174+
self.proto.start_node = node;
170175
self.proto.start_offset = 0;
171-
self.proto.end_container = node;
176+
self.proto.end_node = node;
172177

173178
// Set end_offset
174179
switch (try parser.nodeType(node)) {
@@ -196,16 +201,16 @@ pub const Range = struct {
196201
return .{
197202
.proto = .{
198203
.collapsed = self.proto.collapsed,
199-
.end_container = self.proto.end_container,
204+
.end_node = self.proto.end_node,
200205
.end_offset = self.proto.end_offset,
201-
.start_container = self.proto.start_container,
206+
.start_node = self.proto.start_node,
202207
.start_offset = self.proto.start_offset,
203208
},
204209
};
205210
}
206211

207212
pub fn _comparePoint(self: *const Range, node: *parser.Node, offset_: i32) !i32 {
208-
const start = self.proto.start_container;
213+
const start = self.proto.start_node;
209214
if (try parser.nodeGetRootNode(start) != try parser.nodeGetRootNode(node)) {
210215
// WPT really wants this error to be first. Later, when we check
211216
// if the relative position is 'disconnected', it'll also catch this
@@ -225,7 +230,7 @@ pub const Range = struct {
225230
return -1;
226231
}
227232

228-
if (try compare(node, offset, self.proto.end_container, self.proto.end_offset) == 1) {
233+
if (try compare(node, offset, self.proto.end_node, self.proto.end_offset) == 1) {
229234
return 1;
230235
}
231236

@@ -240,7 +245,7 @@ pub const Range = struct {
240245
}
241246

242247
pub fn _intersectsNode(self: *const Range, node: *parser.Node) !bool {
243-
const start_root = try parser.nodeGetRootNode(self.proto.start_container);
248+
const start_root = try parser.nodeGetRootNode(self.proto.start_node);
244249
const node_root = try parser.nodeGetRootNode(node);
245250
if (start_root != node_root) {
246251
return false;
@@ -251,19 +256,29 @@ pub const Range = struct {
251256
else => return err,
252257
};
253258

254-
if (try compare(parent, index + 1, self.proto.start_container, self.proto.start_offset) != 1) {
259+
if (try compare(parent, index + 1, self.proto.start_node, self.proto.start_offset) != 1) {
255260
// node isn't after start, can't intersect
256261
return false;
257262
}
258263

259-
if (try compare(parent, index, self.proto.end_container, self.proto.end_offset) != -1) {
264+
if (try compare(parent, index, self.proto.end_node, self.proto.end_offset) != -1) {
260265
// node isn't before end, can't intersect
261266
return false;
262267
}
263268

264269
return true;
265270
}
266271

272+
pub fn _compareBoundaryPoints(self: *const Range, how: i32, other: *const Range) !i32 {
273+
return switch (how) {
274+
_START_TO_START => compare(self.proto.start_node, self.proto.start_offset, other.proto.start_node, other.proto.start_offset),
275+
_START_TO_END => compare(self.proto.start_node, self.proto.start_offset, other.proto.end_node, other.proto.end_offset),
276+
_END_TO_END => compare(self.proto.end_node, self.proto.end_offset, other.proto.end_node, other.proto.end_offset),
277+
_END_TO_START => compare(self.proto.end_node, self.proto.end_offset, other.proto.start_node, other.proto.start_offset),
278+
else => error.NotSupported, // this is the correct DOM Exception to return
279+
};
280+
}
281+
267282
// The Range.detach() method does nothing. It used to disable the Range
268283
// object and enable the browser to release associated resources. The
269284
// method has been kept for compatibility.

0 commit comments

Comments
 (0)