diff options
author | Mukilan Thiyagarajan <mukilanthiagarajan@gmail.com> | 2017-01-28 17:20:01 +0300 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2017-03-15 16:39:55 +0100 |
commit | 38a61712e41ddeebb52cace6a9787735947964a4 (patch) | |
tree | f9949282e968e9a8fd57a8c8aa1fd63a59d0a89c /components/script/dom/node.rs | |
parent | f90e19f7055387a14cabdf11f77335c7763e3fb7 (diff) | |
download | servo-38a61712e41ddeebb52cace6a9787735947964a4.tar.gz servo-38a61712e41ddeebb52cace6a9787735947964a4.zip |
Implement the form owner concept
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r-- | components/script/dom/node.rs | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index fce1ce4826d..e21dfa2bee0 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -162,7 +162,11 @@ bitflags! { /// Whether any ancestor is a fragmentation container const CAN_BE_FRAGMENTED = 0x40, #[doc = "Specifies whether this node needs to be dirted when viewport size changed."] - const DIRTY_ON_VIEWPORT_SIZE_CHANGE = 0x80 + const DIRTY_ON_VIEWPORT_SIZE_CHANGE = 0x80, + + #[doc = "Specifies whether the parser has set an associated form owner for \ + this element. Only applicable for form-associatable elements."] + const PARSER_ASSOCIATED_FORM_OWNER = 0x90, } } @@ -286,6 +290,11 @@ impl Node { for node in child.traverse_preorder() { // Out-of-document elements never have the descendants flag set. node.set_flag(IS_IN_DOC | HAS_DIRTY_DESCENDANTS, false); + } + for node in child.traverse_preorder() { + // This needs to be in its own loop, because unbind_from_tree may + // rely on the state of IS_IN_DOC of the context node's descendants, + // e.g. when removing a <form>. vtable_for(&&*node).unbind_from_tree(&context); node.style_and_layout_data.get().map(|d| node.dispose(d)); } @@ -2656,3 +2665,41 @@ impl Into<LayoutElementType> for ElementTypeId { } } +/// Helper trait to insert an element into vector whose elements +/// are maintained in tree order +pub trait VecPreOrderInsertionHelper<T> { + fn insert_pre_order(&mut self, elem: &T, tree_root: &Node); +} + +impl<T> VecPreOrderInsertionHelper<T> for Vec<JS<T>> + where T: DerivedFrom<Node> + DomObject +{ + /// This algorithm relies on the following assumptions: + /// * any elements inserted in this vector share the same tree root + /// * any time an element is removed from the tree root, it is also removed from this array + /// * any time an element is moved within the tree, it is removed from this array and re-inserted + /// + /// Under these assumptions, an element's tree-order position in this array can be determined by + /// performing a [preorder traversal](https://dom.spec.whatwg.org/#concept-tree-order) of the tree root's children, + /// and increasing the destination index in the array every time a node in the array is encountered during + /// the traversal. + fn insert_pre_order(&mut self, elem: &T, tree_root: &Node) { + if self.is_empty() { + self.push(JS::from_ref(elem)); + return; + } + + let elem_node = elem.upcast::<Node>(); + let mut head: usize = 0; + for node in tree_root.traverse_preorder() { + let head_node = Root::upcast::<Node>(Root::from_ref(&*self[head])); + if head_node == node { + head += 1; + } + if elem_node == node.r() || head == self.len() { + break; + } + } + self.insert(head, JS::from_ref(elem)); + } +} |