Skip to content

Commit be20a55

Browse files
authored
Let embedder handle "maybe clone option into selectedcontent" algorithm (#719)
* Let embedder handle "maybe clone option into selectedcontent" algorithm Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Prepare a new release Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
1 parent 1a097f7 commit be20a55

File tree

10 files changed

+179
-85
lines changed

10 files changed

+179
-85
lines changed

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ members = [
1010
]
1111

1212
[workspace.package]
13-
version = "0.37.1"
13+
version = "0.38.0"
1414
license = "MIT OR Apache-2.0"
1515
authors = [ "The html5ever Project Developers" ]
1616
repository = "https://github.com/servo/html5ever"
@@ -21,9 +21,9 @@ rust-version = "1.71.0"
2121
# Repo dependencies
2222
tendril = { version = "0.5", path = "tendril" }
2323
web_atoms = { version = "0.2.1", path = "web_atoms" }
24-
markup5ever = { version = "0.37.1", path = "markup5ever" }
25-
xml5ever = { version = "0.37.1", path = "xml5ever" }
26-
html5ever = { version = "0.37.1", path = "html5ever" }
24+
markup5ever = { version = "0.38", path = "markup5ever" }
25+
xml5ever = { version = "0.38", path = "xml5ever" }
26+
html5ever = { version = "0.38", path = "html5ever" }
2727

2828
# External dependencies
2929
encoding_rs = "0.8.12"

html5ever/examples/arena.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -339,21 +339,6 @@ impl<'arena> TreeSink for Sink<'arena> {
339339
new_parent.append(child)
340340
}
341341
}
342-
343-
fn clone_subtree(&self, node: &Self::Handle) -> Self::Handle {
344-
// Allocate the new node in the arena using Clone
345-
let cloned_node = self.arena.alloc(Node::new(node.data.clone()));
346-
347-
// Clone all children and append them
348-
let mut child = node.first_child.get();
349-
while let Some(current_child) = child {
350-
let cloned_child = self.clone_subtree(&current_child);
351-
cloned_node.append(cloned_child);
352-
child = current_child.next_sibling.get();
353-
}
354-
355-
cloned_node
356-
}
357342
}
358343

359344
/// In this example an "arena" is created and filled with the DOM nodes.

html5ever/examples/noop-tree-builder.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,6 @@ impl TreeSink for Sink {
113113
fn remove_from_parent(&self, _target: &usize) {}
114114
fn reparent_children(&self, _node: &usize, _new_parent: &usize) {}
115115
fn mark_script_already_started(&self, _node: &usize) {}
116-
117-
fn clone_subtree(&self, _node: &Self::Handle) -> Self::Handle {
118-
// For this noop example, just return a new placeholder ID
119-
self.get_id()
120-
}
121116
}
122117

123118
/// In this example we implement the TreeSink trait which takes each parsed elements and insert

html5ever/examples/print-tree-actions.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,6 @@ impl TreeSink for Sink {
167167
fn pop(&self, elem: &usize) {
168168
println!("Popped element {elem}");
169169
}
170-
171-
fn clone_subtree(&self, node: &Self::Handle) -> Self::Handle {
172-
println!("Clone subtree for node {node}");
173-
// For this example, just return a new placeholder ID
174-
self.get_id()
175-
}
176170
}
177171

178172
/// Same example as the "noop-tree-builder", but this time every function implemented in our

html5ever/src/tree_builder/mod.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ pub struct TreeBuilder<Handle, Sink> {
119119
/// Form element pointer.
120120
form_elem: RefCell<Option<Handle>>,
121121

122-
/// selectedcontent element pointer.
123-
selectedcontent_elem: RefCell<Option<Handle>>,
124-
//§ END
125122
/// Frameset-ok flag.
126123
frameset_ok: Cell<bool>,
127124

@@ -166,7 +163,6 @@ where
166163
active_formatting: Default::default(),
167164
head_elem: Default::default(),
168165
form_elem: Default::default(),
169-
selectedcontent_elem: Default::default(),
170166
frameset_ok: Cell::new(true),
171167
ignore_lf: Default::default(),
172168
foster_parenting: Default::default(),
@@ -207,7 +203,6 @@ where
207203
active_formatting: Default::default(),
208204
head_elem: Default::default(),
209205
form_elem: RefCell::new(form_elem),
210-
selectedcontent_elem: Default::default(),
211206
frameset_ok: Cell::new(true),
212207
ignore_lf: Default::default(),
213208
foster_parenting: Default::default(),
@@ -290,10 +285,6 @@ where
290285
tracer.trace_handle(form_elem);
291286
}
292287

293-
if let Some(selectedcontent_elem) = self.selectedcontent_elem.borrow().as_ref() {
294-
tracer.trace_handle(selectedcontent_elem);
295-
}
296-
297288
if let Some(context_elem) = self.context_elem.borrow().as_ref() {
298289
tracer.trace_handle(context_elem);
299290
}
@@ -1360,7 +1351,7 @@ where
13601351
// FIXME: application cache selection algorithm
13611352
}
13621353

1363-
// https://html.spec.whatwg.org/multipage/#create-an-element-for-the-token
1354+
/// <https://html.spec.whatwg.org/multipage/#create-an-element-for-the-token>
13641355
fn insert_element(
13651356
&self,
13661357
push: PushFlag,
@@ -1405,12 +1396,6 @@ where
14051396

14061397
self.insert_at(insertion_point, AppendNode(elem.clone()));
14071398

1408-
if qname.local == local_name!("selectedcontent")
1409-
&& self.selectedcontent_elem.borrow().is_none()
1410-
{
1411-
*self.selectedcontent_elem.borrow_mut() = Some(elem.clone());
1412-
}
1413-
14141399
match push {
14151400
PushFlag::Push => self.push(&elem),
14161401
PushFlag::NoPush => (),
@@ -1595,19 +1580,6 @@ where
15951580
self.remove_from_stack(&node);
15961581
}
15971582

1598-
fn maybe_clone_option_into_selectedcontent(&self, option: &Handle) {
1599-
if let Some(selectedcontent) = self.selectedcontent_elem.borrow().as_ref().cloned() {
1600-
self.clone_option_into_selectedcontent(option, &selectedcontent);
1601-
}
1602-
}
1603-
1604-
fn clone_option_into_selectedcontent(&self, option: &Handle, selectedcontent: &Handle) {
1605-
self.sink
1606-
.reparent_children(selectedcontent, &self.sink.get_document());
1607-
let cloned_option = self.sink.clone_subtree(option);
1608-
self.sink.reparent_children(&cloned_option, selectedcontent);
1609-
}
1610-
16111583
//§ tree-construction
16121584
fn is_foreign(&self, token: &Token) -> bool {
16131585
if let Token::Eof = *token {

html5ever/src/tree_builder/rules.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,8 @@ where
662662
}
663663
ProcessResult::Done
664664
},
665-
665+
// FIXME: This branch does not exist like this in the specification, because it should run for
666+
// implicitly closed option tags too. See https://github.com/servo/html5ever/issues/712.
666667
Token::Tag(tag @ tag!(</option>)) => {
667668
let option_in_stack = self
668669
.open_elems
@@ -680,7 +681,8 @@ where
680681
.iter()
681682
.any(|elem| self.sink.same_node(elem, &option))
682683
{
683-
self.maybe_clone_option_into_selectedcontent(&option);
684+
self.sink
685+
.maybe_clone_an_option_into_selectedcontent(&option);
684686
}
685687
}
686688

html5ever/tests/driver.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,6 @@ impl TreeSink for Sink {
9999
fn remove_from_parent(&self, _target: &usize) {}
100100
fn reparent_children(&self, _node: &usize, _new_parent: &usize) {}
101101
fn mark_script_already_started(&self, _node: &usize) {}
102-
103-
fn clone_subtree(&self, _node: &Self::Handle) -> Self::Handle {
104-
// For this noop example, just return a new placeholder ID
105-
self.get_id()
106-
}
107102
}
108103

109104
#[test]

markup5ever/interface/tree_builder.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,6 @@ pub trait TreeSink {
236236
/// Remove all the children from node and append them to new_parent.
237237
fn reparent_children(&self, node: &Self::Handle, new_parent: &Self::Handle);
238238

239-
/// Clone a node and all its descendants, returning the cloned node.
240-
fn clone_subtree(&self, node: &Self::Handle) -> Self::Handle;
241-
242239
/// Returns true if the adjusted current node is an HTML integration point
243240
/// and the token is a start tag.
244241
fn is_mathml_annotation_xml_integration_point(&self, _handle: &Self::Handle) -> bool {
@@ -263,6 +260,17 @@ pub trait TreeSink {
263260
) -> bool {
264261
false
265262
}
263+
264+
/// Implements [`maybe clone an option into selectedcontent`](https://html.spec.whatwg.org/#maybe-clone-an-option-into-selectedcontent).
265+
///
266+
/// The provided handle is guaranteed to be an `<option>` element.
267+
///
268+
/// Leaving this method unimplemented will not cause panics, but will result in a (slightly) incorrect DOM tree.
269+
///
270+
/// This method will never be called from `xml5ever`.
271+
fn maybe_clone_an_option_into_selectedcontent(&self, option: &Self::Handle) {
272+
_ = option;
273+
}
266274
}
267275

268276
/// Trace hooks for a garbage-collected DOM.

0 commit comments

Comments
 (0)