aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/script/dom/document.rs41
-rw-r--r--src/components/script/dom/element.rs4
m---------src/platform/linux/fontconfig0
-rw-r--r--src/test/content/test_document_getElementById_tree_order.html40
-rw-r--r--src/test/ref/basic.list1
-rw-r--r--src/test/ref/setattribute_id_restyle_a.html12
-rw-r--r--src/test/ref/setattribute_id_restyle_b.html6
7 files changed, 96 insertions, 8 deletions
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index 6d8c7fe9313..a3a95277cc1 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -7,6 +7,7 @@ use dom::bindings::codegen::InheritTypes::{DocumentBase, NodeCast, DocumentCast}
use dom::bindings::codegen::InheritTypes::{HTMLHeadElementCast, TextCast, ElementCast};
use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast};
use dom::bindings::codegen::DocumentBinding;
+use dom::bindings::codegen::NodeBinding::NodeConstants::{DOCUMENT_POSITION_CONTAINS, DOCUMENT_POSITION_PRECEDING};
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError};
@@ -59,7 +60,7 @@ pub struct Document {
node: Node,
reflector_: Reflector,
window: JS<Window>,
- idmap: HashMap<DOMString, JS<Element>>,
+ idmap: HashMap<DOMString, ~[JS<Element>]>,
implementation: Option<JS<DOMImplementation>>,
content_type: DOMString,
encoding_name: DOMString,
@@ -249,7 +250,7 @@ impl Document {
// http://dom.spec.whatwg.org/#dom-document-getelementbyid.
match self.idmap.find_equiv(&id) {
None => None,
- Some(node) => Some(node.clone()),
+ Some(ref elements) => Some(elements[0].clone()),
}
}
@@ -647,8 +648,22 @@ impl Document {
/// Remove any existing association between the provided id and any elements in this document.
pub fn unregister_named_element(&mut self,
+ abstract_self: &JS<Element>,
id: DOMString) {
- self.idmap.remove(&id);
+ let mut is_empty = false;
+ match self.idmap.find_mut(&id) {
+ None => {},
+ Some(elements) => {
+ let position = elements.iter()
+ .position(|element| element == abstract_self)
+ .expect("This element should be in registered.");
+ elements.remove(position);
+ is_empty = elements.is_empty();
+ }
+ }
+ if is_empty {
+ self.idmap.remove(&id);
+ }
}
/// Associate an element present in this document with the provided id.
@@ -665,12 +680,26 @@ impl Document {
// FIXME https://github.com/mozilla/rust/issues/13195
// Use mangle() when it exists again.
match self.idmap.find_mut(&id) {
- Some(v) => {
- *v = element.clone();
+ Some(elements) => {
+ let new_node = NodeCast::from(element);
+ let mut head : uint = 0u;
+ let mut tail : uint = elements.len();
+ while head < tail {
+ let middle = ((head + tail) / 2) as int;
+ let elem = &elements[middle];
+ let js_node = NodeCast::from(elem);
+ let position = elem.get().node.CompareDocumentPosition(&js_node, &new_node);
+ if position == DOCUMENT_POSITION_PRECEDING || position == DOCUMENT_POSITION_PRECEDING + DOCUMENT_POSITION_CONTAINS {
+ tail = middle as uint;
+ } else {
+ head = middle as uint + 1u;
+ }
+ }
+ elements.insert(tail, element.clone());
return;
},
None => (),
}
- self.idmap.insert(id, element.clone());
+ self.idmap.insert(id, ~[element.clone()]);
}
}
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index 8299f516119..3361765e3c0 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -361,7 +361,7 @@ impl AttributeHandlers for JS<Element> {
// "borrowed value does not live long enough"
let mut doc = node.get().owner_doc().clone();
let doc = doc.get_mut();
- doc.unregister_named_element(old_value);
+ doc.unregister_named_element(self, old_value);
}
_ => ()
}
@@ -654,7 +654,7 @@ impl IElement for JS<Element> {
match self.get_attribute(Null, "id") {
Some(attr) => {
let mut doc = document_from_node(self);
- doc.get_mut().unregister_named_element(attr.get().Value());
+ doc.get_mut().unregister_named_element(self, attr.get().Value());
}
_ => ()
}
diff --git a/src/platform/linux/fontconfig b/src/platform/linux/fontconfig
-Subproject b2cfb1f4b3561e01a58359cd18929457a0486db
+Subproject 0450af3d92f1fb4f269cc64e58647871a5bf728
diff --git a/src/test/content/test_document_getElementById_tree_order.html b/src/test/content/test_document_getElementById_tree_order.html
new file mode 100644
index 00000000000..ccf0c37bb01
--- /dev/null
+++ b/src/test/content/test_document_getElementById_tree_order.html
@@ -0,0 +1,40 @@
+<html>
+ <head>
+ <script src="harness.js"></script>
+ </head>
+ <body>
+ <div id="a">
+ </div>
+ <div id="b">
+ <p id="b">P</p>
+ <input id="b" type="submit" value="Submit">
+ </div>
+ <script>
+ {
+ var b = document.getElementById("b");
+ is_a(b, HTMLDivElement);
+ var a = document.getElementById("a");
+ var p = document.createElement("p");
+ p.id = "b";
+ a.appendChild(p);
+ var newB = document.getElementById("b");
+ is_a(newB, HTMLParagraphElement);
+ }
+ {
+ var gbody = document.getElementsByTagName("body")[0];
+ var div = document.createElement("div");
+ div.setAttribute("id", "c");
+ var h1 = document.createElement("h1");
+ h1.setAttribute("id", "c");
+ gbody.appendChild(div);
+ gbody.appendChild(h1);
+ var c = document.getElementById("c");
+ is_a(c, HTMLDivElement);
+ gbody.removeChild(div);
+ var newC = document.getElementById("c");
+ is_a(newC, HTMLHeadingElement);
+ }
+ finish();
+ </script>
+ </body>
+</html>
diff --git a/src/test/ref/basic.list b/src/test/ref/basic.list
index 4df86c52e8b..d59e1fb229f 100644
--- a/src/test/ref/basic.list
+++ b/src/test/ref/basic.list
@@ -65,3 +65,4 @@
== background_repeat_y_a.html background_repeat_y_b.html
== background_repeat_none_a.html background_repeat_none_b.html
== background_repeat_both_a.html background_repeat_both_b.html
+== setattribute_id_restyle_a.html setattribute_id_restyle_b.html
diff --git a/src/test/ref/setattribute_id_restyle_a.html b/src/test/ref/setattribute_id_restyle_a.html
new file mode 100644
index 00000000000..469ce797db7
--- /dev/null
+++ b/src/test/ref/setattribute_id_restyle_a.html
@@ -0,0 +1,12 @@
+<style>
+ #foo { background-color: #FF0000; }
+</style>
+
+<div>hello</div>
+<div id="">world</div>
+
+<script>
+ var divs = document.getElementsByTagName('div');
+ divs[0].setAttribute('id', 'foo');
+ divs[1].setAttribute('id', 'foo');
+</script>
diff --git a/src/test/ref/setattribute_id_restyle_b.html b/src/test/ref/setattribute_id_restyle_b.html
new file mode 100644
index 00000000000..f16fe454c50
--- /dev/null
+++ b/src/test/ref/setattribute_id_restyle_b.html
@@ -0,0 +1,6 @@
+<style>
+ #foo { background-color: #FF0000; }
+</style>
+
+<div id="foo">hello</div>
+<div id="foo">world</div>