@@ -210,8 +210,40 @@ impl<Handle, Sink> TreeBuilderActions<Handle>
210210
211211 // Insert at the "appropriate place for inserting a node".
212212 fn insert_appropriately ( & mut self , child : NodeOrText < Handle > , override_target : Option < Handle > ) {
213- let insertion_point = self . appropriate_place_for_insertion ( override_target) ;
214- self . insert_at ( insertion_point, child) ;
213+ declare_tag_set ! ( foster_target = "table" "tbody" "tfoot" "thead" "tr" ) ;
214+ let target = override_target. unwrap_or_else ( || self . current_node ( ) ) ;
215+ if !( self . foster_parenting && self . elem_in ( target. clone ( ) , foster_target) ) {
216+ if self . html_elem_named ( target. clone ( ) , local_name ! ( "template" ) ) {
217+ // No foster parenting (inside template).
218+ let contents = self . sink . get_template_contents ( target) ;
219+ self . sink . append ( contents, child) ;
220+ } else {
221+ // No foster parenting (the common case).
222+ self . sink . append ( target, child) ;
223+ }
224+ return ;
225+ }
226+
227+ // Foster parenting
228+ let mut iter = self . open_elems . iter ( ) . rev ( ) . peekable ( ) ;
229+ while let Some ( elem) = iter. next ( ) {
230+ if self . html_elem_named ( elem. clone ( ) , local_name ! ( "template" ) ) {
231+ let contents = self . sink . get_template_contents ( elem. clone ( ) ) ;
232+ self . sink . append ( contents, child) ;
233+ return ;
234+ } else if self . html_elem_named ( elem. clone ( ) , local_name ! ( "table" ) ) {
235+ // Try inserting "inside last table's parent node, immediately before last table"
236+ if let Err ( child) = self . sink . append_before_sibling ( elem. clone ( ) , child) {
237+ // If last_table has no parent, we regain ownership of the child.
238+ // Insert "inside previous element, after its last child (if any)"
239+ let previous_element = ( * iter. peek ( ) . unwrap ( ) ) . clone ( ) ;
240+ self . sink . append ( previous_element, child) ;
241+ }
242+ return ;
243+ }
244+ }
245+ let html_elem = self . html_elem ( ) ;
246+ self . sink . append ( html_elem, child) ;
215247 }
216248
217249 fn adoption_agency ( & mut self , subject : LocalName ) {
@@ -743,40 +775,10 @@ impl<Handle, Sink> TreeBuilderActions<Handle>
743775 // FIXME: application cache selection algorithm
744776 }
745777
746- // https://html.spec.whatwg.org/multipage/#create-an-element-for-the-token
747778 fn insert_element ( & mut self , push : PushFlag , ns : Namespace , name : LocalName , attrs : Vec < Attribute > )
748779 -> Handle {
749- declare_tag_set ! ( form_associatable =
750- "button" "fieldset" "input" "object"
751- "output" "select" "textarea" "img" ) ;
752-
753- declare_tag_set ! ( listed = [ form_associatable] - "img" ) ;
754-
755- // Step 7.
756- let qname = QualName :: new ( ns, name) ;
757- let elem = self . sink . create_element ( qname. clone ( ) , attrs. clone ( ) ) ;
758-
759- let insertion_point = self . appropriate_place_for_insertion ( None ) ;
760- let tree_node = match insertion_point {
761- LastChild ( ref p) |
762- BeforeSibling ( ref p) => p. clone ( )
763- } ;
764-
765- // Step 12.
766- if form_associatable ( qname. clone ( ) ) &&
767- self . form_elem . is_some ( ) &&
768- !self . in_html_elem_named ( local_name ! ( "template" ) ) &&
769- !( listed ( qname. clone ( ) ) &&
770- attrs. iter ( ) . any ( |a| a. name == qualname ! ( "" , "form" ) ) ) {
771-
772- let form = self . form_elem . as_ref ( ) . unwrap ( ) . clone ( ) ;
773- if self . sink . same_tree ( tree_node, form. clone ( ) ) {
774- self . sink . associate_with_form ( elem. clone ( ) , form)
775- }
776- }
777-
778- self . insert_at ( insertion_point, AppendNode ( elem. clone ( ) ) ) ;
779-
780+ let elem = self . sink . create_element ( QualName :: new ( ns, name) , attrs) ;
781+ self . insert_appropriately ( AppendNode ( elem. clone ( ) ) , None ) ;
780782 match push {
781783 Push => self . push ( & elem) ,
782784 NoPush => ( ) ,
0 commit comments