mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Upgrade to SM 39
This commit is contained in:
parent
a256f39796
commit
675267b782
205 changed files with 6546 additions and 5340 deletions
|
@ -521,6 +521,7 @@ pub struct LayoutElement<'le> {
|
||||||
|
|
||||||
impl<'le> LayoutElement<'le> {
|
impl<'le> LayoutElement<'le> {
|
||||||
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
|
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
|
||||||
|
use script::dom::element::ElementHelpers;
|
||||||
let style: &Option<PropertyDeclarationBlock> = unsafe {
|
let style: &Option<PropertyDeclarationBlock> = unsafe {
|
||||||
&*self.element.style_attribute().borrow_for_layout()
|
&*self.element.style_attribute().borrow_for_layout()
|
||||||
};
|
};
|
||||||
|
@ -536,6 +537,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_namespace(self) -> &'le Namespace {
|
fn get_namespace(self) -> &'le Namespace {
|
||||||
|
use script::dom::element::ElementHelpers;
|
||||||
self.element.namespace()
|
self.element.namespace()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,7 @@ pub struct UnrootedPass;
|
||||||
// TODO (#3874, sort of): unwrap other types like Vec/Option/HashMap/etc
|
// TODO (#3874, sort of): unwrap other types like Vec/Option/HashMap/etc
|
||||||
fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
|
fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) |
|
ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) =>
|
||||||
ast::TyPtr(ast::MutTy { ty: ref t, ..}) | ast::TyRptr(_, ast::MutTy { ty: ref t, ..}) =>
|
|
||||||
lint_unrooted_ty(cx, &**t, warning),
|
lint_unrooted_ty(cx, &**t, warning),
|
||||||
ast::TyPath(..) => {
|
ast::TyPath(..) => {
|
||||||
match cx.tcx.def_map.borrow()[&ty.id] {
|
match cx.tcx.def_map.borrow()[&ty.id] {
|
||||||
|
@ -47,7 +46,7 @@ fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable:
|
||||||
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
||||||
&self.$field_name
|
&self.$field_name
|
||||||
}
|
}
|
||||||
|
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
||||||
|
self.$field_name.set_jsobject(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_item.map(|it| push(Annotatable::Item(it)))
|
impl_item.map(|it| push(Annotatable::Item(it)))
|
||||||
|
@ -37,6 +40,9 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable:
|
||||||
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
|
||||||
self.$field_name.reflector()
|
self.$field_name.reflector()
|
||||||
}
|
}
|
||||||
|
fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) {
|
||||||
|
self.$field_name.init_reflector(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_item.map(|it| push(Annotatable::Item(it)))
|
impl_item.map(|it| push(Annotatable::Item(it)))
|
||||||
|
|
|
@ -6,18 +6,19 @@ use devtools_traits::{CachedConsoleMessage, CachedConsoleMessageTypes, PAGE_ERRO
|
||||||
use devtools_traits::{EvaluateJSReply, NodeInfo, Modification, TimelineMarker, TimelineMarkerType};
|
use devtools_traits::{EvaluateJSReply, NodeInfo, Modification, TimelineMarker, TimelineMarkerType};
|
||||||
use dom::bindings::conversions::FromJSValConvertible;
|
use dom::bindings::conversions::FromJSValConvertible;
|
||||||
use dom::bindings::conversions::StringificationBehavior;
|
use dom::bindings::conversions::StringificationBehavior;
|
||||||
use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
|
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
|
||||||
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||||
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
|
use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods};
|
||||||
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
|
use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods};
|
||||||
use dom::node::{Node, NodeHelpers};
|
use dom::node::{Node, NodeHelpers};
|
||||||
use dom::window::{WindowHelpers, ScriptHelpers};
|
use dom::window::{WindowHelpers, ScriptHelpers};
|
||||||
use dom::element::Element;
|
|
||||||
use dom::document::DocumentHelpers;
|
use dom::document::DocumentHelpers;
|
||||||
use page::{IterablePage, Page};
|
use page::{IterablePage, Page};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use script_task::{get_page, ScriptTask};
|
use script_task::{get_page, ScriptTask};
|
||||||
|
use js::jsapi::RootedValue;
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -25,53 +26,54 @@ use std::rc::Rc;
|
||||||
|
|
||||||
pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<EvaluateJSReply>){
|
pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<EvaluateJSReply>){
|
||||||
let page = get_page(&*page, pipeline);
|
let page = get_page(&*page, pipeline);
|
||||||
let window = page.window().root();
|
let window = page.window();
|
||||||
let cx = window.r().get_cx();
|
let cx = window.r().get_cx();
|
||||||
let rval = window.r().evaluate_js_on_global_with_result(&eval);
|
let mut rval = RootedValue::new(cx, UndefinedValue());
|
||||||
|
window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut());
|
||||||
|
|
||||||
reply.send(if rval.is_undefined() {
|
reply.send(if rval.ptr.is_undefined() {
|
||||||
EvaluateJSReply::VoidValue
|
EvaluateJSReply::VoidValue
|
||||||
} else if rval.is_boolean() {
|
} else if rval.ptr.is_boolean() {
|
||||||
EvaluateJSReply::BooleanValue(rval.to_boolean())
|
EvaluateJSReply::BooleanValue(rval.ptr.to_boolean())
|
||||||
} else if rval.is_double() {
|
} else if rval.ptr.is_double() {
|
||||||
EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval, ()).unwrap())
|
EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap())
|
||||||
} else if rval.is_string() {
|
} else if rval.ptr.is_string() {
|
||||||
//FIXME: use jsstring_to_str when jsval grows to_jsstring
|
//FIXME: use jsstring_to_str when jsval grows to_jsstring
|
||||||
EvaluateJSReply::StringValue(
|
EvaluateJSReply::StringValue(
|
||||||
FromJSValConvertible::from_jsval(cx, rval, StringificationBehavior::Default).unwrap())
|
FromJSValConvertible::from_jsval(cx, rval.handle(), StringificationBehavior::Default).unwrap())
|
||||||
} else if rval.is_null() {
|
} else if rval.ptr.is_null() {
|
||||||
EvaluateJSReply::NullValue
|
EvaluateJSReply::NullValue
|
||||||
} else {
|
} else {
|
||||||
//FIXME: jsvals don't have an is_int32/is_number yet
|
//FIXME: jsvals don't have an is_int32/is_number yet
|
||||||
assert!(rval.is_object());
|
assert!(rval.ptr.is_object());
|
||||||
panic!("object values unimplemented")
|
panic!("object values unimplemented")
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
|
pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
|
||||||
let page = get_page(&*page, pipeline);
|
let page = get_page(&*page, pipeline);
|
||||||
let document = page.document().root();
|
let document = page.document();
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(document.r());
|
let node = NodeCast::from_ref(document.r());
|
||||||
reply.send(node.summarize()).unwrap();
|
reply.send(node.summarize()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
|
pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) {
|
||||||
let page = get_page(&*page, pipeline);
|
let page = get_page(&*page, pipeline);
|
||||||
let document = page.document().root();
|
let document = page.document();
|
||||||
let document_element = document.r().GetDocumentElement().root().unwrap();
|
let document_element = document.r().GetDocumentElement().unwrap();
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(document_element.r());
|
let node = NodeCast::from_ref(document_element.r());
|
||||||
reply.send(node.summarize()).unwrap();
|
reply.send(node.summarize()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Temporary<Node> {
|
fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Root<Node> {
|
||||||
let page = get_page(&*page, pipeline);
|
let page = get_page(&*page, pipeline);
|
||||||
let document = page.document().root();
|
let document = page.document();
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(document.r());
|
let node = NodeCast::from_ref(document.r());
|
||||||
|
|
||||||
for candidate in node.traverse_preorder() {
|
for candidate in node.traverse_preorder() {
|
||||||
if candidate.root().r().get_unique_id() == node_id {
|
if candidate.r().get_unique_id() == node_id {
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,18 +82,17 @@ fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) {
|
pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) {
|
||||||
let parent = find_node_by_unique_id(&*page, pipeline, node_id).root();
|
let parent = find_node_by_unique_id(&*page, pipeline, node_id);
|
||||||
let children = parent.r().children().map(|child| {
|
let children = parent.r().children().map(|child| {
|
||||||
let child = child.root();
|
|
||||||
child.r().summarize()
|
child.r().summarize()
|
||||||
}).collect();
|
}).collect();
|
||||||
reply.send(children).unwrap();
|
reply.send(children).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) {
|
pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) {
|
||||||
let node = find_node_by_unique_id(&*page, pipeline, node_id).root();
|
let node = find_node_by_unique_id(&*page, pipeline, node_id);
|
||||||
let elem: JSRef<Element> = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
|
let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
|
||||||
let rect = elem.GetBoundingClientRect().root();
|
let rect = elem.GetBoundingClientRect();
|
||||||
let width = *rect.r().Width();
|
let width = *rect.r().Width();
|
||||||
let height = *rect.r().Height();
|
let height = *rect.r().Height();
|
||||||
reply.send((width, height)).unwrap();
|
reply.send((width, height)).unwrap();
|
||||||
|
@ -141,8 +142,8 @@ pub fn handle_modify_attribute(page: &Rc<Page>,
|
||||||
pipeline: PipelineId,
|
pipeline: PipelineId,
|
||||||
node_id: String,
|
node_id: String,
|
||||||
modifications: Vec<Modification>) {
|
modifications: Vec<Modification>) {
|
||||||
let node = find_node_by_unique_id(&*page, pipeline, node_id).root();
|
let node = find_node_by_unique_id(&*page, pipeline, node_id);
|
||||||
let elem: JSRef<Element> = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
|
let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element");
|
||||||
|
|
||||||
for modification in modifications.iter(){
|
for modification in modifications.iter(){
|
||||||
match modification.newValue {
|
match modification.newValue {
|
||||||
|
@ -156,7 +157,7 @@ pub fn handle_modify_attribute(page: &Rc<Page>,
|
||||||
|
|
||||||
pub fn handle_wants_live_notifications(page: &Rc<Page>, pipeline_id: PipelineId, send_notifications: bool) {
|
pub fn handle_wants_live_notifications(page: &Rc<Page>, pipeline_id: PipelineId, send_notifications: bool) {
|
||||||
let page = get_page(&*page, pipeline_id);
|
let page = get_page(&*page, pipeline_id);
|
||||||
let window = page.window().root();
|
let window = page.window();
|
||||||
window.r().set_devtools_wants_updates(send_notifications);
|
window.r().set_devtools_wants_updates(send_notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +168,7 @@ pub fn handle_set_timeline_markers(page: &Rc<Page>,
|
||||||
for marker_type in &marker_types {
|
for marker_type in &marker_types {
|
||||||
match *marker_type {
|
match *marker_type {
|
||||||
TimelineMarkerType::Reflow => {
|
TimelineMarkerType::Reflow => {
|
||||||
let window = page.window().root();
|
let window = page.window();
|
||||||
window.r().set_devtools_timeline_marker(TimelineMarkerType::Reflow, reply.clone());
|
window.r().set_devtools_timeline_marker(TimelineMarkerType::Reflow, reply.clone());
|
||||||
}
|
}
|
||||||
TimelineMarkerType::DOMEvent => {
|
TimelineMarkerType::DOMEvent => {
|
||||||
|
@ -180,7 +181,7 @@ pub fn handle_set_timeline_markers(page: &Rc<Page>,
|
||||||
pub fn handle_drop_timeline_markers(page: &Rc<Page>,
|
pub fn handle_drop_timeline_markers(page: &Rc<Page>,
|
||||||
script_task: &ScriptTask,
|
script_task: &ScriptTask,
|
||||||
marker_types: Vec<TimelineMarkerType>) {
|
marker_types: Vec<TimelineMarkerType>) {
|
||||||
let window = page.window().root();
|
let window = page.window();
|
||||||
for marker_type in &marker_types {
|
for marker_type in &marker_types {
|
||||||
match *marker_type {
|
match *marker_type {
|
||||||
TimelineMarkerType::Reflow => {
|
TimelineMarkerType::Reflow => {
|
||||||
|
@ -195,6 +196,6 @@ pub fn handle_drop_timeline_markers(page: &Rc<Page>,
|
||||||
|
|
||||||
pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, callback: Box<Fn(f64, )>) {
|
pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, callback: Box<Fn(f64, )>) {
|
||||||
let page = page.find(id).expect("There is no such page");
|
let page = page.find(id).expect("There is no such page");
|
||||||
let doc = page.document().root();
|
let doc = page.document();
|
||||||
doc.r().request_animation_frame(callback);
|
doc.r().request_animation_frame(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast};
|
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast};
|
||||||
use dom::bindings::js::{JSRef, Temporary, OptionalRootable, Rootable};
|
|
||||||
use dom::element::{Element, ActivationElementHelpers};
|
use dom::element::{Element, ActivationElementHelpers};
|
||||||
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
|
@ -15,7 +14,7 @@ use std::borrow::ToOwned;
|
||||||
|
|
||||||
/// Trait for elements with defined activation behavior
|
/// Trait for elements with defined activation behavior
|
||||||
pub trait Activatable {
|
pub trait Activatable {
|
||||||
fn as_element(&self) -> Temporary<Element>;
|
fn as_element<'a>(&'a self) -> &'a Element;
|
||||||
|
|
||||||
// Is this particular instance of the element activatable?
|
// Is this particular instance of the element activatable?
|
||||||
fn is_instance_activatable(&self) -> bool;
|
fn is_instance_activatable(&self) -> bool;
|
||||||
|
@ -27,32 +26,32 @@ pub trait Activatable {
|
||||||
fn canceled_activation(&self);
|
fn canceled_activation(&self);
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
||||||
fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>);
|
fn activation_behavior(&self, event: &Event, target: &EventTarget);
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
||||||
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool);
|
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool);
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-synthetic-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#run-synthetic-click-activation-steps
|
||||||
fn synthetic_click_activation(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
fn synthetic_click_activation(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
||||||
let element = self.as_element().root();
|
let element = self.as_element();
|
||||||
// Step 1
|
// Step 1
|
||||||
if element.r().click_in_progress() {
|
if element.click_in_progress() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Step 2
|
// Step 2
|
||||||
element.r().set_click_in_progress(true);
|
element.set_click_in_progress(true);
|
||||||
// Step 3
|
// Step 3
|
||||||
self.pre_click_activation();
|
self.pre_click_activation();
|
||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
// https://html.spec.whatwg.org/multipage/#fire-a-synthetic-mouse-event
|
// https://html.spec.whatwg.org/multipage/#fire-a-synthetic-mouse-event
|
||||||
let win = window_from_node(element.r()).root();
|
let win = window_from_node(element);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(element.r());
|
let target = EventTargetCast::from_ref(element);
|
||||||
let mouse = MouseEvent::new(win.r(), "click".to_owned(),
|
let mouse = MouseEvent::new(win.r(), "click".to_owned(),
|
||||||
EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, Some(win.r()), 1,
|
EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, Some(win.r()), 1,
|
||||||
0, 0, 0, 0, ctrlKey, shiftKey, altKey, metaKey,
|
0, 0, 0, 0, ctrlKey, shiftKey, altKey, metaKey,
|
||||||
0, None).root();
|
0, None);
|
||||||
let event: JSRef<Event> = EventCast::from_ref(mouse.r());
|
let event = EventCast::from_ref(mouse.r());
|
||||||
event.fire(target);
|
event.fire(target);
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
|
@ -64,6 +63,6 @@ pub trait Activatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6
|
// Step 6
|
||||||
element.r().set_click_in_progress(false);
|
element.set_click_in_progress(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,10 @@ use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods};
|
use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods};
|
||||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap};
|
||||||
use dom::bindings::js::{OptionalRootable, Rootable, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::element::{Element, AttributeHandlers};
|
use dom::element::{Element, AttributeHandlers};
|
||||||
use dom::node::Node;
|
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom::virtualmethods::vtable_for;
|
use dom::virtualmethods::vtable_for;
|
||||||
|
|
||||||
|
@ -125,7 +124,7 @@ pub struct Attr {
|
||||||
|
|
||||||
impl Attr {
|
impl Attr {
|
||||||
fn new_inherited(local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace,
|
fn new_inherited(local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace,
|
||||||
prefix: Option<Atom>, owner: Option<JSRef<Element>>) -> Attr {
|
prefix: Option<Atom>, owner: Option<&Element>) -> Attr {
|
||||||
Attr {
|
Attr {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
local_name: local_name,
|
local_name: local_name,
|
||||||
|
@ -133,13 +132,13 @@ impl Attr {
|
||||||
name: name,
|
name: name,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
owner: MutNullableHeap::new(owner.map(JS::from_rooted)),
|
owner: MutNullableHeap::new(owner.map(JS::from_ref)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(window: JSRef<Window>, local_name: Atom, value: AttrValue,
|
pub fn new(window: &Window, local_name: Atom, value: AttrValue,
|
||||||
name: Atom, namespace: Namespace,
|
name: Atom, namespace: Namespace,
|
||||||
prefix: Option<Atom>, owner: Option<JSRef<Element>>) -> Temporary<Attr> {
|
prefix: Option<Atom>, owner: Option<&Element>) -> Root<Attr> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
box Attr::new_inherited(local_name, value, name, namespace, prefix, owner),
|
box Attr::new_inherited(local_name, value, name, namespace, prefix, owner),
|
||||||
GlobalRef::Window(window),
|
GlobalRef::Window(window),
|
||||||
|
@ -162,7 +161,7 @@ impl Attr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AttrMethods for JSRef<'a, Attr> {
|
impl<'a> AttrMethods for &'a Attr {
|
||||||
// https://dom.spec.whatwg.org/#dom-attr-localname
|
// https://dom.spec.whatwg.org/#dom-attr-localname
|
||||||
fn LocalName(self) -> DOMString {
|
fn LocalName(self) -> DOMString {
|
||||||
(**self.local_name()).to_owned()
|
(**self.local_name()).to_owned()
|
||||||
|
@ -177,8 +176,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
|
||||||
fn SetValue(self, value: DOMString) {
|
fn SetValue(self, value: DOMString) {
|
||||||
match self.owner() {
|
match self.owner() {
|
||||||
None => *self.value.borrow_mut() = AttrValue::String(value),
|
None => *self.value.borrow_mut() = AttrValue::String(value),
|
||||||
Some(o) => {
|
Some(owner) => {
|
||||||
let owner = o.root();
|
|
||||||
let value = owner.r().parse_attribute(&self.namespace, self.local_name(), value);
|
let value = owner.r().parse_attribute(&self.namespace, self.local_name(), value);
|
||||||
self.set_value(AttrSettingType::ReplacedAttr, value, owner.r());
|
self.set_value(AttrSettingType::ReplacedAttr, value, owner.r());
|
||||||
}
|
}
|
||||||
|
@ -225,7 +223,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-attr-ownerelement
|
// https://dom.spec.whatwg.org/#dom-attr-ownerelement
|
||||||
fn GetOwnerElement(self) -> Option<Temporary<Element>> {
|
fn GetOwnerElement(self) -> Option<Root<Element>> {
|
||||||
self.owner()
|
self.owner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,19 +234,19 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AttrHelpers<'a> {
|
pub trait AttrHelpers<'a> {
|
||||||
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>);
|
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element);
|
||||||
fn value(self) -> Ref<'a, AttrValue>;
|
fn value(self) -> Ref<'a, AttrValue>;
|
||||||
fn local_name(self) -> &'a Atom;
|
fn local_name(self) -> &'a Atom;
|
||||||
fn set_owner(self, owner: Option<JSRef<Element>>);
|
fn set_owner(self, owner: Option<&Element>);
|
||||||
fn owner(self) -> Option<Temporary<Element>>;
|
fn owner(self) -> Option<Root<Element>>;
|
||||||
fn summarize(self) -> AttrInfo;
|
fn summarize(self) -> AttrInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> {
|
impl<'a> AttrHelpers<'a> for &'a Attr {
|
||||||
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>) {
|
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element) {
|
||||||
assert!(Some(owner) == self.owner().root().r());
|
assert!(Some(owner) == self.owner().r());
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(owner);
|
let node = NodeCast::from_ref(owner);
|
||||||
let namespace_is_null = self.namespace == ns!("");
|
let namespace_is_null = self.namespace == ns!("");
|
||||||
|
|
||||||
match set_type {
|
match set_type {
|
||||||
|
@ -265,21 +263,21 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(self) -> Ref<'a, AttrValue> {
|
fn value(self) -> Ref<'a, AttrValue> {
|
||||||
self.extended_deref().value.borrow()
|
self.value.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_name(self) -> &'a Atom {
|
fn local_name(self) -> &'a Atom {
|
||||||
&self.extended_deref().local_name
|
&self.local_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the owner element. Should be called after the attribute is added
|
/// Sets the owner element. Should be called after the attribute is added
|
||||||
/// or removed from its older parent.
|
/// or removed from its older parent.
|
||||||
fn set_owner(self, owner: Option<JSRef<Element>>) {
|
fn set_owner(self, owner: Option<&Element>) {
|
||||||
let ref ns = self.namespace;
|
let ref ns = self.namespace;
|
||||||
match (self.owner().root().r(), owner) {
|
match (self.owner().r(), owner) {
|
||||||
(None, Some(new)) => {
|
(None, Some(new)) => {
|
||||||
// Already in the list of attributes of new owner.
|
// Already in the list of attributes of new owner.
|
||||||
assert!(new.get_attribute(&ns, &self.local_name).root().r() == Some(self))
|
assert!(new.get_attribute(&ns, &self.local_name) == Some(Root::from_ref(self)))
|
||||||
}
|
}
|
||||||
(Some(old), None) => {
|
(Some(old), None) => {
|
||||||
// Already gone from the list of attributes of old owner.
|
// Already gone from the list of attributes of old owner.
|
||||||
|
@ -287,11 +285,11 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> {
|
||||||
}
|
}
|
||||||
(old, new) => assert!(old == new)
|
(old, new) => assert!(old == new)
|
||||||
}
|
}
|
||||||
self.owner.set(owner.map(JS::from_rooted))
|
self.owner.set(owner.map(JS::from_ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn owner(self) -> Option<Temporary<Element>> {
|
fn owner(self) -> Option<Root<Element>> {
|
||||||
self.owner.get().map(Temporary::from_rooted)
|
self.owner.get().map(Root::from_rooted)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn summarize(self) -> AttrInfo {
|
fn summarize(self) -> AttrInfo {
|
||||||
|
@ -311,7 +309,7 @@ pub trait AttrHelpersForLayout {
|
||||||
unsafe fn value_atom_forever(&self) -> Option<Atom>;
|
unsafe fn value_atom_forever(&self) -> Option<Atom>;
|
||||||
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]>;
|
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]>;
|
||||||
unsafe fn local_name_atom_forever(&self) -> Atom;
|
unsafe fn local_name_atom_forever(&self) -> Atom;
|
||||||
unsafe fn value(&self) -> &AttrValue;
|
unsafe fn value_for_layout(&self) -> &AttrValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
@ -354,7 +352,7 @@ impl AttrHelpersForLayout for Attr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn value(&self) -> &AttrValue {
|
unsafe fn value_for_layout(&self) -> &AttrValue {
|
||||||
self.value.borrow_for_layout()
|
self.value.borrow_for_layout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,22 @@
|
||||||
|
|
||||||
use dom::bindings::error::{Fallible, Error};
|
use dom::bindings::error::{Fallible, Error};
|
||||||
use dom::bindings::global::global_object_for_js_object;
|
use dom::bindings::global::global_object_for_js_object;
|
||||||
use dom::bindings::js::JSRef;
|
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::utils::Reflectable;
|
||||||
use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable, JS_GetGlobalObject};
|
use js::jsapi::{JSContext, JSObject, JS_WrapObject, IsCallable};
|
||||||
use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException};
|
use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException};
|
||||||
|
use js::jsapi::{RootedObject, RootedValue, MutableHandleObject, Heap};
|
||||||
|
use js::jsapi::{JSAutoCompartment};
|
||||||
|
use js::jsapi::{JS_BeginRequest, JS_EndRequest};
|
||||||
|
use js::jsapi::{JS_EnterCompartment, JS_LeaveCompartment, JSCompartment};
|
||||||
|
use js::jsapi::GetGlobalForObjectCrossCompartment;
|
||||||
|
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
|
||||||
use js::jsval::{JSVal, UndefinedValue};
|
use js::jsval::{JSVal, UndefinedValue};
|
||||||
use js::rust::with_compartment;
|
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::intrinsics::return_address;
|
||||||
|
use std::default::Default;
|
||||||
|
|
||||||
/// The exception handling used for a call.
|
/// The exception handling used for a call.
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
@ -26,7 +33,7 @@ pub enum ExceptionHandling {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A common base class for representing IDL callback function types.
|
/// A common base class for representing IDL callback function types.
|
||||||
#[derive(Copy, Clone,PartialEq)]
|
#[derive(PartialEq)]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
pub struct CallbackFunction {
|
pub struct CallbackFunction {
|
||||||
object: CallbackObject
|
object: CallbackObject
|
||||||
|
@ -34,17 +41,23 @@ pub struct CallbackFunction {
|
||||||
|
|
||||||
impl CallbackFunction {
|
impl CallbackFunction {
|
||||||
/// Create a new `CallbackFunction` for this object.
|
/// Create a new `CallbackFunction` for this object.
|
||||||
pub fn new(callback: *mut JSObject) -> CallbackFunction {
|
pub fn new() -> CallbackFunction {
|
||||||
CallbackFunction {
|
CallbackFunction {
|
||||||
object: CallbackObject {
|
object: CallbackObject {
|
||||||
callback: callback
|
callback: Heap::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize the callback function with a value.
|
||||||
|
/// Should be called once this object is done moving.
|
||||||
|
pub fn init(&mut self, callback: *mut JSObject) {
|
||||||
|
self.object.callback.set(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A common base class for representing IDL callback interface types.
|
/// A common base class for representing IDL callback interface types.
|
||||||
#[derive(Copy, Clone,PartialEq)]
|
#[derive(PartialEq)]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
pub struct CallbackInterface {
|
pub struct CallbackInterface {
|
||||||
object: CallbackObject
|
object: CallbackObject
|
||||||
|
@ -53,18 +66,23 @@ pub struct CallbackInterface {
|
||||||
/// A common base class for representing IDL callback function and
|
/// A common base class for representing IDL callback function and
|
||||||
/// callback interface types.
|
/// callback interface types.
|
||||||
#[allow(raw_pointer_derive)]
|
#[allow(raw_pointer_derive)]
|
||||||
#[derive(Copy, Clone,PartialEq)]
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct CallbackObject {
|
struct CallbackObject {
|
||||||
/// The underlying `JSObject`.
|
/// The underlying `JSObject`.
|
||||||
callback: *mut JSObject,
|
callback: Heap<*mut JSObject>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for CallbackObject {
|
||||||
|
fn eq(&self, other: &CallbackObject) -> bool {
|
||||||
|
self.callback.get() == other.callback.get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait to be implemented by concrete IDL callback function and
|
/// A trait to be implemented by concrete IDL callback function and
|
||||||
/// callback interface types.
|
/// callback interface types.
|
||||||
pub trait CallbackContainer {
|
pub trait CallbackContainer {
|
||||||
/// Create a new CallbackContainer object for the given `JSObject`.
|
/// Create a new CallbackContainer object for the given `JSObject`.
|
||||||
fn new(callback: *mut JSObject) -> Self;
|
fn new(callback: *mut JSObject) -> Rc<Self>;
|
||||||
/// Returns the underlying `JSObject`.
|
/// Returns the underlying `JSObject`.
|
||||||
fn callback(&self) -> *mut JSObject;
|
fn callback(&self) -> *mut JSObject;
|
||||||
}
|
}
|
||||||
|
@ -72,83 +90,103 @@ pub trait CallbackContainer {
|
||||||
impl CallbackInterface {
|
impl CallbackInterface {
|
||||||
/// Returns the underlying `JSObject`.
|
/// Returns the underlying `JSObject`.
|
||||||
pub fn callback(&self) -> *mut JSObject {
|
pub fn callback(&self) -> *mut JSObject {
|
||||||
self.object.callback
|
self.object.callback.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackFunction {
|
impl CallbackFunction {
|
||||||
/// Returns the underlying `JSObject`.
|
/// Returns the underlying `JSObject`.
|
||||||
pub fn callback(&self) -> *mut JSObject {
|
pub fn callback(&self) -> *mut JSObject {
|
||||||
self.object.callback
|
self.object.callback.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallbackInterface {
|
impl CallbackInterface {
|
||||||
/// Create a new CallbackInterface object for the given `JSObject`.
|
/// Create a new CallbackInterface object for the given `JSObject`.
|
||||||
pub fn new(callback: *mut JSObject) -> CallbackInterface {
|
pub fn new() -> CallbackInterface {
|
||||||
CallbackInterface {
|
CallbackInterface {
|
||||||
object: CallbackObject {
|
object: CallbackObject {
|
||||||
callback: callback
|
callback: Heap::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize the callback function with a value.
|
||||||
|
/// Should be called once this object is done moving.
|
||||||
|
pub fn init(&mut self, callback: *mut JSObject) {
|
||||||
|
self.object.callback.set(callback);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the property with the given `name`, if it is a callable object,
|
/// Returns the property with the given `name`, if it is a callable object,
|
||||||
/// or an error otherwise.
|
/// or an error otherwise.
|
||||||
pub fn get_callable_property(&self, cx: *mut JSContext, name: &str)
|
pub fn get_callable_property(&self, cx: *mut JSContext, name: &str)
|
||||||
-> Fallible<JSVal> {
|
-> Fallible<JSVal> {
|
||||||
let mut callable = UndefinedValue();
|
let mut callable = RootedValue::new(cx, UndefinedValue());
|
||||||
|
let obj = RootedObject::new(cx, self.callback());
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CString::new(name).unwrap();
|
let c_name = CString::new(name).unwrap();
|
||||||
if JS_GetProperty(cx, self.callback(), c_name.as_ptr(), &mut callable) == 0 {
|
if JS_GetProperty(cx, obj.handle(), c_name.as_ptr(),
|
||||||
|
callable.handle_mut()) == 0 {
|
||||||
return Err(Error::JSFailed);
|
return Err(Error::JSFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !callable.is_object() ||
|
if !callable.ptr.is_object() ||
|
||||||
JS_ObjectIsCallable(cx, callable.to_object()) == 0 {
|
IsCallable(callable.ptr.to_object()) == 0 {
|
||||||
return Err(Error::Type(
|
return Err(Error::Type(
|
||||||
format!("The value of the {} property is not callable", name)));
|
format!("The value of the {} property is not callable", name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(callable)
|
Ok(callable.ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the reflector for `p` into the compartment of `cx`.
|
/// Wraps the reflector for `p` into the compartment of `cx`.
|
||||||
pub fn wrap_call_this_object<T: Reflectable>(cx: *mut JSContext,
|
pub fn wrap_call_this_object<T: Reflectable>(cx: *mut JSContext,
|
||||||
p: JSRef<T>) -> *mut JSObject {
|
p: &T,
|
||||||
let mut obj = p.reflector().get_jsobject();
|
mut rval: MutableHandleObject) {
|
||||||
assert!(!obj.is_null());
|
rval.set(p.reflector().get_jsobject().get());
|
||||||
|
assert!(!rval.get().is_null());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if JS_WrapObject(cx, &mut obj) == 0 {
|
if JS_WrapObject(cx, rval) == 0 {
|
||||||
return ptr::null_mut();
|
rval.set(ptr::null_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class that performs whatever setup we need to safely make a call while
|
/// A class that performs whatever setup we need to safely make a call while
|
||||||
/// this class is on the stack. After `new` returns, the call is safe to make.
|
/// this class is on the stack. After `new` returns, the call is safe to make.
|
||||||
pub struct CallSetup {
|
pub struct CallSetup {
|
||||||
|
/// The compartment for reporting exceptions.
|
||||||
|
/// As a RootedObject, this must be the first field in order to
|
||||||
|
/// determine the final address on the stack correctly.
|
||||||
|
exception_compartment: RootedObject,
|
||||||
/// The `JSContext` used for the call.
|
/// The `JSContext` used for the call.
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
|
/// The compartment we were in before the call.
|
||||||
|
old_compartment: *mut JSCompartment,
|
||||||
/// The exception handling used for the call.
|
/// The exception handling used for the call.
|
||||||
_handling: ExceptionHandling,
|
handling: ExceptionHandling,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallSetup {
|
impl CallSetup {
|
||||||
/// Performs the setup needed to make a call.
|
/// Performs the setup needed to make a call.
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new<T: CallbackContainer>(callback: T, handling: ExceptionHandling) -> CallSetup {
|
pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup {
|
||||||
let global = global_object_for_js_object(callback.callback());
|
let global = global_object_for_js_object(callback.callback());
|
||||||
let global = global.root();
|
|
||||||
let cx = global.r().get_cx();
|
let cx = global.r().get_cx();
|
||||||
|
unsafe { JS_BeginRequest(cx); }
|
||||||
|
|
||||||
|
let exception_compartment = unsafe {
|
||||||
|
GetGlobalForObjectCrossCompartment(callback.callback())
|
||||||
|
};
|
||||||
CallSetup {
|
CallSetup {
|
||||||
|
exception_compartment:
|
||||||
|
RootedObject::new_with_addr(cx, exception_compartment,
|
||||||
|
unsafe { return_address() }),
|
||||||
cx: cx,
|
cx: cx,
|
||||||
_handling: handling,
|
old_compartment: unsafe { JS_EnterCompartment(cx, callback.callback()) },
|
||||||
|
handling: handling,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,14 +198,23 @@ impl CallSetup {
|
||||||
|
|
||||||
impl Drop for CallSetup {
|
impl Drop for CallSetup {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let need_to_deal_with_exception = unsafe { JS_IsExceptionPending(self.cx) } != 0;
|
unsafe { JS_LeaveCompartment(self.cx, self.old_compartment); }
|
||||||
|
let need_to_deal_with_exception =
|
||||||
|
self.handling == ExceptionHandling::Report &&
|
||||||
|
unsafe { JS_IsExceptionPending(self.cx) } != 0;
|
||||||
if need_to_deal_with_exception {
|
if need_to_deal_with_exception {
|
||||||
unsafe {
|
unsafe {
|
||||||
let old_global = JS_GetGlobalObject(self.cx);
|
let old_global = RootedObject::new(self.cx, self.exception_compartment.ptr);
|
||||||
with_compartment(self.cx, old_global, || {
|
let saved = JS_SaveFrameChain(self.cx) != 0;
|
||||||
JS_ReportPendingException(self.cx)
|
{
|
||||||
});
|
let _ac = JSAutoCompartment::new(self.cx, old_global.ptr);
|
||||||
|
JS_ReportPendingException(self.cx);
|
||||||
|
}
|
||||||
|
if saved {
|
||||||
|
JS_RestoreFrameChain(self.cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe { JS_EndRequest(self.cx); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,9 @@ impl<T> DOMRefCell<T> {
|
||||||
/// so you have to be careful in trace code!
|
/// so you have to be careful in trace code!
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
|
pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
|
||||||
debug_assert!(task_state::get().contains(SCRIPT | IN_GC));
|
// FIXME: IN_GC isn't reliable enough - doesn't catch minor GCs
|
||||||
|
// https://github.com/servo/servo/issues/6389
|
||||||
|
//debug_assert!(task_state::get().contains(SCRIPT | IN_GC));
|
||||||
&*self.value.as_unsafe_cell().get()
|
&*self.value.as_unsafe_cell().get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
DOMInterfaces = {
|
DOMInterfaces = {
|
||||||
|
|
||||||
'Window': {
|
'Window': {
|
||||||
'outerObjectHook': 'Some(bindings::utils::outerize_global as extern fn(*mut JSContext, JSHandleObject) -> *mut JSObject)',
|
'outerObjectHook': 'Some(bindings::utils::outerize_global)',
|
||||||
},
|
},
|
||||||
|
|
||||||
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
|
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -148,16 +148,16 @@ class Descriptor(DescriptorProvider):
|
||||||
if self.interface.isCallback():
|
if self.interface.isCallback():
|
||||||
self.needsRooting = False
|
self.needsRooting = False
|
||||||
ty = "%sBinding::%s" % (ifaceName, ifaceName)
|
ty = "%sBinding::%s" % (ifaceName, ifaceName)
|
||||||
self.returnType = ty
|
self.returnType = "Rc<%s>"% ty
|
||||||
self.argumentType = "???"
|
self.argumentType = "???"
|
||||||
self.memberType = "???"
|
self.memberType = "???"
|
||||||
self.nativeType = ty
|
self.nativeType = ty
|
||||||
else:
|
else:
|
||||||
self.needsRooting = True
|
self.needsRooting = True
|
||||||
self.returnType = "Temporary<%s>" % ifaceName
|
self.returnType = "Root<%s>" % ifaceName
|
||||||
self.argumentType = "JSRef<%s>" % ifaceName
|
self.argumentType = "&%s" % ifaceName
|
||||||
self.memberType = "Root<%s>" % ifaceName
|
self.memberType = "Root<%s>" % ifaceName
|
||||||
self.nativeType = "Unrooted<%s>" % ifaceName
|
self.nativeType = "Root<%s>" % ifaceName
|
||||||
|
|
||||||
self.concreteType = ifaceName
|
self.concreteType = ifaceName
|
||||||
self.register = desc.get('register', True)
|
self.register = desc.get('register', True)
|
||||||
|
|
|
@ -24,17 +24,17 @@
|
||||||
//! | USVString | `USVString` |
|
//! | USVString | `USVString` |
|
||||||
//! | ByteString | `ByteString` |
|
//! | ByteString | `ByteString` |
|
||||||
//! | object | `*mut JSObject` |
|
//! | object | `*mut JSObject` |
|
||||||
//! | interface types | `JSRef<T>` | `Temporary<T>` |
|
//! | interface types | `&T` | `Root<T>` |
|
||||||
//! | dictionary types | `&T` | *unsupported* |
|
//! | dictionary types | `&T` | *unsupported* |
|
||||||
//! | enumeration types | `T` |
|
//! | enumeration types | `T` |
|
||||||
//! | callback function types | `T` |
|
//! | callback function types | `Rc<T>` |
|
||||||
//! | nullable types | `Option<T>` |
|
//! | nullable types | `Option<T>` |
|
||||||
//! | sequences | `Vec<T>` |
|
//! | sequences | `Vec<T>` |
|
||||||
//! | union types | `T` |
|
//! | union types | `T` |
|
||||||
|
|
||||||
use dom::bindings::codegen::PrototypeList;
|
use dom::bindings::codegen::PrototypeList;
|
||||||
use dom::bindings::error::throw_type_error;
|
use dom::bindings::error::throw_type_error;
|
||||||
use dom::bindings::js::{JSRef, Root, Unrooted};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::str::{ByteString, USVString};
|
use dom::bindings::str::{ByteString, USVString};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector, DOMClass};
|
use dom::bindings::utils::{Reflectable, Reflector, DOMClass};
|
||||||
|
@ -43,14 +43,15 @@ use util::str::DOMString;
|
||||||
use js;
|
use js;
|
||||||
use js::glue::{RUST_JSID_TO_STRING, RUST_JSID_IS_STRING};
|
use js::glue::{RUST_JSID_TO_STRING, RUST_JSID_IS_STRING};
|
||||||
use js::glue::RUST_JS_NumberValue;
|
use js::glue::RUST_JS_NumberValue;
|
||||||
use js::jsapi::{JSBool, JSContext, JSObject, JSString, jsid};
|
use js::rust::{ToUint64, ToInt64};
|
||||||
use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64};
|
use js::rust::{ToUint32, ToInt32};
|
||||||
use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32};
|
use js::rust::{ToUint16, ToNumber, ToBoolean, ToString};
|
||||||
use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean};
|
use js::jsapi::{JSContext, JSObject, JSString};
|
||||||
use js::jsapi::{JS_ValueToString, JS_GetStringCharsAndLength};
|
use js::jsapi::{JS_StringHasLatin1Chars, JS_GetLatin1StringCharsAndLength, JS_GetTwoByteStringCharsAndLength};
|
||||||
use js::jsapi::{JS_NewUCStringCopyN, JS_NewStringCopyN};
|
use js::jsapi::{JS_NewUCStringCopyN, JS_NewStringCopyN};
|
||||||
use js::jsapi::{JS_WrapValue};
|
use js::jsapi::{JS_WrapValue};
|
||||||
use js::jsapi::{JSClass, JS_GetClass};
|
use js::jsapi::{JSClass, JS_GetClass};
|
||||||
|
use js::jsapi::{HandleId, HandleValue, HandleObject, MutableHandleValue};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::jsval::{UndefinedValue, NullValue, BooleanValue, Int32Value, UInt32Value};
|
use js::jsval::{UndefinedValue, NullValue, BooleanValue, Int32Value, UInt32Value};
|
||||||
use js::jsval::{StringValue, ObjectValue, ObjectOrNullValue};
|
use js::jsval::{StringValue, ObjectValue, ObjectOrNullValue};
|
||||||
|
@ -60,6 +61,9 @@ use num::Float;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::default;
|
use std::default;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use core::nonzero::NonZero;
|
||||||
|
|
||||||
/// A trait to retrieve the constants necessary to check if a `JSObject`
|
/// A trait to retrieve the constants necessary to check if a `JSObject`
|
||||||
/// implements a given interface.
|
/// implements a given interface.
|
||||||
|
@ -74,7 +78,7 @@ pub trait IDLInterface {
|
||||||
/// A trait to convert Rust types to `JSVal`s.
|
/// A trait to convert Rust types to `JSVal`s.
|
||||||
pub trait ToJSValConvertible {
|
pub trait ToJSValConvertible {
|
||||||
/// Convert `self` to a `JSVal`. JSAPI failure causes a task failure.
|
/// Convert `self` to a `JSVal`. JSAPI failure causes a task failure.
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal;
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait to convert `JSVal`s to Rust types.
|
/// A trait to convert `JSVal`s to Rust types.
|
||||||
|
@ -85,206 +89,201 @@ pub trait FromJSValConvertible {
|
||||||
/// Optional configuration of type `T` can be passed as the `option`
|
/// Optional configuration of type `T` can be passed as the `option`
|
||||||
/// argument.
|
/// argument.
|
||||||
/// If it returns `Err(())`, a JSAPI exception is pending.
|
/// If it returns `Err(())`, a JSAPI exception is pending.
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, option: Self::Config) -> Result<Self, ()>;
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, option: Self::Config) -> Result<Self, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ToJSValConvertible for () {
|
impl ToJSValConvertible for () {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
UndefinedValue()
|
rval.set(UndefinedValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for JSVal {
|
impl ToJSValConvertible for JSVal {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
let mut value = *self;
|
rval.set(*self);
|
||||||
if unsafe { JS_WrapValue(cx, &mut value) } == 0 {
|
if unsafe { JS_WrapValue(cx, rval) } == 0 {
|
||||||
panic!("JS_WrapValue failed.");
|
panic!("JS_WrapValue failed.");
|
||||||
}
|
}
|
||||||
value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn convert_from_jsval<T: default::Default>(
|
impl ToJSValConvertible for HandleValue {
|
||||||
cx: *mut JSContext, value: JSVal,
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
convert_fn: unsafe extern "C" fn(*mut JSContext, JSVal, *mut T) -> JSBool) -> Result<T, ()> {
|
rval.set(self.get());
|
||||||
let mut ret = default::Default::default();
|
if unsafe { JS_WrapValue(cx, rval) } == 0 {
|
||||||
if convert_fn(cx, value, &mut ret) == 0 {
|
panic!("JS_WrapValue failed.");
|
||||||
Err(())
|
}
|
||||||
} else {
|
|
||||||
Ok(ret)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ToJSValConvertible for bool {
|
impl ToJSValConvertible for bool {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
BooleanValue(*self)
|
rval.set(BooleanValue(*self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for bool {
|
impl FromJSValConvertible for bool {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<bool, ()> {
|
fn from_jsval(_cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<bool, ()> {
|
||||||
let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) };
|
Ok(ToBoolean(val))
|
||||||
result.map(|b| b != 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for i8 {
|
impl ToJSValConvertible for i8 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
Int32Value(*self as i32)
|
rval.set(Int32Value(*self as i32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for i8 {
|
impl FromJSValConvertible for i8 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i8, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i8, ()> {
|
||||||
let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
|
let result = ToInt32(cx, val);
|
||||||
result.map(|v| v as i8)
|
result.map(|v| v as i8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for u8 {
|
impl ToJSValConvertible for u8 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
Int32Value(*self as i32)
|
rval.set(Int32Value(*self as i32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for u8 {
|
impl FromJSValConvertible for u8 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u8, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u8, ()> {
|
||||||
let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
|
let result = ToInt32(cx, val);
|
||||||
result.map(|v| v as u8)
|
result.map(|v| v as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for i16 {
|
impl ToJSValConvertible for i16 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
Int32Value(*self as i32)
|
rval.set(Int32Value(*self as i32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for i16 {
|
impl FromJSValConvertible for i16 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i16, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i16, ()> {
|
||||||
let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) };
|
let result = ToInt32(cx, val);
|
||||||
result.map(|v| v as i16)
|
result.map(|v| v as i16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for u16 {
|
impl ToJSValConvertible for u16 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
Int32Value(*self as i32)
|
rval.set(Int32Value(*self as i32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for u16 {
|
impl FromJSValConvertible for u16 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u16, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u16, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) }
|
ToUint16(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for i32 {
|
impl ToJSValConvertible for i32 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
Int32Value(*self)
|
rval.set(Int32Value(*self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for i32 {
|
impl FromJSValConvertible for i32 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i32, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i32, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }
|
ToInt32(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for u32 {
|
impl ToJSValConvertible for u32 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
UInt32Value(*self)
|
rval.set(UInt32Value(*self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for u32 {
|
impl FromJSValConvertible for u32 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u32, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u32, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) }
|
ToUint32(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for i64 {
|
impl ToJSValConvertible for i64 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
RUST_JS_NumberValue(*self as f64)
|
rval.set(RUST_JS_NumberValue(*self as f64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for i64 {
|
impl FromJSValConvertible for i64 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i64, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i64, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) }
|
ToInt64(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for u64 {
|
impl ToJSValConvertible for u64 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
RUST_JS_NumberValue(*self as f64)
|
rval.set(RUST_JS_NumberValue(*self as f64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for u64 {
|
impl FromJSValConvertible for u64 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u64, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u64, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToUint64) }
|
ToUint64(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for f32 {
|
impl ToJSValConvertible for f32 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
RUST_JS_NumberValue(*self as f64)
|
rval.set(RUST_JS_NumberValue(*self as f64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for f32 {
|
impl FromJSValConvertible for f32 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<f32, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f32, ()> {
|
||||||
let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) };
|
let result = ToNumber(cx, val);
|
||||||
result.map(|f| f as f32)
|
result.map(|f| f as f32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for f64 {
|
impl ToJSValConvertible for f64 {
|
||||||
fn to_jsval(&self, _cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
RUST_JS_NumberValue(*self)
|
rval.set(RUST_JS_NumberValue(*self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for f64 {
|
impl FromJSValConvertible for f64 {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<f64, ()> {
|
fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f64, ()> {
|
||||||
unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }
|
ToNumber(cx, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Float + ToJSValConvertible> ToJSValConvertible for Finite<T> {
|
impl<T: Float + ToJSValConvertible> ToJSValConvertible for Finite<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
let value = **self;
|
let value = **self;
|
||||||
value.to_jsval(cx)
|
value.to_jsval(cx, rval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite<T> {
|
impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite<T> {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
fn from_jsval(cx: *mut JSContext, value: JSVal, option: ()) -> Result<Finite<T>, ()> {
|
fn from_jsval(cx: *mut JSContext, value: HandleValue, option: ()) -> Result<Finite<T>, ()> {
|
||||||
let result = try!(FromJSValConvertible::from_jsval(cx, value, option));
|
let result = try!(FromJSValConvertible::from_jsval(cx, value, option));
|
||||||
match Finite::new(result) {
|
match Finite::new(result) {
|
||||||
Some(v) => Ok(v),
|
Some(v) => Ok(v),
|
||||||
|
@ -297,21 +296,22 @@ impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for str {
|
impl ToJSValConvertible for str {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let string_utf16: Vec<u16> = self.utf16_units().collect();
|
let string_utf16: Vec<u16> = self.utf16_units().collect();
|
||||||
let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr(), string_utf16.len() as libc::size_t);
|
let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr() as *const i16,
|
||||||
|
string_utf16.len() as libc::size_t);
|
||||||
if jsstr.is_null() {
|
if jsstr.is_null() {
|
||||||
panic!("JS_NewUCStringCopyN failed");
|
panic!("JS_NewUCStringCopyN failed");
|
||||||
}
|
}
|
||||||
StringValue(&*jsstr)
|
rval.set(StringValue(&*jsstr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for DOMString {
|
impl ToJSValConvertible for DOMString {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
(**self).to_jsval(cx)
|
(**self).to_jsval(cx, rval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,18 +333,36 @@ impl default::Default for StringificationBehavior {
|
||||||
/// Convert the given `JSString` to a `DOMString`. Fails if the string does not
|
/// Convert the given `JSString` to a `DOMString`. Fails if the string does not
|
||||||
/// contain valid UTF-16.
|
/// contain valid UTF-16.
|
||||||
pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString {
|
pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString {
|
||||||
unsafe {
|
let mut length = 0;
|
||||||
let mut length = 0;
|
let latin1 = unsafe { JS_StringHasLatin1Chars(s) != 0 };
|
||||||
let chars = JS_GetStringCharsAndLength(cx, s, &mut length);
|
if latin1 {
|
||||||
|
let chars = unsafe {
|
||||||
|
JS_GetLatin1StringCharsAndLength(cx, ptr::null(), s, &mut length)
|
||||||
|
};
|
||||||
assert!(!chars.is_null());
|
assert!(!chars.is_null());
|
||||||
let char_vec = slice::from_raw_parts(chars, length as usize);
|
|
||||||
|
let mut buf = String::with_capacity(length as usize);
|
||||||
|
for i in 0..(length as isize) {
|
||||||
|
unsafe {
|
||||||
|
buf.push(*chars.offset(i) as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf
|
||||||
|
} else {
|
||||||
|
let chars = unsafe {
|
||||||
|
JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), s, &mut length)
|
||||||
|
};
|
||||||
|
assert!(!chars.is_null());
|
||||||
|
let char_vec = unsafe {
|
||||||
|
slice::from_raw_parts(chars as *const u16, length as usize)
|
||||||
|
};
|
||||||
String::from_utf16(char_vec).unwrap()
|
String::from_utf16(char_vec).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the given `jsid` to a `DOMString`. Fails if the `jsid` is not a
|
/// Convert the given `jsid` to a `DOMString`. Fails if the `jsid` is not a
|
||||||
/// string, or if the string does not contain valid UTF-16.
|
/// string, or if the string does not contain valid UTF-16.
|
||||||
pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString {
|
pub fn jsid_to_str(cx: *mut JSContext, id: HandleId) -> DOMString {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(RUST_JSID_IS_STRING(id) != 0);
|
assert!(RUST_JSID_IS_STRING(id) != 0);
|
||||||
jsstring_to_str(cx, RUST_JSID_TO_STRING(id))
|
jsstring_to_str(cx, RUST_JSID_TO_STRING(id))
|
||||||
|
@ -353,15 +371,16 @@ pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString {
|
||||||
|
|
||||||
impl FromJSValConvertible for DOMString {
|
impl FromJSValConvertible for DOMString {
|
||||||
type Config = StringificationBehavior;
|
type Config = StringificationBehavior;
|
||||||
fn from_jsval(cx: *mut JSContext, value: JSVal,
|
fn from_jsval(cx: *mut JSContext, value: HandleValue,
|
||||||
null_behavior: StringificationBehavior)
|
null_behavior: StringificationBehavior)
|
||||||
-> Result<DOMString, ()> {
|
-> Result<DOMString, ()> {
|
||||||
if null_behavior == StringificationBehavior::Empty && value.is_null() {
|
if null_behavior == StringificationBehavior::Empty &&
|
||||||
|
value.get().is_null() {
|
||||||
Ok("".to_owned())
|
Ok("".to_owned())
|
||||||
} else {
|
} else {
|
||||||
let jsstr = unsafe { JS_ValueToString(cx, value) };
|
let jsstr = ToString(cx, value);
|
||||||
if jsstr.is_null() {
|
if jsstr.is_null() {
|
||||||
debug!("JS_ValueToString failed");
|
debug!("ToString failed");
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
Ok(jsstring_to_str(cx, jsstr))
|
Ok(jsstring_to_str(cx, jsstr))
|
||||||
|
@ -371,56 +390,75 @@ impl FromJSValConvertible for DOMString {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for USVString {
|
impl ToJSValConvertible for USVString {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
self.0.to_jsval(cx)
|
self.0.to_jsval(cx, rval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for USVString {
|
impl FromJSValConvertible for USVString {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, value: JSVal, _: ())
|
fn from_jsval(cx: *mut JSContext, value: HandleValue, _: ())
|
||||||
-> Result<USVString, ()> {
|
-> Result<USVString, ()> {
|
||||||
let jsstr = unsafe { JS_ValueToString(cx, value) };
|
let jsstr = ToString(cx, value);
|
||||||
if jsstr.is_null() {
|
if jsstr.is_null() {
|
||||||
debug!("JS_ValueToString failed");
|
debug!("ToString failed");
|
||||||
Err(())
|
return Err(());
|
||||||
} else {
|
}
|
||||||
unsafe {
|
let latin1 = unsafe { JS_StringHasLatin1Chars(jsstr) != 0 };
|
||||||
let mut length = 0;
|
if latin1 {
|
||||||
let chars = JS_GetStringCharsAndLength(cx, jsstr, &mut length);
|
return Ok(USVString(jsstring_to_str(cx, jsstr)));
|
||||||
assert!(!chars.is_null());
|
}
|
||||||
let char_vec = slice::from_raw_parts(chars, length as usize);
|
unsafe {
|
||||||
Ok(USVString(String::from_utf16_lossy(char_vec)))
|
let mut length = 0;
|
||||||
}
|
let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), jsstr, &mut length);
|
||||||
|
assert!(!chars.is_null());
|
||||||
|
let char_vec = slice::from_raw_parts(chars as *const u16, length as usize);
|
||||||
|
Ok(USVString(String::from_utf16_lossy(char_vec)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for ByteString {
|
impl ToJSValConvertible for ByteString {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let jsstr = JS_NewStringCopyN(cx, self.as_ptr() as *const libc::c_char,
|
let jsstr = JS_NewStringCopyN(cx, self.as_ptr() as *const libc::c_char,
|
||||||
self.len() as libc::size_t);
|
self.len() as libc::size_t);
|
||||||
if jsstr.is_null() {
|
if jsstr.is_null() {
|
||||||
panic!("JS_NewStringCopyN failed");
|
panic!("JS_NewStringCopyN failed");
|
||||||
}
|
}
|
||||||
StringValue(&*jsstr)
|
rval.set(StringValue(&*jsstr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromJSValConvertible for ByteString {
|
impl FromJSValConvertible for ByteString {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, value: JSVal, _option: ()) -> Result<ByteString, ()> {
|
fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<ByteString, ()> {
|
||||||
unsafe {
|
let string = ToString(cx, value);
|
||||||
let string = JS_ValueToString(cx, value);
|
if string.is_null() {
|
||||||
if string.is_null() {
|
debug!("ToString failed");
|
||||||
debug!("JS_ValueToString failed");
|
return Err(());
|
||||||
return Err(());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
let latin1 = unsafe { JS_StringHasLatin1Chars(string) != 0 };
|
||||||
|
if latin1 {
|
||||||
let mut length = 0;
|
let mut length = 0;
|
||||||
let chars = JS_GetStringCharsAndLength(cx, string, &mut length);
|
let chars = unsafe {
|
||||||
|
JS_GetLatin1StringCharsAndLength(cx, ptr::null(),
|
||||||
|
string, &mut length)
|
||||||
|
};
|
||||||
|
assert!(!chars.is_null());
|
||||||
|
|
||||||
|
let char_vec = unsafe {
|
||||||
|
Vec::from_raw_buf(chars as *mut u8, length as usize)
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(ByteString::new(char_vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut length = 0;
|
||||||
|
let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), string, &mut length);
|
||||||
let char_vec = slice::from_raw_parts(chars, length as usize);
|
let char_vec = slice::from_raw_parts(chars, length as usize);
|
||||||
|
|
||||||
if char_vec.iter().any(|&c| c > 0xFF) {
|
if char_vec.iter().any(|&c| c > 0xFF) {
|
||||||
|
@ -434,14 +472,13 @@ impl FromJSValConvertible for ByteString {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for Reflector {
|
impl ToJSValConvertible for Reflector {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
let obj = self.get_jsobject();
|
let obj = self.get_jsobject().get();
|
||||||
assert!(!obj.is_null());
|
assert!(!obj.is_null());
|
||||||
let mut value = ObjectValue(unsafe { &*obj });
|
rval.set(ObjectValue(unsafe { &*obj }));
|
||||||
if unsafe { JS_WrapValue(cx, &mut value) } == 0 {
|
if unsafe { JS_WrapValue(cx, rval) } == 0 {
|
||||||
panic!("JS_WrapValue failed.");
|
panic!("JS_WrapValue failed.");
|
||||||
}
|
}
|
||||||
value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,11 +491,10 @@ pub fn is_dom_class(clasp: *const JSClass) -> bool {
|
||||||
|
|
||||||
/// Returns whether `obj` is a DOM object implemented as a proxy.
|
/// Returns whether `obj` is a DOM object implemented as a proxy.
|
||||||
pub fn is_dom_proxy(obj: *mut JSObject) -> bool {
|
pub fn is_dom_proxy(obj: *mut JSObject) -> bool {
|
||||||
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
use js::glue::IsProxyHandlerFamily;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(js_IsObjectProxyClass(obj) || js_IsFunctionProxyClass(obj)) &&
|
let clasp = JS_GetClass(obj);
|
||||||
IsProxyHandlerFamily(obj)
|
((*clasp).flags & js::JSCLASS_IS_PROXY) != 0 && IsProxyHandlerFamily(obj) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,29 +503,24 @@ pub fn is_dom_proxy(obj: *mut JSObject) -> bool {
|
||||||
// We use slot 0 for holding the raw object. This is safe for both
|
// We use slot 0 for holding the raw object. This is safe for both
|
||||||
// globals and non-globals.
|
// globals and non-globals.
|
||||||
pub const DOM_OBJECT_SLOT: u32 = 0;
|
pub const DOM_OBJECT_SLOT: u32 = 0;
|
||||||
const DOM_PROXY_OBJECT_SLOT: u32 = js::JSSLOT_PROXY_PRIVATE;
|
|
||||||
|
|
||||||
/// Returns the index of the slot wherein a pointer to the reflected DOM object
|
|
||||||
/// is stored.
|
|
||||||
///
|
|
||||||
/// Fails if `obj` is not a DOM object.
|
|
||||||
pub unsafe fn dom_object_slot(obj: *mut JSObject) -> u32 {
|
|
||||||
let clasp = JS_GetClass(obj);
|
|
||||||
if is_dom_class(&*clasp) {
|
|
||||||
DOM_OBJECT_SLOT
|
|
||||||
} else {
|
|
||||||
assert!(is_dom_proxy(obj));
|
|
||||||
DOM_PROXY_OBJECT_SLOT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the DOM object from the given reflector.
|
/// Get the DOM object from the given reflector.
|
||||||
pub unsafe fn native_from_reflector<T>(obj: *mut JSObject) -> *const T {
|
pub unsafe fn native_from_reflector<T>(obj: *mut JSObject) -> *const T {
|
||||||
use js::jsapi::JS_GetReservedSlot;
|
use js::jsapi::JS_GetReservedSlot;
|
||||||
|
use js::glue::GetProxyPrivate;
|
||||||
|
|
||||||
let slot = dom_object_slot(obj);
|
let clasp = JS_GetClass(obj);
|
||||||
let value = JS_GetReservedSlot(obj, slot);
|
let value = if is_dom_class(clasp) {
|
||||||
value.to_private() as *const T
|
JS_GetReservedSlot(obj, DOM_OBJECT_SLOT)
|
||||||
|
} else {
|
||||||
|
assert!(is_dom_proxy(obj));
|
||||||
|
GetProxyPrivate(obj)
|
||||||
|
};
|
||||||
|
if value.is_undefined() {
|
||||||
|
ptr::null()
|
||||||
|
} else {
|
||||||
|
value.to_private() as *const T
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object.
|
/// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object.
|
||||||
|
@ -518,17 +549,16 @@ unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> {
|
||||||
/// Returns Err(()) if `obj` is an opaque security wrapper or if the object is
|
/// Returns Err(()) if `obj` is an opaque security wrapper or if the object is
|
||||||
/// not a reflector for a DOM object of the given type (as defined by the
|
/// not a reflector for a DOM object of the given type (as defined by the
|
||||||
/// proto_id and proto_depth).
|
/// proto_id and proto_depth).
|
||||||
pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unrooted<T>, ()>
|
pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Root<T>, ()>
|
||||||
where T: Reflectable + IDLInterface
|
where T: Reflectable + IDLInterface
|
||||||
{
|
{
|
||||||
use js::glue::{IsWrapper, UnwrapObject};
|
use js::glue::{IsWrapper, UnwrapObject};
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let dom_class = try!(get_dom_class(obj).or_else(|_| {
|
let dom_class = try!(get_dom_class(obj).or_else(|_| {
|
||||||
if IsWrapper(obj) == 1 {
|
if IsWrapper(obj) == 1 {
|
||||||
debug!("found wrapper");
|
debug!("found wrapper");
|
||||||
obj = UnwrapObject(obj, /* stopAtOuter = */ 0, ptr::null_mut());
|
obj = UnwrapObject(obj, /* stopAtOuter = */ 0);
|
||||||
if obj.is_null() {
|
if obj.is_null() {
|
||||||
debug!("unwrapping security wrapper failed");
|
debug!("unwrapping security wrapper failed");
|
||||||
Err(())
|
Err(())
|
||||||
|
@ -547,7 +577,9 @@ pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unro
|
||||||
let proto_depth = <T as IDLInterface>::get_prototype_depth();
|
let proto_depth = <T as IDLInterface>::get_prototype_depth();
|
||||||
if dom_class.interface_chain[proto_depth] == proto_id {
|
if dom_class.interface_chain[proto_depth] == proto_id {
|
||||||
debug!("good prototype");
|
debug!("good prototype");
|
||||||
Ok(Unrooted::from_raw(native_from_reflector(obj)))
|
let native = native_from_reflector(obj);
|
||||||
|
assert!(!native.is_null());
|
||||||
|
Ok(Root::new(NonZero::new(native)))
|
||||||
} else {
|
} else {
|
||||||
debug!("bad prototype");
|
debug!("bad prototype");
|
||||||
Err(())
|
Err(())
|
||||||
|
@ -555,37 +587,54 @@ pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a Rooted<T> for a DOM object accessible from a HandleValue
|
||||||
|
pub fn native_from_handlevalue<T>(v: HandleValue) -> Result<Root<T>, ()>
|
||||||
|
where T: Reflectable + IDLInterface
|
||||||
|
{
|
||||||
|
native_from_reflector_jsmanaged(v.get().to_object())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a Rooted<T> for a DOM object accessible from a HandleObject
|
||||||
|
pub fn native_from_handleobject<T>(obj: HandleObject) -> Result<Root<T>, ()>
|
||||||
|
where T: Reflectable + IDLInterface
|
||||||
|
{
|
||||||
|
native_from_reflector_jsmanaged(obj.get())
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> ToJSValConvertible for Root<T> {
|
impl<T: Reflectable> ToJSValConvertible for Root<T> {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
self.r().reflector().to_jsval(cx)
|
self.r().reflector().to_jsval(cx, rval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Reflectable> ToJSValConvertible for JSRef<'a, T> {
|
impl<'a, T: Reflectable> ToJSValConvertible for &'a T {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
self.reflector().to_jsval(cx)
|
self.reflector().to_jsval(cx, rval);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Reflectable> ToJSValConvertible for Unrooted<T> {
|
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
|
||||||
self.reflector().to_jsval(cx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
|
impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
match self {
|
match self {
|
||||||
&Some(ref value) => value.to_jsval(cx),
|
&Some(ref value) => value.to_jsval(cx, rval),
|
||||||
&None => NullValue(),
|
&None => rval.set(NullValue()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ToJSValConvertible> ToJSValConvertible for Option<Rc<T>> {
|
||||||
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
|
match self {
|
||||||
|
&Some(ref value) => (**value).to_jsval(cx, rval),
|
||||||
|
&None => rval.set(NullValue()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<X: default::Default, T: FromJSValConvertible<Config=X>> FromJSValConvertible for Option<T> {
|
impl<X: default::Default, T: FromJSValConvertible<Config=X>> FromJSValConvertible for Option<T> {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
fn from_jsval(cx: *mut JSContext, value: JSVal, _: ()) -> Result<Option<T>, ()> {
|
fn from_jsval(cx: *mut JSContext, value: HandleValue, _: ()) -> Result<Option<T>, ()> {
|
||||||
if value.is_null_or_undefined() {
|
if value.get().is_null_or_undefined() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
let option: X = default::Default::default();
|
let option: X = default::Default::default();
|
||||||
|
@ -596,11 +645,10 @@ impl<X: default::Default, T: FromJSValConvertible<Config=X>> FromJSValConvertibl
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToJSValConvertible for *mut JSObject {
|
impl ToJSValConvertible for *mut JSObject {
|
||||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
|
||||||
let mut wrapped = ObjectOrNullValue(*self);
|
rval.set(ObjectOrNullValue(*self));
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(JS_WrapValue(cx, &mut wrapped) != 0);
|
assert!(JS_WrapValue(cx, rval) != 0);
|
||||||
}
|
}
|
||||||
wrapped
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,22 @@
|
||||||
|
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::Rootable;
|
|
||||||
use dom::domexception::{DOMException, DOMErrorName};
|
use dom::domexception::{DOMException, DOMErrorName};
|
||||||
|
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, JSObject, RootedValue};
|
||||||
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException, JS_ReportPendingException};
|
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException, JS_ReportPendingException};
|
||||||
use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR, JSEXN_RANGEERR};
|
use js::jsapi::{JS_ReportErrorNumber1, JSErrorFormatString, JSExnType};
|
||||||
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
|
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
|
||||||
use js::rust::with_compartment;
|
use js::jsapi::JSAutoCompartment;
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
use js::JSFalse;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
/// DOM exceptions that can be thrown by a native DOM method.
|
/// DOM exceptions that can be thrown by a native DOM method.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -116,10 +118,11 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||||
let exception = DOMException::new(global, code).root();
|
let exception = DOMException::new(global, code);
|
||||||
let thrown = exception.to_jsval(cx);
|
let mut thrown = RootedValue::new(cx, UndefinedValue());
|
||||||
|
exception.to_jsval(cx, thrown.handle_mut());
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_SetPendingException(cx, thrown);
|
JS_SetPendingException(cx, thrown.handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,9 +131,10 @@ pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if JS_IsExceptionPending(cx) != 0 {
|
if JS_IsExceptionPending(cx) != 0 {
|
||||||
let saved = JS_SaveFrameChain(cx);
|
let saved = JS_SaveFrameChain(cx);
|
||||||
with_compartment(cx, obj, || {
|
{
|
||||||
|
let _ac = JSAutoCompartment::new(cx, obj);
|
||||||
JS_ReportPendingException(cx);
|
JS_ReportPendingException(cx);
|
||||||
});
|
}
|
||||||
if saved != 0 {
|
if saved != 0 {
|
||||||
JS_RestoreFrameChain(cx);
|
JS_RestoreFrameChain(cx);
|
||||||
}
|
}
|
||||||
|
@ -158,25 +162,26 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [
|
||||||
static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
|
static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
|
||||||
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
|
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
|
||||||
argCount: 1,
|
argCount: 1,
|
||||||
exnType: JSEXN_TYPEERR as i16,
|
exnType: JSExnType::JSEXN_TYPEERR as i16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Format string struct used to throw `RangeError`s.
|
/// Format string struct used to throw `RangeError`s.
|
||||||
static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
|
static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
|
||||||
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
|
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
|
||||||
argCount: 1,
|
argCount: 1,
|
||||||
exnType: JSEXN_RANGEERR as i16,
|
exnType: JSExnType::JSEXN_RANGEERR as i16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Callback used to throw javascript errors.
|
/// Callback used to throw javascript errors.
|
||||||
/// See throw_js_error for info about error_number.
|
/// See throw_js_error for info about error_number.
|
||||||
unsafe extern fn get_error_message(_user_ref: *mut libc::c_void,
|
unsafe extern fn get_error_message(_user_ref: *mut libc::c_void,
|
||||||
_locale: *const libc::c_char,
|
error_number: libc::c_uint)
|
||||||
error_number: libc::c_uint) -> *const JSErrorFormatString
|
-> *const JSErrorFormatString
|
||||||
{
|
{
|
||||||
match error_number as i32 {
|
let num: JSExnType = mem::transmute(error_number);
|
||||||
JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
match num {
|
||||||
JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
||||||
|
JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
|
||||||
_ => panic!("Bad js error number given to get_error_message: {}", error_number)
|
_ => panic!("Bad js error number given to get_error_message: {}", error_number)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,20 +193,18 @@ unsafe extern fn get_error_message(_user_ref: *mut libc::c_void,
|
||||||
fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) {
|
fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) {
|
||||||
let error = CString::new(error).unwrap();
|
let error = CString::new(error).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_ReportErrorNumber(cx,
|
JS_ReportErrorNumber1(cx,
|
||||||
Some(get_error_message as
|
Some(get_error_message),
|
||||||
unsafe extern "C" fn(*mut libc::c_void, *const libc::c_char,
|
|
||||||
libc::c_uint) -> *const JSErrorFormatString),
|
|
||||||
ptr::null_mut(), error_number, error.as_ptr());
|
ptr::null_mut(), error_number, error.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throw a `TypeError` with the given message.
|
/// Throw a `TypeError` with the given message.
|
||||||
pub fn throw_type_error(cx: *mut JSContext, error: &str) {
|
pub fn throw_type_error(cx: *mut JSContext, error: &str) {
|
||||||
throw_js_error(cx, error, JSEXN_TYPEERR as u32);
|
throw_js_error(cx, error, JSExnType::JSEXN_TYPEERR as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Throw a `RangeError` with the given message.
|
/// Throw a `RangeError` with the given message.
|
||||||
pub fn throw_range_error(cx: *mut JSContext, error: &str) {
|
pub fn throw_range_error(cx: *mut JSContext, error: &str) {
|
||||||
throw_js_error(cx, error, JSEXN_RANGEERR as u32);
|
throw_js_error(cx, error, JSExnType::JSEXN_RANGEERR as u32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
||||||
use dom::bindings::js::{JS, JSRef, Rootable, Root, Unrooted};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::DocumentHelpers;
|
use dom::document::DocumentHelpers;
|
||||||
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
|
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
|
||||||
|
@ -21,7 +21,7 @@ use msg::constellation_msg::{PipelineId, WorkerId};
|
||||||
use net_traits::ResourceTask;
|
use net_traits::ResourceTask;
|
||||||
|
|
||||||
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
||||||
use js::glue::{GetGlobalForObjectCrossCompartment};
|
use js::jsapi::{GetGlobalForObjectCrossCompartment};
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, JSObject};
|
||||||
use js::jsapi::{JS_GetClass};
|
use js::jsapi::{JS_GetClass};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -30,9 +30,9 @@ use url::Url;
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum GlobalRef<'a> {
|
pub enum GlobalRef<'a> {
|
||||||
/// A reference to a `Window` object.
|
/// A reference to a `Window` object.
|
||||||
Window(JSRef<'a, window::Window>),
|
Window(&'a window::Window),
|
||||||
/// A reference to a `WorkerGlobalScope` object.
|
/// A reference to a `WorkerGlobalScope` object.
|
||||||
Worker(JSRef<'a, WorkerGlobalScope>),
|
Worker(&'a WorkerGlobalScope),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stack-based rooted reference to a global object.
|
/// A stack-based rooted reference to a global object.
|
||||||
|
@ -55,15 +55,6 @@ pub enum GlobalField {
|
||||||
Worker(JS<WorkerGlobalScope>),
|
Worker(JS<WorkerGlobalScope>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unrooted reference to a global object.
|
|
||||||
#[must_root]
|
|
||||||
pub enum GlobalUnrooted {
|
|
||||||
/// An unrooted reference to a `Window` object.
|
|
||||||
Window(Unrooted<window::Window>),
|
|
||||||
/// An unrooted reference to a `WorkerGlobalScope` object.
|
|
||||||
Worker(Unrooted<WorkerGlobalScope>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> GlobalRef<'a> {
|
impl<'a> GlobalRef<'a> {
|
||||||
/// Get the `JSContext` for the `JSRuntime` associated with the thread
|
/// Get the `JSContext` for the `JSRuntime` associated with the thread
|
||||||
/// this global object is on.
|
/// this global object is on.
|
||||||
|
@ -76,7 +67,7 @@ impl<'a> GlobalRef<'a> {
|
||||||
|
|
||||||
/// Extract a `Window`, causing task failure if the global object is not
|
/// Extract a `Window`, causing task failure if the global object is not
|
||||||
/// a `Window`.
|
/// a `Window`.
|
||||||
pub fn as_window<'b>(&'b self) -> JSRef<'b, window::Window> {
|
pub fn as_window<'b>(&'b self) -> &'b window::Window {
|
||||||
match *self {
|
match *self {
|
||||||
GlobalRef::Window(window) => window,
|
GlobalRef::Window(window) => window,
|
||||||
GlobalRef::Worker(_) => panic!("expected a Window scope"),
|
GlobalRef::Worker(_) => panic!("expected a Window scope"),
|
||||||
|
@ -104,7 +95,7 @@ impl<'a> GlobalRef<'a> {
|
||||||
pub fn resource_task(&self) -> ResourceTask {
|
pub fn resource_task(&self) -> ResourceTask {
|
||||||
match *self {
|
match *self {
|
||||||
GlobalRef::Window(ref window) => {
|
GlobalRef::Window(ref window) => {
|
||||||
let doc = window.Document().root();
|
let doc = window.Document();
|
||||||
let doc = doc.r();
|
let doc = doc.r();
|
||||||
let loader = doc.loader();
|
let loader = doc.loader();
|
||||||
loader.resource_task.clone()
|
loader.resource_task.clone()
|
||||||
|
@ -182,8 +173,8 @@ impl GlobalField {
|
||||||
/// Create a new `GlobalField` from a rooted reference.
|
/// Create a new `GlobalField` from a rooted reference.
|
||||||
pub fn from_rooted(global: &GlobalRef) -> GlobalField {
|
pub fn from_rooted(global: &GlobalRef) -> GlobalField {
|
||||||
match *global {
|
match *global {
|
||||||
GlobalRef::Window(window) => GlobalField::Window(JS::from_rooted(window)),
|
GlobalRef::Window(window) => GlobalField::Window(JS::from_ref(window)),
|
||||||
GlobalRef::Worker(worker) => GlobalField::Worker(JS::from_rooted(worker)),
|
GlobalRef::Worker(worker) => GlobalField::Worker(JS::from_ref(worker)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,30 +187,20 @@ impl GlobalField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalUnrooted {
|
|
||||||
/// Create a stack-bounded root for this reference.
|
|
||||||
pub fn root(&self) -> GlobalRoot {
|
|
||||||
match *self {
|
|
||||||
GlobalUnrooted::Window(ref window) => GlobalRoot::Window(window.root()),
|
|
||||||
GlobalUnrooted::Worker(ref worker) => GlobalRoot::Worker(worker.root()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the global object of the realm that the given JS object was created in.
|
/// Returns the global object of the realm that the given JS object was created in.
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalUnrooted {
|
pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalRoot {
|
||||||
unsafe {
|
unsafe {
|
||||||
let global = GetGlobalForObjectCrossCompartment(obj);
|
let global = GetGlobalForObjectCrossCompartment(obj);
|
||||||
let clasp = JS_GetClass(global);
|
let clasp = JS_GetClass(global);
|
||||||
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
|
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
|
||||||
match native_from_reflector_jsmanaged(global) {
|
match native_from_reflector_jsmanaged(global) {
|
||||||
Ok(window) => return GlobalUnrooted::Window(window),
|
Ok(window) => return GlobalRoot::Window(window),
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
match native_from_reflector_jsmanaged(global) {
|
match native_from_reflector_jsmanaged(global) {
|
||||||
Ok(worker) => return GlobalUnrooted::Worker(worker),
|
Ok(worker) => return GlobalRoot::Worker(worker),
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,178 +11,32 @@
|
||||||
//!
|
//!
|
||||||
//! Here is a brief overview of the important types:
|
//! Here is a brief overview of the important types:
|
||||||
//!
|
//!
|
||||||
//! - `JSRef<T>`: a freely-copyable reference to a rooted DOM object.
|
|
||||||
//! - `Root<T>`: a stack-based reference to a rooted DOM object.
|
//! - `Root<T>`: a stack-based reference to a rooted DOM object.
|
||||||
//! - `JS<T>`: a reference to a DOM object that can automatically be traced by
|
//! - `JS<T>`: a reference to a DOM object that can automatically be traced by
|
||||||
//! the GC when encountered as a field of a Rust structure.
|
//! the GC when encountered as a field of a Rust structure.
|
||||||
//! - `Temporary<T>`: a reference to a DOM object that will remain rooted for
|
|
||||||
//! the duration of its lifetime.
|
|
||||||
//!
|
//!
|
||||||
//! The rule of thumb is as follows:
|
//! `JS<T>` does not allow access to their inner value without explicitly
|
||||||
|
//! creating a stack-based root via the `root` method. This returns a `Root<T>`,
|
||||||
|
//! which causes the JS-owned value to be uncollectable for the duration of the
|
||||||
|
//! `Root` object's lifetime. A reference to the object can then be obtained
|
||||||
|
//! from the `Root` object. These references are not allowed to outlive their
|
||||||
|
//! originating `Root<T>`.
|
||||||
//!
|
//!
|
||||||
//! - All methods return `Temporary<T>`, to ensure the value remains alive
|
|
||||||
//! until it is stored somewhere that is reachable by the GC.
|
|
||||||
//! - All functions take `JSRef<T>` arguments, to ensure that they will remain
|
|
||||||
//! uncollected for the duration of their usage.
|
|
||||||
//! - All DOM structs contain `JS<T>` fields and derive the `JSTraceable`
|
|
||||||
//! trait, to ensure that they are transitively marked as reachable by the GC
|
|
||||||
//! if the enclosing value is reachable.
|
|
||||||
//! - All methods for type `T` are implemented for `JSRef<T>`, to ensure that
|
|
||||||
//! the self value will not be collected for the duration of the method call.
|
|
||||||
//!
|
|
||||||
//! Both `Temporary<T>` and `JS<T>` do not allow access to their inner value
|
|
||||||
//! without explicitly creating a stack-based root via the `root` method
|
|
||||||
//! through the `Rootable<T>` trait. This returns a `Root<T>`, which causes the
|
|
||||||
//! JS-owned value to be uncollectable for the duration of the `Root` object's
|
|
||||||
//! lifetime. A `JSRef<T>` can be obtained from a `Root<T>` by calling the `r`
|
|
||||||
//! method. These `JSRef<T>` values are not allowed to outlive their
|
|
||||||
//! originating `Root<T>`, to ensure that all interactions with the enclosed
|
|
||||||
//! value only occur when said value is uncollectable, and will cause static
|
|
||||||
//! lifetime errors if misused.
|
|
||||||
//!
|
|
||||||
//! Other miscellaneous helper traits:
|
|
||||||
//!
|
|
||||||
//! - `OptionalRootable` and `OptionalOptionalRootable`: make rooting `Option`
|
|
||||||
//! values easy via a `root` method
|
|
||||||
//! - `ResultRootable`: make rooting successful `Result` values easy
|
|
||||||
//! - `TemporaryPushable`: allows mutating vectors of `JS<T>` with new elements
|
|
||||||
//! of `JSRef`/`Temporary`
|
|
||||||
//! - `RootedReference`: makes obtaining an `Option<JSRef<T>>` from an
|
|
||||||
//! `Option<Root<T>>` easy
|
|
||||||
|
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::trace::RootedVec;
|
use dom::bindings::trace::trace_reflector;
|
||||||
use dom::bindings::utils::{Reflector, Reflectable};
|
use dom::bindings::utils::{Reflector, Reflectable};
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use js::jsapi::JSObject;
|
use js::jsapi::{JSObject, Heap, JSTracer};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::{JSVal, UndefinedValue};
|
||||||
use layout_interface::TrustedNodeAddress;
|
use layout_interface::TrustedNodeAddress;
|
||||||
use script_task::STACK_ROOTS;
|
use script_task::STACK_ROOTS;
|
||||||
|
|
||||||
use core::nonzero::NonZero;
|
use core::nonzero::NonZero;
|
||||||
use libc;
|
|
||||||
use std::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::intrinsics::return_address;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
/// An unrooted, JS-owned value. Must not be held across a GC.
|
|
||||||
///
|
|
||||||
/// This is used in particular to wrap pointers extracted from a reflector.
|
|
||||||
#[must_root]
|
|
||||||
pub struct Unrooted<T> {
|
|
||||||
ptr: NonZero<*const T>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> Unrooted<T> {
|
|
||||||
/// Create a new JS-owned value wrapped from a raw Rust pointer.
|
|
||||||
pub unsafe fn from_raw(raw: *const T) -> Unrooted<T> {
|
|
||||||
assert!(!raw.is_null());
|
|
||||||
Unrooted {
|
|
||||||
ptr: NonZero::new(raw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new unrooted value from a `JS<T>`.
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
pub fn from_js(ptr: JS<T>) -> Unrooted<T> {
|
|
||||||
Unrooted {
|
|
||||||
ptr: ptr.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new unrooted value from a `Temporary<T>`.
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
pub fn from_temporary(ptr: Temporary<T>) -> Unrooted<T> {
|
|
||||||
Unrooted::from_js(ptr.inner)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the `Reflector` for this pointer.
|
|
||||||
pub fn reflector<'a>(&'a self) -> &'a Reflector {
|
|
||||||
unsafe {
|
|
||||||
(**self.ptr).reflector()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an unsafe pointer to the interior of this object.
|
|
||||||
pub unsafe fn unsafe_get(&self) -> *const T {
|
|
||||||
*self.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> Rootable<T> for Unrooted<T> {
|
|
||||||
/// Create a stack-bounded root for this value.
|
|
||||||
fn root(&self) -> Root<T> {
|
|
||||||
STACK_ROOTS.with(|ref collection| {
|
|
||||||
let RootCollectionPtr(collection) = collection.get().unwrap();
|
|
||||||
unsafe {
|
|
||||||
Root::new(&*collection, self.ptr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Copy for Unrooted<T> {}
|
|
||||||
impl<T> Clone for Unrooted<T> {
|
|
||||||
fn clone(&self) -> Unrooted<T> { *self }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A type that represents a JS-owned value that is rooted for the lifetime of
|
|
||||||
/// this value. Importantly, it requires explicit rooting in order to interact
|
|
||||||
/// with the inner value. Can be assigned into JS-owned member fields (i.e.
|
|
||||||
/// `JS<T>` types) safely via the `JS<T>::assign` method or
|
|
||||||
/// `OptionalSettable::assign` (for `Option<JS<T>>` fields).
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
pub struct Temporary<T> {
|
|
||||||
inner: JS<T>,
|
|
||||||
/// On-stack JS pointer to assuage conservative stack scanner
|
|
||||||
_js_ptr: *mut JSObject,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Clone for Temporary<T> {
|
|
||||||
fn clone(&self) -> Temporary<T> {
|
|
||||||
Temporary {
|
|
||||||
inner: self.inner,
|
|
||||||
_js_ptr: self._js_ptr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PartialEq for Temporary<T> {
|
|
||||||
fn eq(&self, other: &Temporary<T>) -> bool {
|
|
||||||
self.inner == other.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> Temporary<T> {
|
|
||||||
/// Create a new `Temporary` value from an unrooted value.
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
pub fn from_unrooted(unrooted: Unrooted<T>) -> Temporary<T> {
|
|
||||||
Temporary {
|
|
||||||
inner: JS { ptr: unrooted.ptr },
|
|
||||||
_js_ptr: unrooted.reflector().get_jsobject(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new `Temporary` value from a rooted value.
|
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
pub fn from_rooted<U: Assignable<T>>(root: U) -> Temporary<T> {
|
|
||||||
let inner = JS::from_rooted(root);
|
|
||||||
Temporary {
|
|
||||||
inner: inner,
|
|
||||||
_js_ptr: inner.reflector().get_jsobject(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> Rootable<T> for Temporary<T> {
|
|
||||||
/// Create a stack-bounded root for this value.
|
|
||||||
fn root(&self) -> Root<T> {
|
|
||||||
self.inner.root()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A traced reference to a DOM object. Must only be used as a field in other
|
/// A traced reference to a DOM object. Must only be used as a field in other
|
||||||
/// DOM objects.
|
/// DOM objects.
|
||||||
#[must_root]
|
#[must_root]
|
||||||
|
@ -198,6 +52,32 @@ impl<T> JS<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<T: Reflectable> JS<T> {
|
||||||
|
/// Root this JS-owned value to prevent its collection as garbage.
|
||||||
|
pub fn root(&self) -> Root<T> {
|
||||||
|
Root::new(self.ptr)
|
||||||
|
}
|
||||||
|
/// Create a JS<T> from a Root<T>
|
||||||
|
/// XXX Not a great API. Should be a call on Root<T> instead
|
||||||
|
pub fn from_rooted(root: &Root<T>) -> JS<T> {
|
||||||
|
JS {
|
||||||
|
ptr: unsafe { NonZero::new(&**root) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Create a JS<T> from a &T
|
||||||
|
pub fn from_ref(obj: &T) -> JS<T> {
|
||||||
|
JS {
|
||||||
|
ptr: unsafe { NonZero::new(&*obj) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Store an rooted value in this field. This is safe under the
|
||||||
|
/// assumption that JS<T> values are only used as fields in DOM types that
|
||||||
|
/// are reachable in the GC graph, so this unrooted value becomes
|
||||||
|
/// transitively rooted for the lifetime of its new owner.
|
||||||
|
pub fn assign(&mut self, val: Root<T>) {
|
||||||
|
self.ptr = val.ptr.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An unrooted reference to a DOM object for use in layout. `Layout*Helpers`
|
/// An unrooted reference to a DOM object for use in layout. `Layout*Helpers`
|
||||||
/// traits must be implemented on this.
|
/// traits must be implemented on this.
|
||||||
|
@ -208,7 +88,7 @@ pub struct LayoutJS<T> {
|
||||||
impl<T: Reflectable> LayoutJS<T> {
|
impl<T: Reflectable> LayoutJS<T> {
|
||||||
/// Get the reflector.
|
/// Get the reflector.
|
||||||
pub unsafe fn get_jsobject(&self) -> *mut JSObject {
|
pub unsafe fn get_jsobject(&self) -> *mut JSObject {
|
||||||
(**self.ptr).reflector().get_jsobject()
|
(**self.ptr).reflector().get_jsobject().get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,14 +97,12 @@ impl<T> Copy for JS<T> {}
|
||||||
impl<T> Copy for LayoutJS<T> {}
|
impl<T> Copy for LayoutJS<T> {}
|
||||||
|
|
||||||
impl<T> PartialEq for JS<T> {
|
impl<T> PartialEq for JS<T> {
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
fn eq(&self, other: &JS<T>) -> bool {
|
fn eq(&self, other: &JS<T>) -> bool {
|
||||||
self.ptr == other.ptr
|
self.ptr == other.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PartialEq for LayoutJS<T> {
|
impl<T> PartialEq for LayoutJS<T> {
|
||||||
#[allow(unrooted_must_root)]
|
|
||||||
fn eq(&self, other: &LayoutJS<T>) -> bool {
|
fn eq(&self, other: &LayoutJS<T>) -> bool {
|
||||||
self.ptr == other.ptr
|
self.ptr == other.ptr
|
||||||
}
|
}
|
||||||
|
@ -260,29 +138,6 @@ impl LayoutJS<Node> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> Rootable<T> for JS<T> {
|
|
||||||
/// Root this JS-owned value to prevent its collection as garbage.
|
|
||||||
fn root(&self) -> Root<T> {
|
|
||||||
STACK_ROOTS.with(|ref collection| {
|
|
||||||
let RootCollectionPtr(collection) = collection.get().unwrap();
|
|
||||||
unsafe {
|
|
||||||
Root::new(&*collection, self.ptr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<U: Reflectable> JS<U> {
|
|
||||||
/// Create a `JS<T>` from any JS-managed pointer.
|
|
||||||
pub fn from_rooted<T: Assignable<U>>(root: T) -> JS<U> {
|
|
||||||
unsafe {
|
|
||||||
root.get_js()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//XXXjdm This is disappointing. This only gets called from trace hooks, in theory,
|
|
||||||
// so it's safe to assume that self is rooted and thereby safe to access.
|
|
||||||
impl<T: Reflectable> Reflectable for JS<T> {
|
impl<T: Reflectable> Reflectable for JS<T> {
|
||||||
fn reflector<'a>(&'a self) -> &'a Reflector {
|
fn reflector<'a>(&'a self) -> &'a Reflector {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -298,19 +153,50 @@ impl<T: Reflectable> Reflectable for JS<T> {
|
||||||
pub trait HeapGCValue: JSTraceable {
|
pub trait HeapGCValue: JSTraceable {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HeapGCValue for JSVal {
|
impl HeapGCValue for Heap<JSVal> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> HeapGCValue for JS<T> {
|
impl<T: Reflectable> HeapGCValue for JS<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A holder that provides interior mutability for GC-managed values such as
|
/// A holder that provides interior mutability for GC-managed JSVals.
|
||||||
/// `JSVal` and `JS<T>`.
|
|
||||||
///
|
///
|
||||||
/// Must be used in place of traditional interior mutability to ensure proper
|
/// Must be used in place of traditional interior mutability to ensure proper
|
||||||
/// GC barriers are enforced.
|
/// GC barriers are enforced.
|
||||||
#[must_root]
|
#[must_root]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
|
pub struct MutHeapJSVal {
|
||||||
|
val: UnsafeCell<Heap<JSVal>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MutHeapJSVal {
|
||||||
|
/// Create a new `MutHeapJSVal`.
|
||||||
|
pub fn new() -> MutHeapJSVal {
|
||||||
|
MutHeapJSVal {
|
||||||
|
val: UnsafeCell::new(Heap::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set this `MutHeapJSVal` to the given value, calling write barriers as
|
||||||
|
/// appropriate.
|
||||||
|
pub fn set(&self, val: JSVal) {
|
||||||
|
unsafe {
|
||||||
|
let cell = self.val.get();
|
||||||
|
(*cell).set(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the value in this `MutHeapJSVal`, calling read barriers as appropriate.
|
||||||
|
pub fn get(&self) -> JSVal {
|
||||||
|
unsafe { (*self.val.get()).get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// A holder that provides interior mutability for GC-managed values such as
|
||||||
|
/// `JS<T>`.
|
||||||
|
#[must_root]
|
||||||
|
#[jstraceable]
|
||||||
pub struct MutHeap<T: HeapGCValue+Copy> {
|
pub struct MutHeap<T: HeapGCValue+Copy> {
|
||||||
val: Cell<T>,
|
val: Cell<T>,
|
||||||
}
|
}
|
||||||
|
@ -323,13 +209,12 @@ impl<T: HeapGCValue+Copy> MutHeap<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set this `MutHeap` to the given value, calling write barriers as
|
/// Set this `MutHeap` to the given value.
|
||||||
/// appropriate.
|
|
||||||
pub fn set(&self, val: T) {
|
pub fn set(&self, val: T) {
|
||||||
self.val.set(val)
|
self.val.set(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the value in this `MutHeap`, calling read barriers as appropriate.
|
/// Set the value in this `MutHeap`.
|
||||||
pub fn get(&self) -> T {
|
pub fn get(&self) -> T {
|
||||||
self.val.get()
|
self.val.get()
|
||||||
}
|
}
|
||||||
|
@ -353,8 +238,7 @@ impl<T: HeapGCValue+Copy> MutNullableHeap<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set this `MutNullableHeap` to the given value, calling write barriers
|
/// Set this `MutNullableHeap` to the given value.
|
||||||
/// as appropriate.
|
|
||||||
pub fn set(&self, val: Option<T>) {
|
pub fn set(&self, val: Option<T>) {
|
||||||
self.ptr.set(val);
|
self.ptr.set(val);
|
||||||
}
|
}
|
||||||
|
@ -368,14 +252,14 @@ impl<T: HeapGCValue+Copy> MutNullableHeap<T> {
|
||||||
impl<T: Reflectable> MutNullableHeap<JS<T>> {
|
impl<T: Reflectable> MutNullableHeap<JS<T>> {
|
||||||
/// Retrieve a copy of the current inner value. If it is `None`, it is
|
/// Retrieve a copy of the current inner value. If it is `None`, it is
|
||||||
/// initialized with the result of `cb` first.
|
/// initialized with the result of `cb` first.
|
||||||
pub fn or_init<F>(&self, cb: F) -> Temporary<T>
|
pub fn or_init<F>(&self, cb: F) -> Root<T>
|
||||||
where F: FnOnce() -> Temporary<T>
|
where F: FnOnce() -> Root<T>
|
||||||
{
|
{
|
||||||
match self.get() {
|
match self.get() {
|
||||||
Some(inner) => Temporary::from_rooted(inner),
|
Some(inner) => Root::from_rooted(inner),
|
||||||
None => {
|
None => {
|
||||||
let inner = cb();
|
let inner = cb();
|
||||||
self.set(Some(JS::from_rooted(inner.clone())));
|
self.set(Some(JS::from_rooted(&inner)));
|
||||||
inner
|
inner
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -396,16 +280,6 @@ impl<T: HeapGCValue+Copy> Default for MutNullableHeap<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> JS<T> {
|
|
||||||
/// Store an unrooted value in this field. This is safe under the
|
|
||||||
/// assumption that JS<T> values are only used as fields in DOM types that
|
|
||||||
/// are reachable in the GC graph, so this unrooted value becomes
|
|
||||||
/// transitively rooted for the lifetime of its new owner.
|
|
||||||
pub fn assign(&mut self, val: Temporary<T>) {
|
|
||||||
*self = val.inner.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> LayoutJS<T> {
|
impl<T: Reflectable> LayoutJS<T> {
|
||||||
/// Returns an unsafe pointer to the interior of this JS object. This is
|
/// Returns an unsafe pointer to the interior of this JS object. This is
|
||||||
/// the only method that be safely accessed from layout. (The fact that
|
/// the only method that be safely accessed from layout. (The fact that
|
||||||
|
@ -419,129 +293,36 @@ impl<T: Reflectable> LayoutJS<T> {
|
||||||
pub trait RootedReference<T> {
|
pub trait RootedReference<T> {
|
||||||
/// Obtain a safe optional reference to the wrapped JS owned-value that
|
/// Obtain a safe optional reference to the wrapped JS owned-value that
|
||||||
/// cannot outlive the lifetime of this root.
|
/// cannot outlive the lifetime of this root.
|
||||||
fn r<'a>(&'a self) -> Option<JSRef<'a, T>>;
|
fn r<'a>(&'a self) -> Option<&'a T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> RootedReference<T> for Option<Root<T>> {
|
impl<T: Reflectable> RootedReference<T> for Option<Root<T>> {
|
||||||
fn r<'a>(&'a self) -> Option<JSRef<'a, T>> {
|
fn r<'a>(&'a self) -> Option<&'a T> {
|
||||||
self.as_ref().map(|root| root.r())
|
self.as_ref().map(|root| root.r())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an `Option<Option<JSRef<T>>>` out of an `Option<Option<Root<T>>>`
|
/// Get an `Option<Option<&T>>` out of an `Option<Option<Root<T>>>`
|
||||||
pub trait OptionalRootedReference<T> {
|
pub trait OptionalRootedReference<T> {
|
||||||
/// Obtain a safe optional optional reference to the wrapped JS owned-value
|
/// Obtain a safe optional optional reference to the wrapped JS owned-value
|
||||||
/// that cannot outlive the lifetime of this root.
|
/// that cannot outlive the lifetime of this root.
|
||||||
fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>;
|
fn r<'a>(&'a self) -> Option<Option<&'a T>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<T>>> {
|
impl<T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<T>>> {
|
||||||
fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>> {
|
fn r<'a>(&'a self) -> Option<Option<&'a T>> {
|
||||||
self.as_ref().map(|inner| inner.r())
|
self.as_ref().map(|inner| inner.r())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait that allows extracting a `JS<T>` value from a variety of
|
/// A rooting mechanism for reflectors on the stack.
|
||||||
/// rooting-related containers, which in general is an unsafe operation since
|
/// LIFO is not required.
|
||||||
/// they can outlive the rooted lifetime of the original value.
|
|
||||||
pub trait Assignable<T> {
|
|
||||||
/// Extract an unrooted `JS<T>`.
|
|
||||||
unsafe fn get_js(&self) -> JS<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Assignable<T> for JS<T> {
|
|
||||||
unsafe fn get_js(&self) -> JS<T> {
|
|
||||||
self.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Reflectable> Assignable<T> for JSRef<'a, T> {
|
|
||||||
unsafe fn get_js(&self) -> JS<T> {
|
|
||||||
JS {
|
|
||||||
ptr: self.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable> Assignable<T> for Temporary<T> {
|
|
||||||
unsafe fn get_js(&self) -> JS<T> {
|
|
||||||
self.inner.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Root a rootable `Option` type (used for `Option<Temporary<T>>`)
|
|
||||||
pub trait OptionalRootable<T> {
|
|
||||||
/// Root the inner value, if it exists.
|
|
||||||
fn root(&self) -> Option<Root<T>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable, U: Rootable<T>> OptionalRootable<T> for Option<U> {
|
|
||||||
fn root(&self) -> Option<Root<T>> {
|
|
||||||
self.as_ref().map(|inner| inner.root())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Root a rootable `Option<Option>` type (used for `Option<Option<JS<T>>>`)
|
|
||||||
pub trait OptionalOptionalRootable<T> {
|
|
||||||
/// Root the inner value, if it exists.
|
|
||||||
fn root(&self) -> Option<Option<Root<T>>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable, U: OptionalRootable<T>> OptionalOptionalRootable<T> for Option<U> {
|
|
||||||
fn root(&self) -> Option<Option<Root<T>>> {
|
|
||||||
self.as_ref().map(|inner| inner.root())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Root a rootable `Result` type (any of `Temporary<T>` or `JS<T>`)
|
|
||||||
pub trait ResultRootable<T,U> {
|
|
||||||
/// Root the inner value, if it exists.
|
|
||||||
fn root(self) -> Result<Root<T>, U>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Reflectable, U, V: Rootable<T>> ResultRootable<T, U> for Result<V, U> {
|
|
||||||
fn root(self) -> Result<Root<T>, U> {
|
|
||||||
self.map(|inner| inner.root())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Root a rootable type.
|
|
||||||
pub trait Rootable<T> {
|
|
||||||
/// Root the value.
|
|
||||||
fn root(&self) -> Root<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Provides a facility to push unrooted values onto lists of rooted values.
|
|
||||||
/// This is safe under the assumption that said lists are reachable via the GC
|
|
||||||
/// graph, and therefore the new values are transitively rooted for the
|
|
||||||
/// lifetime of their new owner.
|
|
||||||
pub trait TemporaryPushable<T> {
|
|
||||||
/// Push a new value onto this container.
|
|
||||||
fn push_unrooted(&mut self, val: &T);
|
|
||||||
/// Insert a new value into this container.
|
|
||||||
fn insert_unrooted(&mut self, index: usize, val: &T);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Assignable<U>, U: Reflectable> TemporaryPushable<T> for Vec<JS<U>> {
|
|
||||||
fn push_unrooted(&mut self, val: &T) {
|
|
||||||
self.push(unsafe { val.get_js() });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_unrooted(&mut self, index: usize, val: &T) {
|
|
||||||
self.insert(index, unsafe { val.get_js() });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An opaque, LIFO rooting mechanism. This tracks roots and ensures that they
|
|
||||||
/// are destructed in a LIFO order.
|
|
||||||
///
|
///
|
||||||
/// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*]
|
/// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*]
|
||||||
/// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting).
|
/// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting).
|
||||||
#[no_move]
|
#[no_move]
|
||||||
pub struct RootCollection {
|
pub struct RootCollection {
|
||||||
roots: UnsafeCell<RootedVec<*mut JSObject>>,
|
roots: UnsafeCell<Vec<*const Reflector>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A pointer to a RootCollection, for use in global variables.
|
/// A pointer to a RootCollection, for use in global variables.
|
||||||
|
@ -555,142 +336,114 @@ impl Clone for RootCollectionPtr {
|
||||||
impl RootCollection {
|
impl RootCollection {
|
||||||
/// Create an empty collection of roots
|
/// Create an empty collection of roots
|
||||||
pub fn new() -> RootCollection {
|
pub fn new() -> RootCollection {
|
||||||
let addr = unsafe {
|
|
||||||
return_address() as *const libc::c_void
|
|
||||||
};
|
|
||||||
|
|
||||||
RootCollection {
|
RootCollection {
|
||||||
roots: UnsafeCell::new(RootedVec::new_with_destination_address(addr)),
|
roots: UnsafeCell::new(vec!()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Track a stack-based root as a pointer to ensure LIFO root ordering.
|
/// Start tracking a stack-based root
|
||||||
fn root<'b>(&self, untracked_js_ptr: *mut JSObject) {
|
fn root<'b>(&self, untracked_reflector: *const Reflector) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let roots = self.roots.get();
|
let mut roots = &mut *self.roots.get();
|
||||||
(*roots).push(untracked_js_ptr);
|
roots.push(untracked_reflector);
|
||||||
debug!(" rooting {:?}", untracked_js_ptr);
|
assert!(!(*untracked_reflector).get_jsobject().is_null())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop tracking a stack-based root, asserting if LIFO root ordering has
|
/// Stop tracking a stack-based root, asserting if the reflector isn't found
|
||||||
/// been violated
|
|
||||||
fn unroot<'b, T: Reflectable>(&self, rooted: &Root<T>) {
|
fn unroot<'b, T: Reflectable>(&self, rooted: &Root<T>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let roots = self.roots.get();
|
let mut roots = &mut *self.roots.get();
|
||||||
let unrooted = (*roots).pop().unwrap();
|
let old_reflector = &*rooted.r().reflector();
|
||||||
debug!("unrooted {:?} (expecting {:?}", unrooted, rooted.js_ptr);
|
match roots.iter().rposition(|r| *r == old_reflector) {
|
||||||
assert!(unrooted == rooted.js_ptr);
|
Some(idx) => {
|
||||||
|
roots.remove(idx);
|
||||||
|
},
|
||||||
|
None => panic!("Can't remove a root that was never rooted!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SM Callback that traces the rooted reflectors
|
||||||
|
pub unsafe fn trace_roots(tracer: *mut JSTracer) {
|
||||||
|
STACK_ROOTS.with(|ref collection| {
|
||||||
|
let RootCollectionPtr(collection) = collection.get().unwrap();
|
||||||
|
let collection = &*(*collection).roots.get();
|
||||||
|
for root in collection.iter() {
|
||||||
|
trace_reflector(tracer, "reflector", &**root);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// A rooted reference to a DOM object.
|
/// A rooted reference to a DOM object.
|
||||||
///
|
///
|
||||||
/// The JS value is pinned for the duration of this object's lifetime; roots
|
/// The JS value is pinned for the duration of this object's lifetime; roots
|
||||||
/// are additive, so this object's destruction will not invalidate other roots
|
/// are additive, so this object's destruction will not invalidate other roots
|
||||||
/// for the same JS value. `Root`s cannot outlive the associated
|
/// for the same JS value. `Root`s cannot outlive the associated
|
||||||
/// `RootCollection` object. Attempts to transfer ownership of a `Root` via
|
/// `RootCollection` object.
|
||||||
/// moving will trigger dynamic unrooting failures due to incorrect ordering.
|
|
||||||
#[no_move]
|
|
||||||
pub struct Root<T: Reflectable> {
|
pub struct Root<T: Reflectable> {
|
||||||
/// List that ensures correct dynamic root ordering
|
|
||||||
root_list: &'static RootCollection,
|
|
||||||
/// Reference to rooted value that must not outlive this container
|
/// Reference to rooted value that must not outlive this container
|
||||||
ptr: NonZero<*const T>,
|
ptr: NonZero<*const T>,
|
||||||
/// On-stack JS pointer to assuage conservative stack scanner
|
/// List that ensures correct dynamic root ordering
|
||||||
js_ptr: *mut JSObject,
|
root_list: *const RootCollection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> Root<T> {
|
impl<T: Reflectable> Root<T> {
|
||||||
/// Create a new stack-bounded root for the provided JS-owned value.
|
/// Create a new stack-bounded root for the provided JS-owned value.
|
||||||
/// It cannot not outlive its associated `RootCollection`, and it contains
|
/// It cannot not outlive its associated `RootCollection`, and it gives
|
||||||
/// a `JSRef` which cannot outlive this new `Root`.
|
/// out references which cannot outlive this new `Root`.
|
||||||
#[inline]
|
pub fn new(unrooted: NonZero<*const T>)
|
||||||
fn new(roots: &'static RootCollection, unrooted: NonZero<*const T>)
|
-> Root<T> {
|
||||||
-> Root<T> {
|
STACK_ROOTS.with(|ref collection| {
|
||||||
let js_ptr = unsafe {
|
let RootCollectionPtr(collection) = collection.get().unwrap();
|
||||||
(**unrooted).reflector().get_jsobject()
|
unsafe { (*collection).root(&*(**unrooted).reflector()) }
|
||||||
};
|
Root {
|
||||||
roots.root(js_ptr);
|
ptr: unrooted,
|
||||||
Root {
|
root_list: collection,
|
||||||
root_list: roots,
|
}
|
||||||
ptr: unrooted,
|
})
|
||||||
js_ptr: js_ptr,
|
}
|
||||||
}
|
|
||||||
|
/// Generate a new root from a reference
|
||||||
|
pub fn from_ref(unrooted: &T) -> Root<T> {
|
||||||
|
Root::new(unsafe { NonZero::new(&*unrooted) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain a safe reference to the wrapped JS owned-value that cannot
|
/// Obtain a safe reference to the wrapped JS owned-value that cannot
|
||||||
/// outlive the lifetime of this root.
|
/// outlive the lifetime of this root.
|
||||||
pub fn r<'b>(&'b self) -> JSRef<'b, T> {
|
pub fn r<'a>(&'a self) -> &'a T {
|
||||||
JSRef {
|
&**self
|
||||||
ptr: self.ptr,
|
|
||||||
chain: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain an unsafe reference to the wrapped JS owned-value that can
|
/// Don't use this. Don't make me find you.
|
||||||
/// outlive the lifetime of this root.
|
pub fn get_unsound_ref_forever<'a, 'b>(&'a self) -> &'b T {
|
||||||
///
|
unsafe { &**self.ptr }
|
||||||
/// DO NOT CALL.
|
}
|
||||||
pub fn get_unsound_ref_forever<'b>(&self) -> JSRef<'b, T> {
|
|
||||||
JSRef {
|
/// Generate a new root from a JS<T> reference
|
||||||
ptr: self.ptr,
|
#[allow(unrooted_must_root)]
|
||||||
chain: PhantomData,
|
pub fn from_rooted(js: JS<T>) -> Root<T> {
|
||||||
}
|
js.root()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Reflectable> Deref for Root<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref<'a>(&'a self) -> &'a T {
|
||||||
|
unsafe { &**self.ptr.deref() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Reflectable> PartialEq for Root<T> {
|
||||||
|
fn eq(&self, other: &Root<T>) -> bool {
|
||||||
|
self.ptr == other.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> Drop for Root<T> {
|
impl<T: Reflectable> Drop for Root<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.root_list.unroot(self);
|
unsafe { (*self.root_list).unroot(self); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Reflectable> Deref for JSRef<'a, T> {
|
|
||||||
type Target = T;
|
|
||||||
fn deref<'b>(&'b self) -> &'b T {
|
|
||||||
unsafe {
|
|
||||||
&**self.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A reference to a DOM object that is guaranteed to be alive. This is freely
|
|
||||||
/// copyable.
|
|
||||||
pub struct JSRef<'a, T> {
|
|
||||||
ptr: NonZero<*const T>,
|
|
||||||
chain: PhantomData<&'a ()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Copy for JSRef<'a, T> {}
|
|
||||||
|
|
||||||
impl<'a, T> Clone for JSRef<'a, T> {
|
|
||||||
fn clone(&self) -> JSRef<'a, T> {
|
|
||||||
JSRef {
|
|
||||||
ptr: self.ptr.clone(),
|
|
||||||
chain: self.chain,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, T> PartialEq<JSRef<'b, T>> for JSRef<'a, T> {
|
|
||||||
fn eq(&self, other: &JSRef<T>) -> bool {
|
|
||||||
self.ptr == other.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Reflectable> JSRef<'a, T> {
|
|
||||||
/// Returns the inner pointer directly.
|
|
||||||
pub fn extended_deref(self) -> &'a T {
|
|
||||||
unsafe {
|
|
||||||
&**self.ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> {
|
|
||||||
fn reflector<'b>(&'b self) -> &'b Reflector {
|
|
||||||
(**self).reflector()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,18 +8,19 @@
|
||||||
|
|
||||||
use dom::bindings::conversions::is_dom_proxy;
|
use dom::bindings::conversions::is_dom_proxy;
|
||||||
use dom::bindings::utils::delete_property_by_id;
|
use dom::bindings::utils::delete_property_by_id;
|
||||||
use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString};
|
use js::jsapi::{JSContext, JSPropertyDescriptor, JSObject, JSString};
|
||||||
use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewStringCopyN};
|
use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewStringCopyN};
|
||||||
use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto};
|
use js::jsapi::{JS_DefinePropertyById6, JS_NewObjectWithGivenProto};
|
||||||
use js::jsapi::{JS_ReportErrorFlagsAndNumber, JS_StrictPropertyStub};
|
use js::jsapi::{JS_StrictPropertyStub, JSErrNum};
|
||||||
use js::jsapi::{JSREPORT_WARNING, JSREPORT_STRICT, JSREPORT_STRICT_MODE_ERROR};
|
use js::jsapi::{Handle, HandleObject, HandleId, MutableHandle, RootedObject, ObjectOpResult};
|
||||||
|
use js::jsapi::AutoIdVector;
|
||||||
|
use js::jsapi::GetObjectProto;
|
||||||
use js::jsval::ObjectValue;
|
use js::jsval::ObjectValue;
|
||||||
use js::glue::GetProxyExtra;
|
use js::glue::GetProxyExtra;
|
||||||
use js::glue::{GetObjectProto, GetObjectParent, SetProxyExtra, GetProxyHandler};
|
use js::glue::{SetProxyExtra, GetProxyHandler};
|
||||||
use js::glue::InvokeGetOwnPropertyDescriptor;
|
use js::glue::InvokeGetOwnPropertyDescriptor;
|
||||||
use js::glue::RUST_js_GetErrorMessage;
|
use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY};
|
||||||
use js::glue::AutoIdVector;
|
use js::{JSTrue, JSFalse};
|
||||||
use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY, JSRESOLVE_QUALIFIED};
|
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -32,60 +33,78 @@ static JSPROXYSLOT_EXPANDO: u32 = 0;
|
||||||
/// Otherwise, walk along the prototype chain to find a property with that
|
/// Otherwise, walk along the prototype chain to find a property with that
|
||||||
/// name.
|
/// name.
|
||||||
pub unsafe extern fn get_property_descriptor(cx: *mut JSContext,
|
pub unsafe extern fn get_property_descriptor(cx: *mut JSContext,
|
||||||
proxy: *mut JSObject,
|
proxy: HandleObject,
|
||||||
id: jsid, set: bool,
|
id: HandleId,
|
||||||
desc: *mut JSPropertyDescriptor)
|
desc: MutableHandle<JSPropertyDescriptor>)
|
||||||
-> bool {
|
-> u8 {
|
||||||
let handler = GetProxyHandler(proxy);
|
let handler = GetProxyHandler(proxy.get());
|
||||||
if !InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) {
|
if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, desc) == 0 {
|
||||||
return false;
|
return JSFalse;
|
||||||
}
|
}
|
||||||
if !(*desc).obj.is_null() {
|
if !desc.get().obj.is_null() {
|
||||||
return true;
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//let proto = JS_GetPrototype(proxy);
|
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
||||||
let proto = GetObjectProto(proxy);
|
if GetObjectProto(cx, proxy, proto.handle_mut()) == 0 {
|
||||||
if proto.is_null() {
|
desc.get().obj = ptr::null_mut();
|
||||||
(*desc).obj = ptr::null_mut();
|
return JSTrue;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc) != 0
|
JS_GetPropertyDescriptorById(cx, proto.handle(), id, desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines an expando on the given `proxy`.
|
/// Defines an expando on the given `proxy`.
|
||||||
pub unsafe extern fn define_property(cx: *mut JSContext, proxy: *mut JSObject,
|
pub unsafe extern fn define_property(cx: *mut JSContext, proxy: HandleObject,
|
||||||
id: jsid, desc: *mut JSPropertyDescriptor)
|
id: HandleId, desc: Handle<JSPropertyDescriptor>,
|
||||||
-> bool {
|
result: *mut ObjectOpResult)
|
||||||
static JSMSG_GETTER_ONLY: libc::c_uint = 160;
|
-> u8 {
|
||||||
|
|
||||||
//FIXME: Workaround for https://github.com/mozilla/rust/issues/13385
|
//FIXME: Workaround for https://github.com/mozilla/rust/issues/13385
|
||||||
let setter: *const libc::c_void = mem::transmute((*desc).setter);
|
let setter: *const libc::c_void = mem::transmute(desc.get().setter);
|
||||||
let setter_stub: *const libc::c_void = mem::transmute(JS_StrictPropertyStub);
|
let setter_stub: *const libc::c_void = mem::transmute(JS_StrictPropertyStub);
|
||||||
if ((*desc).attrs & JSPROP_GETTER) != 0 && setter == setter_stub {
|
if (desc.get().attrs & JSPROP_GETTER) != 0 && setter == setter_stub {
|
||||||
return JS_ReportErrorFlagsAndNumber(cx,
|
(*result).code_ = JSErrNum::JSMSG_GETTER_ONLY as u32;
|
||||||
JSREPORT_WARNING | JSREPORT_STRICT |
|
return JSTrue;
|
||||||
JSREPORT_STRICT_MODE_ERROR,
|
|
||||||
Some(RUST_js_GetErrorMessage), ptr::null_mut(),
|
|
||||||
JSMSG_GETTER_ONLY) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let expando = ensure_expando_object(cx, proxy);
|
let expando = RootedObject::new(cx, ensure_expando_object(cx, proxy));
|
||||||
return JS_DefinePropertyById(cx, expando, id, (*desc).value, (*desc).getter,
|
JS_DefinePropertyById6(cx, expando.handle(), id, desc, result)
|
||||||
(*desc).setter, (*desc).attrs) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes an expando off the given `proxy`.
|
/// Deletes an expando off the given `proxy`.
|
||||||
pub unsafe extern fn delete(cx: *mut JSContext, proxy: *mut JSObject, id: jsid,
|
pub unsafe extern fn delete(cx: *mut JSContext, proxy: HandleObject, id: HandleId,
|
||||||
bp: *mut bool) -> bool {
|
bp: *mut ObjectOpResult) -> u8 {
|
||||||
let expando = get_expando_object(proxy);
|
let expando = RootedObject::new(cx, get_expando_object(proxy));
|
||||||
if expando.is_null() {
|
if expando.ptr.is_null() {
|
||||||
*bp = true;
|
(*bp).code_ = 0 /* OkCode */;
|
||||||
return true;
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return delete_property_by_id(cx, expando, id, &mut *bp);
|
delete_property_by_id(cx, expando.handle(), id, bp)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stub for ownPropertyKeys
|
||||||
|
pub unsafe extern fn own_property_keys(cx: *mut JSContext,
|
||||||
|
proxy: HandleObject,
|
||||||
|
props: *mut AutoIdVector) -> u8 {
|
||||||
|
// FIXME: implement this
|
||||||
|
// https://github.com/servo/servo/issues/6390
|
||||||
|
JSTrue
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Controls whether the Extensible bit can be changed
|
||||||
|
pub unsafe extern fn prevent_extensions(_cx: *mut JSContext,
|
||||||
|
_proxy: HandleObject,
|
||||||
|
result: *mut ObjectOpResult) -> u8 {
|
||||||
|
(*result).code_ = JSErrNum::JSMSG_CANT_PREVENT_EXTENSIONS as u32;
|
||||||
|
return JSTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reports whether the object is Extensible
|
||||||
|
pub unsafe extern fn is_extensible(_cx: *mut JSContext, _proxy: HandleObject,
|
||||||
|
succeeded: *mut u8) -> u8 {
|
||||||
|
*succeeded = JSTrue;
|
||||||
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the stringification of an object with class `name`.
|
/// Returns the stringification of an object with class `name`.
|
||||||
|
@ -103,10 +122,10 @@ pub fn object_to_string(cx: *mut JSContext, name: &str) -> *mut JSString {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the expando object, or null if there is none.
|
/// Get the expando object, or null if there is none.
|
||||||
pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject {
|
pub fn get_expando_object(obj: HandleObject) -> *mut JSObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(is_dom_proxy(obj));
|
assert!(is_dom_proxy(obj.get()));
|
||||||
let val = GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
let val = GetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO);
|
||||||
if val.is_undefined() {
|
if val.is_undefined() {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,18 +136,16 @@ pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject {
|
||||||
|
|
||||||
/// Get the expando object, or create it if it doesn't exist yet.
|
/// Get the expando object, or create it if it doesn't exist yet.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
pub fn ensure_expando_object(cx: *mut JSContext, obj: *mut JSObject)
|
pub fn ensure_expando_object(cx: *mut JSContext, obj: HandleObject)
|
||||||
-> *mut JSObject {
|
-> *mut JSObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(is_dom_proxy(obj));
|
assert!(is_dom_proxy(obj.get()));
|
||||||
let mut expando = get_expando_object(obj);
|
let mut expando = get_expando_object(obj);
|
||||||
if expando.is_null() {
|
if expando.is_null() {
|
||||||
expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(),
|
expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), HandleObject::null());
|
||||||
ptr::null_mut(),
|
|
||||||
GetObjectParent(obj));
|
|
||||||
assert!(!expando.is_null());
|
assert!(!expando.is_null());
|
||||||
|
|
||||||
SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(&*expando));
|
SetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO, ObjectValue(&*expando));
|
||||||
}
|
}
|
||||||
return expando;
|
return expando;
|
||||||
}
|
}
|
||||||
|
@ -142,18 +159,4 @@ pub fn fill_property_descriptor(desc: &mut JSPropertyDescriptor,
|
||||||
desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE;
|
desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE;
|
||||||
desc.getter = None;
|
desc.getter = None;
|
||||||
desc.setter = None;
|
desc.setter = None;
|
||||||
desc.shortid = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// No-op required hook.
|
|
||||||
pub unsafe extern fn get_own_property_names(_cx: *mut JSContext,
|
|
||||||
_obj: *mut JSObject,
|
|
||||||
_v: *mut AutoIdVector) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// No-op required hook.
|
|
||||||
pub unsafe extern fn enumerate(_cx: *mut JSContext, _obj: *mut JSObject,
|
|
||||||
_v: *mut AutoIdVector) -> bool {
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,12 @@
|
||||||
//! is rooted when a hashmap entry is first created, and unrooted when the hashmap entry
|
//! is rooted when a hashmap entry is first created, and unrooted when the hashmap entry
|
||||||
//! is removed.
|
//! is removed.
|
||||||
|
|
||||||
use dom::bindings::js::{Temporary, JSRef, Unrooted};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, Reflectable};
|
use dom::bindings::utils::{Reflector, Reflectable};
|
||||||
|
use dom::bindings::trace::trace_reflector;
|
||||||
use script_task::{ScriptMsg, ScriptChan};
|
use script_task::{ScriptMsg, ScriptChan};
|
||||||
|
|
||||||
use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext};
|
use js::jsapi::{JSContext, JSTracer};
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -35,6 +36,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use core::nonzero::NonZero;
|
||||||
|
|
||||||
thread_local!(pub static LIVE_REFERENCES: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None)));
|
thread_local!(pub static LIVE_REFERENCES: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None)));
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ impl<T: Reflectable> Trusted<T> {
|
||||||
/// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will
|
/// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will
|
||||||
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
|
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
|
||||||
/// lifetime.
|
/// lifetime.
|
||||||
pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> {
|
pub fn new(cx: *mut JSContext, ptr: &T, script_chan: Box<ScriptChan + Send>) -> Trusted<T> {
|
||||||
LIVE_REFERENCES.with(|ref r| {
|
LIVE_REFERENCES.with(|ref r| {
|
||||||
let r = r.borrow();
|
let r = r.borrow();
|
||||||
let live_references = r.as_ref().unwrap();
|
let live_references = r.as_ref().unwrap();
|
||||||
|
@ -81,14 +83,14 @@ impl<T: Reflectable> Trusted<T> {
|
||||||
/// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
|
/// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
|
||||||
/// a different thread than the original value from which this `Trusted<T>` was
|
/// a different thread than the original value from which this `Trusted<T>` was
|
||||||
/// obtained.
|
/// obtained.
|
||||||
pub fn to_temporary(&self) -> Temporary<T> {
|
pub fn root(&self) -> Root<T> {
|
||||||
assert!(LIVE_REFERENCES.with(|ref r| {
|
assert!(LIVE_REFERENCES.with(|ref r| {
|
||||||
let r = r.borrow();
|
let r = r.borrow();
|
||||||
let live_references = r.as_ref().unwrap();
|
let live_references = r.as_ref().unwrap();
|
||||||
self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
|
self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
|
||||||
}));
|
}));
|
||||||
unsafe {
|
unsafe {
|
||||||
Temporary::from_unrooted(Unrooted::from_raw(self.ptr as *const T))
|
Root::new(NonZero::new(self.ptr as *const T))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,10 +153,6 @@ impl LiveDOMReferences {
|
||||||
refcount.clone()
|
refcount.clone()
|
||||||
}
|
}
|
||||||
Vacant(entry) => {
|
Vacant(entry) => {
|
||||||
unsafe {
|
|
||||||
let rootable = (*ptr).reflector().rootable();
|
|
||||||
JS_AddObjectRoot(cx, rootable);
|
|
||||||
}
|
|
||||||
let refcount = Arc::new(Mutex::new(1));
|
let refcount = Arc::new(Mutex::new(1));
|
||||||
entry.insert(refcount.clone());
|
entry.insert(refcount.clone());
|
||||||
refcount
|
refcount
|
||||||
|
@ -168,7 +166,6 @@ impl LiveDOMReferences {
|
||||||
LIVE_REFERENCES.with(|ref r| {
|
LIVE_REFERENCES.with(|ref r| {
|
||||||
let r = r.borrow();
|
let r = r.borrow();
|
||||||
let live_references = r.as_ref().unwrap();
|
let live_references = r.as_ref().unwrap();
|
||||||
let reflectable = raw_reflectable as *const Reflector;
|
|
||||||
let mut table = live_references.table.borrow_mut();
|
let mut table = live_references.table.borrow_mut();
|
||||||
match table.entry(raw_reflectable) {
|
match table.entry(raw_reflectable) {
|
||||||
Occupied(entry) => {
|
Occupied(entry) => {
|
||||||
|
@ -178,9 +175,6 @@ impl LiveDOMReferences {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
JS_RemoveObjectRoot(cx, (*reflectable).rootable());
|
|
||||||
}
|
|
||||||
let _ = entry.remove();
|
let _ = entry.remove();
|
||||||
}
|
}
|
||||||
Vacant(_) => {
|
Vacant(_) => {
|
||||||
|
@ -194,3 +188,16 @@ impl LiveDOMReferences {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A JSTraceDataOp for tracing reflectors held in LIVE_REFERENCES
|
||||||
|
pub unsafe extern fn trace_refcounted_objects(tracer: *mut JSTracer, _data: *mut libc::c_void) {
|
||||||
|
LIVE_REFERENCES.with(|ref r| {
|
||||||
|
let r = r.borrow();
|
||||||
|
let live_references = r.as_ref().unwrap();
|
||||||
|
let table = live_references.table.borrow();
|
||||||
|
for obj in table.keys() {
|
||||||
|
let reflectable = &*(*obj as *const Reflector);
|
||||||
|
trace_reflector(tracer, "LIVE_REFERENCES", reflectable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use js::glue::JS_STRUCTURED_CLONE_VERSION;
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::JSContext;
|
||||||
use js::jsapi::{JS_WriteStructuredClone, JS_ClearPendingException};
|
use js::jsapi::{JS_WriteStructuredClone, JS_ClearPendingException};
|
||||||
use js::jsapi::JS_ReadStructuredClone;
|
use js::jsapi::JS_ReadStructuredClone;
|
||||||
use js::jsval::{JSVal, UndefinedValue};
|
use js::jsapi::{HandleValue, MutableHandleValue};
|
||||||
|
|
||||||
use libc::size_t;
|
use libc::size_t;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -26,13 +26,14 @@ pub struct StructuredCloneData {
|
||||||
|
|
||||||
impl StructuredCloneData {
|
impl StructuredCloneData {
|
||||||
/// Writes a structured clone. Returns a `DataClone` error if that fails.
|
/// Writes a structured clone. Returns a `DataClone` error if that fails.
|
||||||
pub fn write(cx: *mut JSContext, message: JSVal)
|
pub fn write(cx: *mut JSContext, message: HandleValue)
|
||||||
-> Fallible<StructuredCloneData> {
|
-> Fallible<StructuredCloneData> {
|
||||||
let mut data = ptr::null_mut();
|
let mut data = ptr::null_mut();
|
||||||
let mut nbytes = 0;
|
let mut nbytes = 0;
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes,
|
JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes,
|
||||||
ptr::null(), ptr::null_mut())
|
ptr::null(), ptr::null_mut(),
|
||||||
|
HandleValue::undefined())
|
||||||
};
|
};
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
unsafe { JS_ClearPendingException(cx); }
|
unsafe { JS_ClearPendingException(cx); }
|
||||||
|
@ -47,15 +48,13 @@ impl StructuredCloneData {
|
||||||
/// Reads a structured clone.
|
/// Reads a structured clone.
|
||||||
///
|
///
|
||||||
/// Panics if `JS_ReadStructuredClone` fails.
|
/// Panics if `JS_ReadStructuredClone` fails.
|
||||||
pub fn read(self, global: GlobalRef) -> JSVal {
|
pub fn read(self, global: GlobalRef, rval: MutableHandleValue) {
|
||||||
let mut message = UndefinedValue();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(JS_ReadStructuredClone(
|
assert!(JS_ReadStructuredClone(
|
||||||
global.get_cx(), self.data as *const u64, self.nbytes,
|
global.get_cx(), self.data, self.nbytes,
|
||||||
JS_STRUCTURED_CLONE_VERSION, &mut message,
|
JS_STRUCTURED_CLONE_VERSION, rval,
|
||||||
ptr::null(), ptr::null_mut()) != 0);
|
ptr::null(), ptr::null_mut()) != 0);
|
||||||
}
|
}
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ use euclid::size::Size2D;
|
||||||
use html5ever::tree_builder::QuirksMode;
|
use html5ever::tree_builder::QuirksMode;
|
||||||
use hyper::header::Headers;
|
use hyper::header::Headers;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSGCTraceKind};
|
use js::jsapi::{JSObject, JSTracer, JSGCTraceKind, JS_CallValueTracer, JS_CallObjectTracer, GCTraceKindToAscii, Heap};
|
||||||
|
use js::jsapi::JS_CallUnbarrieredObjectTracer;
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use layout_interface::{LayoutRPC, LayoutChan};
|
use layout_interface::{LayoutRPC, LayoutChan};
|
||||||
|
@ -59,7 +60,7 @@ use msg::compositor_msg::ScriptListener;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::ConstellationChan;
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
use util::str::{LengthOrPercentageOrAuto};
|
use util::str::{LengthOrPercentageOrAuto};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, UnsafeCell, RefCell};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::collections::hash_state::HashState;
|
use std::collections::hash_state::HashState;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -91,36 +92,46 @@ no_jsmanaged_fields!(EncodingRef);
|
||||||
no_jsmanaged_fields!(Reflector);
|
no_jsmanaged_fields!(Reflector);
|
||||||
|
|
||||||
/// Trace a `JSVal`.
|
/// Trace a `JSVal`.
|
||||||
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) {
|
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) {
|
||||||
if !val.is_markable() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
if !val.get().is_markable() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let name = CString::new(description).unwrap();
|
let name = CString::new(description).unwrap();
|
||||||
(*tracer).debugPrinter = None;
|
(*tracer).debugPrinter_ = None;
|
||||||
(*tracer).debugPrintIndex = !0;
|
(*tracer).debugPrintIndex_ = !0;
|
||||||
(*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void;
|
(*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void;
|
||||||
debug!("tracing value {}", description);
|
debug!("tracing value {}", description);
|
||||||
JS_CallTracer(tracer, val.to_gcthing(), val.trace_kind());
|
JS_CallValueTracer(tracer, val.ptr.get() as *mut _,
|
||||||
|
GCTraceKindToAscii(val.get().trace_kind()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trace the `JSObject` held by `reflector`.
|
/// Trace the `JSObject` held by `reflector`.
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) {
|
pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) {
|
||||||
trace_object(tracer, description, reflector.get_jsobject())
|
unsafe {
|
||||||
|
let name = CString::new(description).unwrap();
|
||||||
|
(*tracer).debugPrinter_ = None;
|
||||||
|
(*tracer).debugPrintIndex_ = !0;
|
||||||
|
(*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void;
|
||||||
|
debug!("tracing reflector {}", description);
|
||||||
|
JS_CallUnbarrieredObjectTracer(tracer, reflector.rootable(),
|
||||||
|
GCTraceKindToAscii(JSGCTraceKind::JSTRACE_OBJECT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trace a `JSObject`.
|
/// Trace a `JSObject`.
|
||||||
pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject) {
|
pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: &Heap<*mut JSObject>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let name = CString::new(description).unwrap();
|
let name = CString::new(description).unwrap();
|
||||||
(*tracer).debugPrinter = None;
|
(*tracer).debugPrinter_ = None;
|
||||||
(*tracer).debugPrintIndex = !0;
|
(*tracer).debugPrintIndex_ = !0;
|
||||||
(*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void;
|
(*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void;
|
||||||
debug!("tracing {}", description);
|
debug!("tracing {}", description);
|
||||||
JS_CallTracer(tracer, obj as *mut libc::c_void, JSGCTraceKind::JSTRACE_OBJECT);
|
JS_CallObjectTracer(tracer, obj.ptr.get() as *mut _,
|
||||||
|
GCTraceKindToAscii(JSGCTraceKind::JSTRACE_OBJECT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +179,26 @@ impl<T: JSTraceable+Copy> JSTraceable for Cell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JSTraceable for *mut JSObject {
|
impl<T: JSTraceable> JSTraceable for UnsafeCell<T> {
|
||||||
fn trace(&self, trc: *mut JSTracer) {
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
trace_object(trc, "object", *self);
|
unsafe { (*self.get()).trace(trc) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JSTraceable for JSVal {
|
|
||||||
|
impl JSTraceable for Heap<*mut JSObject> {
|
||||||
fn trace(&self, trc: *mut JSTracer) {
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
trace_jsval(trc, "val", *self);
|
if self.get().is_null() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trace_object(trc, "object", self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl JSTraceable for Heap<JSVal> {
|
||||||
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
trace_jsval(trc, "val", self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,115 +346,101 @@ impl JSTraceable for () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Holds a set of vectors that need to be rooted
|
/// Homemade trait object for JSTraceable things
|
||||||
pub struct RootedCollectionSet {
|
struct TraceableInfo {
|
||||||
set: Vec<HashSet<*const RootedVec<Void>>>
|
pub ptr: *const libc::c_void,
|
||||||
|
pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TLV Holds a set of vectors that need to be rooted
|
/// Holds a set of JSTraceables that need to be rooted
|
||||||
thread_local!(pub static ROOTED_COLLECTIONS: Rc<RefCell<RootedCollectionSet>> =
|
pub struct RootedTraceableSet {
|
||||||
Rc::new(RefCell::new(RootedCollectionSet::new())));
|
set: Vec<TraceableInfo>
|
||||||
|
|
||||||
/// Type of `RootedVec`
|
|
||||||
pub enum CollectionType {
|
|
||||||
/// DOM objects
|
|
||||||
DOMObjects,
|
|
||||||
/// `JSVal`s
|
|
||||||
JSVals,
|
|
||||||
/// `*mut JSObject`s
|
|
||||||
JSObjects,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TLV Holds a set of JSTraceables that need to be rooted
|
||||||
|
thread_local!(pub static ROOTED_TRACEABLES: Rc<RefCell<RootedTraceableSet>> =
|
||||||
|
Rc::new(RefCell::new(RootedTraceableSet::new())));
|
||||||
|
|
||||||
impl RootedCollectionSet {
|
impl RootedTraceableSet {
|
||||||
fn new() -> RootedCollectionSet {
|
fn new() -> RootedTraceableSet {
|
||||||
RootedCollectionSet {
|
RootedTraceableSet {
|
||||||
set: vec!(HashSet::new(), HashSet::new(), HashSet::new())
|
set: vec!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove<T: VecRootableType>(collection: &RootedVec<T>) {
|
fn remove<T: JSTraceable>(traceable: &T) {
|
||||||
ROOTED_COLLECTIONS.with(|ref collections| {
|
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||||
let type_ = VecRootableType::tag(None::<T>);
|
let mut traceables = traceables.borrow_mut();
|
||||||
let mut collections = collections.borrow_mut();
|
let idx =
|
||||||
assert!(collections.set[type_ as usize].remove(&(collection as *const _ as *const _)));
|
match traceables.set.iter()
|
||||||
|
.rposition(|x| x.ptr == traceable as *const T as *const _) {
|
||||||
|
Some(idx) => idx,
|
||||||
|
None => unreachable!(),
|
||||||
|
};
|
||||||
|
traceables.set.remove(idx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add<T: VecRootableType>(collection: &RootedVec<T>) {
|
fn add<T: JSTraceable>(traceable: &T) {
|
||||||
ROOTED_COLLECTIONS.with(|ref collections| {
|
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||||
let type_ = VecRootableType::tag(None::<T>);
|
fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) {
|
||||||
let mut collections = collections.borrow_mut();
|
let obj: &T = unsafe { &*(obj as *const T) };
|
||||||
collections.set[type_ as usize].insert(collection as *const _ as *const _);
|
obj.trace(tracer);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut traceables = traceables.borrow_mut();
|
||||||
|
let info = TraceableInfo {
|
||||||
|
ptr: traceable as *const T as *const libc::c_void,
|
||||||
|
trace: trace::<T>,
|
||||||
|
};
|
||||||
|
traceables.set.push(info);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
||||||
fn trace_collection_type<T>(tracer: *mut JSTracer,
|
for info in self.set.iter() {
|
||||||
collections: &HashSet<*const RootedVec<Void>>)
|
(info.trace)(info.ptr, tracer);
|
||||||
where T: JSTraceable + VecRootableType
|
|
||||||
{
|
|
||||||
for collection in collections {
|
|
||||||
let collection: *const RootedVec<Void> = *collection;
|
|
||||||
let collection = collection as *const RootedVec<T>;
|
|
||||||
unsafe {
|
|
||||||
let _ = (*collection).trace(tracer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dom_collections =
|
|
||||||
&self.set[CollectionType::DOMObjects as usize] as *const _ as *const HashSet<*const RootedVec<JS<Void>>>;
|
|
||||||
for dom_collection in (*dom_collections).iter() {
|
|
||||||
for reflector in (**dom_collection).iter() {
|
|
||||||
trace_reflector(tracer, "", reflector.reflector());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trace_collection_type::<JSVal>(tracer, &self.set[CollectionType::JSVals as usize]);
|
|
||||||
trace_collection_type::<*mut JSObject>(tracer, &self.set[CollectionType::JSObjects as usize]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Roots any JSTraceable thing
|
||||||
/// Trait implemented by all types that can be used with RootedVec
|
///
|
||||||
pub trait VecRootableType {
|
/// If you have a valid Reflectable, use Root.
|
||||||
/// Return the type tag used to determine how to trace RootedVec
|
/// If you have GC things like *mut JSObject or JSVal, use jsapi::Rooted.
|
||||||
fn tag(_a: Option<Self>) -> CollectionType;
|
/// If you have an arbitrary number of Reflectables to root, use RootedVec<JS<T>>
|
||||||
|
/// If you know what you're doing, use this.
|
||||||
|
#[jstraceable]
|
||||||
|
pub struct RootedTraceable<'a, T: 'a + JSTraceable> {
|
||||||
|
ptr: &'a T
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Reflectable> VecRootableType for JS<T> {
|
impl<'a, T: JSTraceable> RootedTraceable<'a, T> {
|
||||||
fn tag(_a: Option<JS<T>>) -> CollectionType { CollectionType::DOMObjects }
|
/// Root a JSTraceable thing for the life of this RootedTraceable
|
||||||
|
pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> {
|
||||||
|
RootedTraceableSet::add(traceable);
|
||||||
|
RootedTraceable { ptr: traceable }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VecRootableType for JSVal {
|
impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> {
|
||||||
fn tag(_a: Option<JSVal>) -> CollectionType { CollectionType::JSVals }
|
fn drop(&mut self) {
|
||||||
}
|
RootedTraceableSet::remove(self.ptr);
|
||||||
|
}
|
||||||
impl VecRootableType for *mut JSObject {
|
|
||||||
fn tag(_a: Option<*mut JSObject>) -> CollectionType { CollectionType::JSObjects }
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Void {}
|
|
||||||
|
|
||||||
impl VecRootableType for Void {
|
|
||||||
fn tag(_a: Option<Void>) -> CollectionType { unreachable!() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Reflectable for Void {
|
|
||||||
fn reflector<'a>(&'a self) -> &'a Reflector { unreachable!() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A vector of items that are rooted for the lifetime
|
/// A vector of items that are rooted for the lifetime
|
||||||
/// of this struct
|
/// of this struct.
|
||||||
|
/// Must be a reflectable
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
#[no_move]
|
#[no_move]
|
||||||
pub struct RootedVec<T: VecRootableType> {
|
#[jstraceable]
|
||||||
|
pub struct RootedVec<T: JSTraceable + Reflectable> {
|
||||||
v: Vec<T>
|
v: Vec<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<T: VecRootableType> RootedVec<T> {
|
impl<T: JSTraceable + Reflectable> RootedVec<T> {
|
||||||
/// Create a vector of items of type T that is rooted for
|
/// Create a vector of items of type T that is rooted for
|
||||||
/// the lifetime of this struct
|
/// the lifetime of this struct
|
||||||
pub fn new() -> RootedVec<T> {
|
pub fn new() -> RootedVec<T> {
|
||||||
|
@ -444,39 +452,38 @@ impl<T: VecRootableType> RootedVec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a vector of items of type T. This constructor is specific
|
/// Create a vector of items of type T. This constructor is specific
|
||||||
/// for RootCollection.
|
/// for RootTraceableSet.
|
||||||
pub fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec<T> {
|
pub fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
RootedCollectionSet::add::<T>(&*(addr as *const _));
|
RootedTraceableSet::add::<RootedVec<T>>(&*(addr as *const _));
|
||||||
}
|
}
|
||||||
RootedVec::<T> { v: vec!() }
|
RootedVec::<T> { v: vec!() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: VecRootableType> Drop for RootedVec<T> {
|
impl<T: JSTraceable + Reflectable> Drop for RootedVec<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
RootedCollectionSet::remove(self);
|
RootedTraceableSet::remove(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: VecRootableType> Deref for RootedVec<T> {
|
impl<T: JSTraceable + Reflectable> Deref for RootedVec<T> {
|
||||||
type Target = Vec<T>;
|
type Target = Vec<T>;
|
||||||
fn deref(&self) -> &Vec<T> {
|
fn deref(&self) -> &Vec<T> {
|
||||||
&self.v
|
&self.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: VecRootableType> DerefMut for RootedVec<T> {
|
impl<T: JSTraceable + Reflectable> DerefMut for RootedVec<T> {
|
||||||
fn deref_mut(&mut self) -> &mut Vec<T> {
|
fn deref_mut(&mut self) -> &mut Vec<T> {
|
||||||
&mut self.v
|
&mut self.v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SM Callback that traces the rooted traceables
|
||||||
/// SM Callback that traces the rooted collections
|
pub unsafe fn trace_traceables(tracer: *mut JSTracer) {
|
||||||
pub unsafe fn trace_collections(tracer: *mut JSTracer) {
|
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||||
ROOTED_COLLECTIONS.with(|ref collections| {
|
let traceables = traceables.borrow();
|
||||||
let collections = collections.borrow();
|
traceables.trace(tracer);
|
||||||
collections.trace(tracer);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::PrototypeList;
|
use dom::bindings::codegen::PrototypeList;
|
||||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||||
use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class};
|
use dom::bindings::conversions::{native_from_handleobject, is_dom_class, jsstring_to_str};
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{Temporary, Root, Rootable};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::trace::trace_object;
|
use dom::bindings::trace::trace_object;
|
||||||
use dom::browsercontext;
|
use dom::browsercontext;
|
||||||
use dom::window;
|
use dom::window;
|
||||||
|
@ -19,30 +19,39 @@ use util::str::DOMString;
|
||||||
use libc;
|
use libc;
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::boxed;
|
use std::boxed;
|
||||||
use std::cell::Cell;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::cmp::PartialEq;
|
||||||
|
use std::default::Default;
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
use js::glue::UnwrapObject;
|
use js::glue::UnwrapObject;
|
||||||
use js::glue::{IsWrapper, RUST_JSID_IS_INT, RUST_JSID_TO_INT};
|
use js::glue::{IsWrapper, RUST_JSID_IS_INT, RUST_JSID_TO_INT};
|
||||||
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
|
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction, JSTraceOp};
|
||||||
use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
|
use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
|
||||||
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAndLength};
|
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
|
||||||
use js::jsapi::{JSHandleObject, JSTracer};
|
use js::jsapi::{HandleObject, HandleId, HandleValue, MutableHandleValue};
|
||||||
use js::jsapi::JS_GetFunctionObject;
|
use js::jsapi::JS_GetFunctionObject;
|
||||||
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype};
|
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype};
|
||||||
use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty};
|
use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty};
|
||||||
use js::jsapi::{JS_DefineFunctions, JS_DefineProperty};
|
use js::jsapi::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperty1};
|
||||||
use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
|
use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
|
||||||
use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass};
|
use js::jsapi::{JSContext, JSObject, JSClass, JSTracer};
|
||||||
use js::jsapi::{JSFunctionSpec, JSPropertySpec};
|
use js::jsapi::{JSFunctionSpec, JSPropertySpec};
|
||||||
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
|
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
|
||||||
use js::jsapi::JS_DeletePropertyById2;
|
use js::jsapi::{OnNewGlobalHookOption, CompartmentOptions};
|
||||||
use js::jsfriendapi::JS_ObjectToOuterObject;
|
use js::jsapi::{JS_FireOnNewGlobalObject, JSVersion};
|
||||||
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
use js::jsapi::JS_DeletePropertyById1;
|
||||||
|
use js::jsapi::JS_ObjectToOuterObject;
|
||||||
|
use js::jsapi::JS_NewObjectWithUniqueType;
|
||||||
|
use js::jsapi::{ObjectOpResult, RootedObject, RootedValue, Heap, MutableHandleObject};
|
||||||
|
use js::jsapi::PropertyDefinitionBehavior;
|
||||||
|
use js::jsapi::JSAutoCompartment;
|
||||||
|
use js::jsapi::{DOMCallbacks, JSWrapObjectCallbacks};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::jsval::{PrivateValue, ObjectValue, NullValue};
|
use js::jsval::{PrivateValue, NullValue};
|
||||||
use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue, UndefinedValue};
|
use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue};
|
||||||
use js::rust::with_compartment;
|
use js::rust::{GCMethods, ToString};
|
||||||
|
use js::glue::{WrapperNew, GetCrossCompartmentWrapper};
|
||||||
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
||||||
use js::JSFUN_CONSTRUCTOR;
|
use js::JSFUN_CONSTRUCTOR;
|
||||||
use js;
|
use js;
|
||||||
|
@ -145,7 +154,7 @@ unsafe impl Sync for DOMClass {}
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct DOMJSClass {
|
pub struct DOMJSClass {
|
||||||
/// The actual JSClass.
|
/// The actual JSClass.
|
||||||
pub base: js::Class,
|
pub base: js::jsapi::Class,
|
||||||
/// Associated data for DOM object reflectors.
|
/// Associated data for DOM object reflectors.
|
||||||
pub dom_class: DOMClass
|
pub dom_class: DOMClass
|
||||||
}
|
}
|
||||||
|
@ -181,95 +190,93 @@ unsafe impl Sync for NativeProperties {}
|
||||||
|
|
||||||
/// A JSNative that cannot be null.
|
/// A JSNative that cannot be null.
|
||||||
pub type NonNullJSNative =
|
pub type NonNullJSNative =
|
||||||
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> u8;
|
||||||
|
|
||||||
/// Creates the *interface prototype object* (if a `proto_class` is given)
|
/// Creates the *interface prototype object* (if a `proto_class` is given)
|
||||||
/// and the *interface object* (if a `constructor` is given).
|
/// and the *interface object* (if a `constructor` is given).
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
pub fn do_create_interface_objects(cx: *mut JSContext, global: *mut JSObject,
|
pub fn do_create_interface_objects(cx: *mut JSContext,
|
||||||
receiver: *mut JSObject,
|
receiver: HandleObject,
|
||||||
proto_proto: *mut JSObject,
|
proto_proto: HandleObject,
|
||||||
proto_class: Option<&'static JSClass>,
|
proto_class: Option<&'static JSClass>,
|
||||||
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
||||||
dom_class: *const DOMClass,
|
dom_class: *const DOMClass,
|
||||||
members: &'static NativeProperties)
|
members: &'static NativeProperties,
|
||||||
-> *mut JSObject {
|
rval: MutableHandleObject) {
|
||||||
|
if let Some(proto_class) = proto_class {
|
||||||
|
create_interface_prototype_object(cx, proto_proto,
|
||||||
|
proto_class, members, rval);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let proto = match proto_class {
|
if !rval.get().is_null() {
|
||||||
Some(proto_class) => {
|
JS_SetReservedSlot(rval.get(), DOM_PROTO_INSTANCE_CLASS_SLOT,
|
||||||
let proto = create_interface_prototype_object(cx, global, proto_proto,
|
PrivateValue(dom_class as *const libc::c_void));
|
||||||
proto_class, members);
|
|
||||||
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
|
||||||
PrivateValue(dom_class as *const libc::c_void));
|
|
||||||
proto
|
|
||||||
},
|
|
||||||
None => ptr::null_mut()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some((native, name, nargs)) = constructor {
|
|
||||||
let s = CString::new(name).unwrap();
|
|
||||||
create_interface_object(cx, global, receiver,
|
|
||||||
native, nargs, proto,
|
|
||||||
members, s.as_ptr())
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proto
|
if let Some((native, name, nargs)) = constructor {
|
||||||
|
let s = CString::new(name).unwrap();
|
||||||
|
create_interface_object(cx, receiver,
|
||||||
|
native, nargs, rval.handle(),
|
||||||
|
members, s.as_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the *interface object*.
|
/// Creates the *interface object*.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
fn create_interface_object(cx: *mut JSContext, global: *mut JSObject,
|
fn create_interface_object(cx: *mut JSContext,
|
||||||
receiver: *mut JSObject,
|
receiver: HandleObject,
|
||||||
constructor_native: NonNullJSNative,
|
constructor_native: NonNullJSNative,
|
||||||
ctor_nargs: u32, proto: *mut JSObject,
|
ctor_nargs: u32, proto: HandleObject,
|
||||||
members: &'static NativeProperties,
|
members: &'static NativeProperties,
|
||||||
name: *const libc::c_char) {
|
name: *const libc::c_char) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fun = JS_NewFunction(cx, Some(constructor_native), ctor_nargs,
|
let fun = JS_NewFunction(cx, Some(constructor_native), ctor_nargs,
|
||||||
JSFUN_CONSTRUCTOR, global, name);
|
JSFUN_CONSTRUCTOR, name);
|
||||||
assert!(!fun.is_null());
|
assert!(!fun.is_null());
|
||||||
|
|
||||||
let constructor = JS_GetFunctionObject(fun);
|
let constructor = RootedObject::new(cx, JS_GetFunctionObject(fun));
|
||||||
assert!(!constructor.is_null());
|
assert!(!constructor.ptr.is_null());
|
||||||
|
|
||||||
if let Some(static_methods) = members.static_methods {
|
if let Some(static_methods) = members.static_methods {
|
||||||
define_methods(cx, constructor, static_methods);
|
define_methods(cx, constructor.handle(), static_methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(static_properties) = members.static_attrs {
|
if let Some(static_properties) = members.static_attrs {
|
||||||
define_properties(cx, constructor, static_properties);
|
define_properties(cx, constructor.handle(), static_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(constants) = members.consts {
|
if let Some(constants) = members.consts {
|
||||||
define_constants(cx, constructor, constants);
|
define_constants(cx, constructor.handle(), constants);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !proto.is_null() {
|
if !proto.get().is_null() {
|
||||||
assert!(JS_LinkConstructorAndPrototype(cx, constructor, proto) != 0);
|
assert!(JS_LinkConstructorAndPrototype(cx, constructor.handle(), proto) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut already_defined = 0;
|
let mut already_defined = 0;
|
||||||
assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut already_defined) != 0);
|
assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut already_defined) != 0);
|
||||||
|
|
||||||
if already_defined == 0 {
|
if already_defined == 0 {
|
||||||
assert!(JS_DefineProperty(cx, receiver, name,
|
assert!(JS_DefineProperty1(cx, receiver, name,
|
||||||
ObjectValue(&*constructor),
|
constructor.handle(),
|
||||||
None, None, 0) != 0);
|
0, None, None) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines constants on `obj`.
|
/// Defines constants on `obj`.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
fn define_constants(cx: *mut JSContext, obj: *mut JSObject,
|
fn define_constants(cx: *mut JSContext, obj: HandleObject,
|
||||||
constants: &'static [ConstantSpec]) {
|
constants: &'static [ConstantSpec]) {
|
||||||
for spec in constants.iter() {
|
for spec in constants.iter() {
|
||||||
|
let value = RootedValue::new(cx, spec.get_value());
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(JS_DefineProperty(cx, obj, spec.name.as_ptr() as *const libc::c_char,
|
assert!(JS_DefineProperty(cx, obj, spec.name.as_ptr() as *const libc::c_char,
|
||||||
spec.get_value(), None, None,
|
value.handle(),
|
||||||
JSPROP_ENUMERATE | JSPROP_READONLY |
|
JSPROP_ENUMERATE | JSPROP_READONLY |
|
||||||
JSPROP_PERMANENT) != 0);
|
JSPROP_PERMANENT, None, None) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,17 +284,17 @@ fn define_constants(cx: *mut JSContext, obj: *mut JSObject,
|
||||||
/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
|
/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
|
||||||
/// memory.
|
/// memory.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
fn define_methods(cx: *mut JSContext, obj: *mut JSObject,
|
fn define_methods(cx: *mut JSContext, obj: HandleObject,
|
||||||
methods: &'static [JSFunctionSpec]) {
|
methods: &'static [JSFunctionSpec]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(JS_DefineFunctions(cx, obj, methods.as_ptr()) != 0);
|
assert!(JS_DefineFunctions(cx, obj, methods.as_ptr(), PropertyDefinitionBehavior::DefineAllProperties) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines attributes on `obj`. The last entry of `properties` must contain
|
/// Defines attributes on `obj`. The last entry of `properties` must contain
|
||||||
/// zeroed memory.
|
/// zeroed memory.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
fn define_properties(cx: *mut JSContext, obj: *mut JSObject,
|
fn define_properties(cx: *mut JSContext, obj: HandleObject,
|
||||||
properties: &'static [JSPropertySpec]) {
|
properties: &'static [JSPropertySpec]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0);
|
assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0);
|
||||||
|
@ -296,36 +303,32 @@ fn define_properties(cx: *mut JSContext, obj: *mut JSObject,
|
||||||
|
|
||||||
/// Creates the *interface prototype object*.
|
/// Creates the *interface prototype object*.
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
fn create_interface_prototype_object(cx: *mut JSContext, global: *mut JSObject,
|
fn create_interface_prototype_object(cx: *mut JSContext, global: HandleObject,
|
||||||
parent_proto: *mut JSObject,
|
|
||||||
proto_class: &'static JSClass,
|
proto_class: &'static JSClass,
|
||||||
members: &'static NativeProperties)
|
members: &'static NativeProperties,
|
||||||
-> *mut JSObject {
|
rval: MutableHandleObject) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let our_proto = JS_NewObjectWithUniqueType(cx, proto_class,
|
rval.set(JS_NewObjectWithUniqueType(cx, proto_class, global));
|
||||||
&*parent_proto, &*global);
|
assert!(!rval.get().is_null());
|
||||||
assert!(!our_proto.is_null());
|
|
||||||
|
|
||||||
if let Some(methods) = members.methods {
|
if let Some(methods) = members.methods {
|
||||||
define_methods(cx, our_proto, methods);
|
define_methods(cx, rval.handle(), methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(properties) = members.attrs {
|
if let Some(properties) = members.attrs {
|
||||||
define_properties(cx, our_proto, properties);
|
define_properties(cx, rval.handle(), properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(constants) = members.consts {
|
if let Some(constants) = members.consts {
|
||||||
define_constants(cx, our_proto, constants);
|
define_constants(cx, rval.handle(), constants);
|
||||||
}
|
}
|
||||||
|
|
||||||
return our_proto;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A throwing constructor, for those interfaces that have neither
|
/// A throwing constructor, for those interfaces that have neither
|
||||||
/// `NoInterfaceObject` nor `Constructor`.
|
/// `NoInterfaceObject` nor `Constructor`.
|
||||||
pub unsafe extern fn throwing_constructor(cx: *mut JSContext, _argc: c_uint,
|
pub unsafe extern fn throwing_constructor(cx: *mut JSContext, _argc: c_uint,
|
||||||
_vp: *mut JSVal) -> JSBool {
|
_vp: *mut JSVal) -> u8 {
|
||||||
throw_type_error(cx, "Illegal constructor.");
|
throw_type_error(cx, "Illegal constructor.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +354,10 @@ pub fn initialize_global(global: *mut JSObject) {
|
||||||
pub trait Reflectable {
|
pub trait Reflectable {
|
||||||
/// Returns the receiver's reflector.
|
/// Returns the receiver's reflector.
|
||||||
fn reflector<'a>(&'a self) -> &'a Reflector;
|
fn reflector<'a>(&'a self) -> &'a Reflector;
|
||||||
|
/// Initializes the Reflector
|
||||||
|
fn init_reflector(&mut self, _obj: *mut JSObject) {
|
||||||
|
panic!("Cannot call init on this Reflectable");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the reflector for a new DOM object and yield ownership to the
|
/// Create the reflector for a new DOM object and yield ownership to the
|
||||||
|
@ -358,47 +365,56 @@ pub trait Reflectable {
|
||||||
pub fn reflect_dom_object<T: Reflectable>
|
pub fn reflect_dom_object<T: Reflectable>
|
||||||
(obj: Box<T>,
|
(obj: Box<T>,
|
||||||
global: GlobalRef,
|
global: GlobalRef,
|
||||||
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Temporary<T>)
|
wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
|
||||||
-> Temporary<T> {
|
-> Root<T> {
|
||||||
wrap_fn(global.get_cx(), global, obj)
|
wrap_fn(global.get_cx(), global, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct to store a reference to the reflector of a DOM object.
|
/// A struct to store a reference to the reflector of a DOM object.
|
||||||
// Allowing unused_attribute because the lint sometimes doesn't run in order
|
// Allowing unused_attribute because the lint sometimes doesn't run in order
|
||||||
#[allow(raw_pointer_derive, unrooted_must_root, unused_attributes)]
|
#[allow(raw_pointer_derive, unrooted_must_root, unused_attributes)]
|
||||||
#[derive(PartialEq)]
|
|
||||||
#[must_root]
|
#[must_root]
|
||||||
#[servo_lang = "reflector"]
|
#[servo_lang = "reflector"]
|
||||||
// If you're renaming or moving this field, update the path in plugins::reflector as well
|
// If you're renaming or moving this field, update the path in plugins::reflector as well
|
||||||
pub struct Reflector {
|
pub struct Reflector {
|
||||||
object: Cell<*mut JSObject>,
|
object: UnsafeCell<*mut JSObject>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
impl PartialEq for Reflector {
|
||||||
|
fn eq(&self, other: &Reflector) -> bool {
|
||||||
|
unsafe { *self.object.get() == *other.object.get() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reflector {
|
impl Reflector {
|
||||||
/// Get the reflector.
|
/// Get the reflector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_jsobject(&self) -> *mut JSObject {
|
pub fn get_jsobject(&self) -> HandleObject {
|
||||||
self.object.get()
|
HandleObject { ptr: self.object.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the reflector. (May be called only once.)
|
/// Initialize the reflector. (May be called only once.)
|
||||||
pub fn set_jsobject(&self, object: *mut JSObject) {
|
pub fn set_jsobject(&mut self, object: *mut JSObject) {
|
||||||
assert!(self.object.get().is_null());
|
unsafe {
|
||||||
assert!(!object.is_null());
|
let obj = self.object.get();
|
||||||
self.object.set(object);
|
assert!((*obj).is_null());
|
||||||
|
assert!(!object.is_null());
|
||||||
|
*obj = object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer to the memory location at which the JS reflector
|
/// Return a pointer to the memory location at which the JS reflector
|
||||||
/// object is stored. Used by Temporary values to root the reflector, as
|
/// object is stored. Used to root the reflector, as
|
||||||
/// required by the JSAPI rooting APIs.
|
/// required by the JSAPI rooting APIs.
|
||||||
pub unsafe fn rootable(&self) -> *mut *mut JSObject {
|
pub fn rootable(&self) -> *mut *mut JSObject {
|
||||||
self.object.as_unsafe_cell().get()
|
self.object.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an uninitialized `Reflector`.
|
/// Create an uninitialized `Reflector`.
|
||||||
pub fn new() -> Reflector {
|
pub fn new() -> Reflector {
|
||||||
Reflector {
|
Reflector {
|
||||||
object: Cell::new(ptr::null_mut()),
|
object: UnsafeCell::new(ptr::null_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,33 +423,34 @@ impl Reflector {
|
||||||
/// set to true and `*vp` to the value, otherwise `*found` is set to false.
|
/// set to true and `*vp` to the value, otherwise `*found` is set to false.
|
||||||
///
|
///
|
||||||
/// Returns false on JSAPI failure.
|
/// Returns false on JSAPI failure.
|
||||||
pub fn get_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject,
|
pub fn get_property_on_prototype(cx: *mut JSContext, proxy: HandleObject,
|
||||||
id: jsid, found: *mut bool, vp: *mut JSVal)
|
id: HandleId, found: *mut bool, vp: MutableHandleValue)
|
||||||
-> bool {
|
-> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
//let proto = GetObjectProto(proxy);
|
//let proto = GetObjectProto(proxy);
|
||||||
let proto = JS_GetPrototype(proxy);
|
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
||||||
if proto.is_null() {
|
if JS_GetPrototype(cx, proxy, proto.handle_mut()) == 0 ||
|
||||||
|
proto.ptr.is_null() {
|
||||||
*found = false;
|
*found = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let mut has_property = 0;
|
let mut has_property = 0;
|
||||||
if JS_HasPropertyById(cx, proto, id, &mut has_property) == 0 {
|
if JS_HasPropertyById(cx, proto.handle(), id, &mut has_property) == 0 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*found = has_property != 0;
|
*found = has_property != 0;
|
||||||
let no_output = vp.is_null();
|
let no_output = vp.ptr.is_null();
|
||||||
if has_property == 0 || no_output {
|
if has_property == 0 || no_output {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp) != 0
|
JS_ForwardGetPropertyTo(cx, proto.handle(), id, proxy, vp) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an array index from the given `jsid`. Returns `None` if the given
|
/// Get an array index from the given `jsid`. Returns `None` if the given
|
||||||
/// `jsid` is not an integer.
|
/// `jsid` is not an integer.
|
||||||
pub fn get_array_index_from_id(_cx: *mut JSContext, id: jsid) -> Option<u32> {
|
pub fn get_array_index_from_id(_cx: *mut JSContext, id: HandleId) -> Option<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if RUST_JSID_IS_INT(id) != 0 {
|
if RUST_JSID_IS_INT(id) != 0 {
|
||||||
return Some(RUST_JSID_TO_INT(id) as u32);
|
return Some(RUST_JSID_TO_INT(id) as u32);
|
||||||
|
@ -460,28 +477,16 @@ pub fn get_array_index_from_id(_cx: *mut JSContext, id: jsid) -> Option<u32> {
|
||||||
/// Returns `Err(())` on JSAPI failure (there is a pending exception), and
|
/// Returns `Err(())` on JSAPI failure (there is a pending exception), and
|
||||||
/// `Ok(None)` if there was no matching string.
|
/// `Ok(None)` if there was no matching string.
|
||||||
pub fn find_enum_string_index(cx: *mut JSContext,
|
pub fn find_enum_string_index(cx: *mut JSContext,
|
||||||
v: JSVal,
|
v: HandleValue,
|
||||||
values: &[&'static str])
|
values: &[&'static str])
|
||||||
-> Result<Option<usize>, ()> {
|
-> Result<Option<usize>, ()> {
|
||||||
unsafe {
|
let jsstr = ToString(cx, v);
|
||||||
let jsstr = JS_ValueToString(cx, v);
|
if jsstr.is_null() {
|
||||||
if jsstr.is_null() {
|
return Err(());
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut length = 0;
|
|
||||||
let chars = JS_GetStringCharsAndLength(cx, jsstr, &mut length);
|
|
||||||
if chars.is_null() {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(values.iter().position(|value| {
|
|
||||||
value.len() == length as usize &&
|
|
||||||
(0..length as usize).all(|j| {
|
|
||||||
value.as_bytes()[j] as u16 == *chars.offset(j as isize)
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let search = jsstring_to_str(cx, jsstr);
|
||||||
|
Ok(values.iter().position(|value| value == &search))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns wether `obj` is a platform object
|
/// Returns wether `obj` is a platform object
|
||||||
|
@ -495,7 +500,7 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool {
|
||||||
}
|
}
|
||||||
// Now for simplicity check for security wrappers before anything else
|
// Now for simplicity check for security wrappers before anything else
|
||||||
if IsWrapper(obj) == 1 {
|
if IsWrapper(obj) == 1 {
|
||||||
let unwrapped_obj = UnwrapObject(obj, /* stopAtOuter = */ 0, ptr::null_mut());
|
let unwrapped_obj = UnwrapObject(obj, /* stopAtOuter = */ 0);
|
||||||
if unwrapped_obj.is_null() {
|
if unwrapped_obj.is_null() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -508,53 +513,54 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool {
|
||||||
|
|
||||||
/// Get the property with name `property` from `object`.
|
/// Get the property with name `property` from `object`.
|
||||||
/// Returns `Err(())` on JSAPI failure (there is a pending exception), and
|
/// Returns `Err(())` on JSAPI failure (there is a pending exception), and
|
||||||
/// `Ok(None)` if there was no property with the given name.
|
/// `Ok(false)` if there was no property with the given name.
|
||||||
pub fn get_dictionary_property(cx: *mut JSContext,
|
pub fn get_dictionary_property(cx: *mut JSContext,
|
||||||
object: *mut JSObject,
|
object: HandleObject,
|
||||||
property: &str) -> Result<Option<JSVal>, ()> {
|
property: &str,
|
||||||
fn has_property(cx: *mut JSContext, object: *mut JSObject, property: &CString,
|
rval: MutableHandleValue)
|
||||||
found: &mut JSBool) -> bool {
|
-> Result<bool, ()> {
|
||||||
|
fn has_property(cx: *mut JSContext, object: HandleObject, property: &CString,
|
||||||
|
found: &mut u8) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_HasProperty(cx, object, property.as_ptr(), found) != 0
|
JS_HasProperty(cx, object, property.as_ptr(), found) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_property(cx: *mut JSContext, object: *mut JSObject, property: &CString,
|
fn get_property(cx: *mut JSContext, object: HandleObject, property: &CString,
|
||||||
value: &mut JSVal) -> bool {
|
value: MutableHandleValue) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_GetProperty(cx, object, property.as_ptr(), value) != 0
|
JS_GetProperty(cx, object, property.as_ptr(), value) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let property = CString::new(property).unwrap();
|
let property = CString::new(property).unwrap();
|
||||||
if object.is_null() {
|
if object.get().is_null() {
|
||||||
return Ok(None);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut found: JSBool = 0;
|
let mut found: u8 = 0;
|
||||||
if !has_property(cx, object, &property, &mut found) {
|
if !has_property(cx, object, &property, &mut found) {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if found == 0 {
|
if found == 0 {
|
||||||
return Ok(None);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut value = NullValue();
|
if !get_property(cx, object, &property, rval) {
|
||||||
if !get_property(cx, object, &property, &mut value) {
|
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(value))
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the property with name `property` from `object`.
|
/// Set the property with name `property` from `object`.
|
||||||
/// Returns `Err(())` on JSAPI failure, or null object,
|
/// Returns `Err(())` on JSAPI failure, or null object,
|
||||||
/// and Ok(()) otherwise
|
/// and Ok(()) otherwise
|
||||||
pub fn set_dictionary_property(cx: *mut JSContext,
|
pub fn set_dictionary_property(cx: *mut JSContext,
|
||||||
object: *mut JSObject,
|
object: HandleObject,
|
||||||
property: &str,
|
property: &str,
|
||||||
value: &mut JSVal) -> Result<(), ()> {
|
value: HandleValue) -> Result<(), ()> {
|
||||||
if object.is_null() {
|
if object.get().is_null() {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,79 +575,99 @@ pub fn set_dictionary_property(cx: *mut JSContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether `proxy` has a property `id` on its prototype.
|
/// Returns whether `proxy` has a property `id` on its prototype.
|
||||||
pub fn has_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject,
|
pub fn has_property_on_prototype(cx: *mut JSContext, proxy: HandleObject,
|
||||||
id: jsid) -> bool {
|
id: HandleId) -> bool {
|
||||||
// MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
|
// MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
return !get_property_on_prototype(cx, proxy, id, &mut found, ptr::null_mut()) || found;
|
return !get_property_on_prototype(cx, proxy, id, &mut found,
|
||||||
|
MutableHandleValue { ptr: ptr::null_mut() }) || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a DOM global object with the given class.
|
/// Create a DOM global object with the given class.
|
||||||
pub fn create_dom_global(cx: *mut JSContext, class: *const JSClass)
|
pub fn create_dom_global(cx: *mut JSContext, class: *const JSClass,
|
||||||
|
trace: JSTraceOp)
|
||||||
-> *mut JSObject {
|
-> *mut JSObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
let obj = JS_NewGlobalObject(cx, class, ptr::null_mut());
|
let mut options = CompartmentOptions::default();
|
||||||
if obj.is_null() {
|
options.version_ = JSVersion::JSVERSION_LATEST;
|
||||||
|
options.traceGlobal_ = trace;
|
||||||
|
|
||||||
|
let obj =
|
||||||
|
RootedObject::new(cx,
|
||||||
|
JS_NewGlobalObject(cx, class, ptr::null_mut(),
|
||||||
|
OnNewGlobalHookOption::DontFireOnNewGlobalHook, &options));
|
||||||
|
if obj.ptr.is_null() {
|
||||||
return ptr::null_mut();
|
return ptr::null_mut();
|
||||||
}
|
}
|
||||||
with_compartment(cx, obj, || {
|
let _ac = JSAutoCompartment::new(cx, obj.ptr);
|
||||||
JS_InitStandardClasses(cx, obj);
|
JS_InitStandardClasses(cx, obj.handle());
|
||||||
});
|
initialize_global(obj.ptr);
|
||||||
initialize_global(obj);
|
JS_FireOnNewGlobalObject(cx, obj.handle());
|
||||||
obj
|
obj.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drop the resources held by reserved slots of a global object
|
/// Drop the resources held by reserved slots of a global object
|
||||||
pub unsafe fn finalize_global(obj: *mut JSObject) {
|
pub unsafe fn finalize_global(obj: *mut JSObject) {
|
||||||
|
let protolist = get_proto_or_iface_array(obj);
|
||||||
|
let list = (*protolist).as_mut_ptr();
|
||||||
|
for idx in 0..(PrototypeList::ID::Count as isize) {
|
||||||
|
let entry = list.offset(idx);
|
||||||
|
let value = *entry;
|
||||||
|
if <*mut JSObject>::needs_post_barrier(value) {
|
||||||
|
<*mut JSObject>::relocate(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
let _: Box<ProtoOrIfaceArray> =
|
let _: Box<ProtoOrIfaceArray> =
|
||||||
Box::from_raw(get_proto_or_iface_array(obj));
|
Box::from_raw(protolist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trace the resources held by reserved slots of a global object
|
/// Trace the resources held by reserved slots of a global object
|
||||||
pub unsafe fn trace_global(tracer: *mut JSTracer, obj: *mut JSObject) {
|
pub unsafe fn trace_global(tracer: *mut JSTracer, obj: *mut JSObject) {
|
||||||
let array = get_proto_or_iface_array(obj);
|
let array = get_proto_or_iface_array(obj);
|
||||||
for &proto in (*array).iter() {
|
for proto in (&*array).iter() {
|
||||||
if !proto.is_null() {
|
if !proto.is_null() {
|
||||||
trace_object(tracer, "prototype", proto);
|
trace_object(tracer, "prototype", &*(proto as *const *mut JSObject as *const Heap<*mut JSObject>));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback to outerize windows when wrapping.
|
unsafe extern fn wrap(cx: *mut JSContext,
|
||||||
pub unsafe extern fn wrap_for_same_compartment(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObject {
|
existing: HandleObject,
|
||||||
|
obj: HandleObject)
|
||||||
|
-> *mut JSObject {
|
||||||
|
// FIXME terrible idea. need security wrappers
|
||||||
|
// https://github.com/servo/servo/issues/2382
|
||||||
|
WrapperNew(cx, obj, GetCrossCompartmentWrapper())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern fn pre_wrap(cx: *mut JSContext, _existing: HandleObject,
|
||||||
|
obj: HandleObject, _object_passed_to_wrap: HandleObject)
|
||||||
|
-> *mut JSObject {
|
||||||
|
let _ac = JSAutoCompartment::new(cx, obj.get());
|
||||||
JS_ObjectToOuterObject(cx, obj)
|
JS_ObjectToOuterObject(cx, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback to outerize windows before wrapping.
|
/// Callback table for use with JS_SetWrapObjectCallbacks
|
||||||
pub unsafe extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject,
|
pub static WRAP_CALLBACKS: JSWrapObjectCallbacks = JSWrapObjectCallbacks {
|
||||||
obj: *mut JSObject, _flags: c_uint) -> *mut JSObject {
|
wrap: Some(wrap),
|
||||||
JS_ObjectToOuterObject(cx, obj)
|
preWrap: Some(pre_wrap),
|
||||||
}
|
};
|
||||||
|
|
||||||
/// Callback to outerize windows.
|
/// Callback to outerize windows.
|
||||||
pub extern fn outerize_global(_cx: *mut JSContext, obj: JSHandleObject) -> *mut JSObject {
|
pub unsafe extern fn outerize_global(_cx: *mut JSContext, obj: HandleObject) -> *mut JSObject {
|
||||||
unsafe {
|
debug!("outerizing");
|
||||||
debug!("outerizing");
|
let win: Root<window::Window> = native_from_handleobject(obj).unwrap();
|
||||||
let obj = *obj.unnamed_field1;
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let win: Root<window::Window> = native_from_reflector_jsmanaged(obj).unwrap().root();
|
let win = win.r();
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
let context = win.browser_context();
|
||||||
let win = win.r();
|
context.as_ref().unwrap().window_proxy()
|
||||||
let context = win.browser_context();
|
|
||||||
context.as_ref().unwrap().window_proxy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes the property `id` from `object`.
|
/// Deletes the property `id` from `object`.
|
||||||
pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject,
|
pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: HandleObject,
|
||||||
id: jsid, bp: &mut bool) -> bool {
|
id: HandleId, bp: *mut ObjectOpResult) -> u8 {
|
||||||
let mut value = UndefinedValue();
|
JS_DeletePropertyById1(cx, object, id, bp)
|
||||||
if JS_DeletePropertyById2(cx, object, id, &mut value) == 0 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bp = value.to_boolean();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
||||||
|
@ -659,6 +685,18 @@ pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::Class,
|
||||||
|
proto_id: u32,
|
||||||
|
depth: u32) -> u8 {
|
||||||
|
let domclass: *const DOMJSClass = clasp as *const _;
|
||||||
|
let domclass = &*domclass;
|
||||||
|
(domclass.dom_class.interface_chain[depth as usize] as u32 == proto_id) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
|
||||||
|
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
|
||||||
|
};
|
||||||
|
|
||||||
/// Validate a namespace and qualified name and extract their parts.
|
/// Validate a namespace and qualified name and extract their parts.
|
||||||
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
||||||
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::InheritTypes::FileDerived;
|
use dom::bindings::codegen::InheritTypes::FileDerived;
|
||||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::codegen::Bindings::BlobBinding;
|
use dom::bindings::codegen::Bindings::BlobBinding;
|
||||||
|
@ -54,20 +54,20 @@ impl Blob {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef, bytes: Option<Vec<u8>>,
|
pub fn new(global: GlobalRef, bytes: Option<Vec<u8>>,
|
||||||
typeString: &str) -> Temporary<Blob> {
|
typeString: &str) -> Root<Blob> {
|
||||||
reflect_dom_object(box Blob::new_inherited(global, BlobTypeId::Blob, bytes, typeString),
|
reflect_dom_object(box Blob::new_inherited(global, BlobTypeId::Blob, bytes, typeString),
|
||||||
global,
|
global,
|
||||||
BlobBinding::Wrap)
|
BlobBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob
|
// http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob
|
||||||
pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<Blob>> {
|
pub fn Constructor(global: GlobalRef) -> Fallible<Root<Blob>> {
|
||||||
Ok(Blob::new(global, None, ""))
|
Ok(Blob::new(global, None, ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob
|
// http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob
|
||||||
pub fn Constructor_(global: GlobalRef, blobParts: DOMString,
|
pub fn Constructor_(global: GlobalRef, blobParts: DOMString,
|
||||||
blobPropertyBag: &BlobBinding::BlobPropertyBag) -> Fallible<Temporary<Blob>> {
|
blobPropertyBag: &BlobBinding::BlobPropertyBag) -> Fallible<Root<Blob>> {
|
||||||
//TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView or Blob
|
//TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView or Blob
|
||||||
let bytes: Option<Vec<u8>> = Some(blobParts.into_bytes());
|
let bytes: Option<Vec<u8>> = Some(blobParts.into_bytes());
|
||||||
let typeString = if is_ascii_printable(&blobPropertyBag.type_) {
|
let typeString = if is_ascii_printable(&blobPropertyBag.type_) {
|
||||||
|
@ -79,7 +79,7 @@ impl Blob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BlobMethods for JSRef<'a, Blob> {
|
impl<'a> BlobMethods for &'a Blob {
|
||||||
// http://dev.w3.org/2006/webapi/FileAPI/#dfn-size
|
// http://dev.w3.org/2006/webapi/FileAPI/#dfn-size
|
||||||
fn Size(self) -> u64{
|
fn Size(self) -> u64{
|
||||||
match self.bytes {
|
match self.bytes {
|
||||||
|
@ -95,7 +95,7 @@ impl<'a> BlobMethods for JSRef<'a, Blob> {
|
||||||
|
|
||||||
// http://dev.w3.org/2006/webapi/FileAPI/#slice-method-algo
|
// http://dev.w3.org/2006/webapi/FileAPI/#slice-method-algo
|
||||||
fn Slice(self, start: Option<i64>, end: Option<i64>,
|
fn Slice(self, start: Option<i64>, end: Option<i64>,
|
||||||
contentType: Option<DOMString>) -> Temporary<Blob> {
|
contentType: Option<DOMString>) -> Root<Blob> {
|
||||||
let size: i64 = self.Size().to_i64().unwrap();
|
let size: i64 = self.Size().to_i64().unwrap();
|
||||||
let relativeStart: i64 = match start {
|
let relativeStart: i64 = match start {
|
||||||
None => 0,
|
None => 0,
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
use dom::bindings::conversions::native_from_handleobject;
|
||||||
use dom::bindings::conversions::{ToJSValConvertible};
|
use dom::bindings::conversions::{ToJSValConvertible};
|
||||||
use dom::bindings::js::{JS, JSRef, Temporary, Root};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::js::{OptionalRootable, OptionalOptionalRootable};
|
|
||||||
use dom::bindings::js::{ResultRootable, Rootable};
|
|
||||||
use dom::bindings::proxyhandler::{get_property_descriptor, fill_property_descriptor};
|
use dom::bindings::proxyhandler::{get_property_descriptor, fill_property_descriptor};
|
||||||
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
|
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
|
||||||
use dom::bindings::utils::get_array_index_from_id;
|
use dom::bindings::utils::get_array_index_from_id;
|
||||||
|
@ -15,73 +13,72 @@ use dom::element::Element;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use dom::window::WindowHelpers;
|
use dom::window::WindowHelpers;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSObject, jsid, JSPropertyDescriptor};
|
use js::jsapi::{JSContext, JSObject, JSPropertyDescriptor, JSErrNum};
|
||||||
|
use js::jsapi::{HandleObject, HandleId, MutableHandle, MutableHandleValue};
|
||||||
use js::jsapi::{JS_AlreadyHasOwnPropertyById, JS_ForwardGetPropertyTo};
|
use js::jsapi::{JS_AlreadyHasOwnPropertyById, JS_ForwardGetPropertyTo};
|
||||||
use js::jsapi::{JS_GetPropertyDescriptorById, JS_DefinePropertyById};
|
use js::jsapi::{JS_GetPropertyDescriptorById, JS_DefinePropertyById6};
|
||||||
use js::jsapi::{JS_SetPropertyById};
|
use js::jsapi::{JS_ForwardSetPropertyTo, ObjectOpResult, RootedObject, RootedValue, Handle, HandleValue, Heap};
|
||||||
use js::jsval::JSVal;
|
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
|
||||||
|
use js::jsval::{ObjectValue, UndefinedValue};
|
||||||
use js::glue::{GetProxyPrivate};
|
use js::glue::{GetProxyPrivate};
|
||||||
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
|
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
|
||||||
use js::rust::with_compartment;
|
use js::{JSTrue, JSFalse};
|
||||||
use js::{JSRESOLVE_QUALIFIED, JSRESOLVE_ASSIGNING};
|
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::default::Default;
|
||||||
|
|
||||||
#[allow(raw_pointer_derive)]
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
#[privatize]
|
#[privatize]
|
||||||
pub struct BrowserContext {
|
pub struct BrowserContext {
|
||||||
history: Vec<SessionHistoryEntry>,
|
history: Vec<SessionHistoryEntry>,
|
||||||
active_index: usize,
|
active_index: usize,
|
||||||
window_proxy: *mut JSObject,
|
window_proxy: Heap<*mut JSObject>,
|
||||||
frame_element: Option<JS<Element>>,
|
frame_element: Option<JS<Element>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BrowserContext {
|
impl BrowserContext {
|
||||||
pub fn new(document: JSRef<Document>, frame_element: Option<JSRef<Element>>) -> BrowserContext {
|
pub fn new(document: &Document, frame_element: Option<&Element>) -> BrowserContext {
|
||||||
let mut context = BrowserContext {
|
BrowserContext {
|
||||||
history: vec!(SessionHistoryEntry::new(document)),
|
history: vec!(SessionHistoryEntry::new(document)),
|
||||||
active_index: 0,
|
active_index: 0,
|
||||||
window_proxy: ptr::null_mut(),
|
window_proxy: Heap::default(),
|
||||||
frame_element: frame_element.map(JS::from_rooted),
|
frame_element: frame_element.map(JS::from_ref),
|
||||||
};
|
}
|
||||||
context.create_window_proxy();
|
|
||||||
context
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_document(&self) -> Temporary<Document> {
|
pub fn active_document(&self) -> Root<Document> {
|
||||||
Temporary::from_rooted(self.history[self.active_index].document.clone())
|
self.history[self.active_index].document.root()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_window(&self) -> Temporary<Window> {
|
pub fn active_window(&self) -> Root<Window> {
|
||||||
let doc = self.active_document().root();
|
let doc = self.active_document();
|
||||||
doc.r().window()
|
doc.r().window()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame_element(&self) -> Option<Temporary<Element>> {
|
pub fn frame_element(&self) -> Option<Root<Element>> {
|
||||||
self.frame_element.map(Temporary::from_rooted)
|
self.frame_element.map(Root::from_rooted)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_proxy(&self) -> *mut JSObject {
|
pub fn window_proxy(&self) -> *mut JSObject {
|
||||||
assert!(!self.window_proxy.is_null());
|
assert!(!self.window_proxy.get().is_null());
|
||||||
self.window_proxy
|
self.window_proxy.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn create_window_proxy(&mut self) {
|
pub fn create_window_proxy(&mut self) {
|
||||||
let win = self.active_window().root();
|
let win = self.active_window();
|
||||||
let win = win.r();
|
let win = win.r();
|
||||||
|
|
||||||
let WindowProxyHandler(handler) = win.windowproxy_handler();
|
let WindowProxyHandler(handler) = win.windowproxy_handler();
|
||||||
assert!(!handler.is_null());
|
assert!(!handler.is_null());
|
||||||
|
|
||||||
let parent = win.reflector().get_jsobject();
|
|
||||||
let cx = win.get_cx();
|
let cx = win.get_cx();
|
||||||
let wrapper = with_compartment(cx, parent, || unsafe {
|
let _ar = JSAutoRequest::new(cx);
|
||||||
WrapperNew(cx, parent, handler)
|
let parent = win.reflector().get_jsobject();
|
||||||
});
|
let _ac = JSAutoCompartment::new(cx, parent.get());
|
||||||
|
let wrapper = unsafe { WrapperNew(cx, parent, handler) };
|
||||||
assert!(!wrapper.is_null());
|
assert!(!wrapper.is_null());
|
||||||
self.window_proxy = wrapper;
|
self.window_proxy.set(wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,20 +93,20 @@ pub struct SessionHistoryEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SessionHistoryEntry {
|
impl SessionHistoryEntry {
|
||||||
fn new(document: JSRef<Document>) -> SessionHistoryEntry {
|
fn new(document: &Document) -> SessionHistoryEntry {
|
||||||
SessionHistoryEntry {
|
SessionHistoryEntry {
|
||||||
document: JS::from_rooted(document),
|
document: JS::from_ref(document),
|
||||||
children: vec!()
|
children: vec!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: *mut JSObject, id: jsid) -> Option<Temporary<Window>> {
|
unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: HandleObject, id: HandleId) -> Option<Root<Window>> {
|
||||||
let index = get_array_index_from_id(cx, id);
|
let index = get_array_index_from_id(cx, id);
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
let win: Root<Window> = native_from_reflector_jsmanaged(target).unwrap().root();
|
let win: Root<Window> = native_from_handleobject(target.handle()).unwrap();
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
return win.r().IndexedGetter(index, &mut found);
|
return win.r().IndexedGetter(index, &mut found);
|
||||||
}
|
}
|
||||||
|
@ -118,132 +115,133 @@ unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: *mut JSObject, id: jsid)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern fn getOwnPropertyDescriptor(cx: *mut JSContext, proxy: *mut JSObject, id: jsid,
|
unsafe extern fn getOwnPropertyDescriptor(cx: *mut JSContext, proxy: HandleObject, id: HandleId,
|
||||||
set: bool, desc: *mut JSPropertyDescriptor) -> bool {
|
desc: MutableHandle<JSPropertyDescriptor>) -> u8 {
|
||||||
let window = GetSubframeWindow(cx, proxy, id);
|
let window = GetSubframeWindow(cx, proxy, id);
|
||||||
if let Some(window) = window {
|
if let Some(window) = window {
|
||||||
let window = window.root();
|
let mut val = RootedValue::new(cx, UndefinedValue());
|
||||||
(*desc).value = window.to_jsval(cx);
|
window.to_jsval(cx, val.handle_mut());
|
||||||
fill_property_descriptor(&mut *desc, proxy, true);
|
(*desc.ptr).value = val.ptr;
|
||||||
return true;
|
fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, true);
|
||||||
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED;
|
|
||||||
// XXX This should be JS_GetOwnPropertyDescriptorById
|
// XXX This should be JS_GetOwnPropertyDescriptorById
|
||||||
if JS_GetPropertyDescriptorById(cx, target, id, flags, desc) == 0 {
|
if JS_GetPropertyDescriptorById(cx, target.handle(), id, desc) == 0 {
|
||||||
return false;
|
return JSFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*desc).obj != target {
|
if (*desc.ptr).obj != target.ptr {
|
||||||
// Not an own property
|
// Not an own property
|
||||||
(*desc).obj = ptr::null_mut();
|
(*desc.ptr).obj = ptr::null_mut();
|
||||||
} else {
|
} else {
|
||||||
(*desc).obj = proxy;
|
(*desc.ptr).obj = *proxy.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
JSTrue
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern fn defineProperty(cx: *mut JSContext, proxy: *mut JSObject, id: jsid,
|
unsafe extern fn defineProperty(cx: *mut JSContext,
|
||||||
desc: *mut JSPropertyDescriptor) -> bool {
|
proxy: HandleObject,
|
||||||
|
id: HandleId,
|
||||||
|
desc: Handle<JSPropertyDescriptor>,
|
||||||
|
res: *mut ObjectOpResult) -> u8 {
|
||||||
if get_array_index_from_id(cx, id).is_some() {
|
if get_array_index_from_id(cx, id).is_some() {
|
||||||
// Spec says to Reject whether this is a supported index or not,
|
// Spec says to Reject whether this is a supported index or not,
|
||||||
// since we have no indexed setter or indexed creator. That means
|
// since we have no indexed setter or indexed creator. That means
|
||||||
// throwing in strict mode (FIXME: Bug 828137), doing nothing in
|
// throwing in strict mode (FIXME: Bug 828137), doing nothing in
|
||||||
// non-strict mode.
|
// non-strict mode.
|
||||||
return true;
|
(*res).code_ = JSErrNum::JSMSG_CANT_DEFINE_WINDOW_ELEMENT as u32;
|
||||||
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
JS_DefinePropertyById(cx, target, id, (*desc).value, (*desc).getter,
|
JS_DefinePropertyById6(cx, target.handle(), id, desc, res)
|
||||||
(*desc).setter, (*desc).attrs) != 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern fn hasOwn(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, bp: *mut bool) -> bool {
|
unsafe extern fn hasOwn(cx: *mut JSContext, proxy: HandleObject, id: HandleId, bp: *mut u8) -> u8 {
|
||||||
let window = GetSubframeWindow(cx, proxy, id);
|
let window = GetSubframeWindow(cx, proxy, id);
|
||||||
if window.is_some() {
|
if window.is_some() {
|
||||||
*bp = true;
|
*bp = JSTrue;
|
||||||
return true;
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
let mut found = 0;
|
let mut found = 0;
|
||||||
if JS_AlreadyHasOwnPropertyById(cx, target, id, &mut found) == 0 {
|
if JS_AlreadyHasOwnPropertyById(cx, target.handle(), id, &mut found) == 0 {
|
||||||
return false;
|
return JSFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bp = found != 0;
|
*bp = (found != 0) as u8;
|
||||||
return true;
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern fn get(cx: *mut JSContext, proxy: *mut JSObject, receiver: *mut JSObject, id: jsid,
|
unsafe extern fn get(cx: *mut JSContext,
|
||||||
vp: *mut JSVal) -> bool {
|
proxy: HandleObject,
|
||||||
|
receiver: HandleObject,
|
||||||
|
id: HandleId,
|
||||||
|
vp: MutableHandleValue) -> u8 {
|
||||||
let window = GetSubframeWindow(cx, proxy, id);
|
let window = GetSubframeWindow(cx, proxy, id);
|
||||||
if let Some(window) = window {
|
if let Some(window) = window {
|
||||||
let window = window.root();
|
window.to_jsval(cx, vp);
|
||||||
*vp = window.to_jsval(cx);
|
return JSTrue;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
JS_ForwardGetPropertyTo(cx, target, id, receiver, vp) != 0
|
JS_ForwardGetPropertyTo(cx, target.handle(), id, receiver, vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe extern fn set(cx: *mut JSContext, proxy: *mut JSObject, _receiver: *mut JSObject,
|
unsafe extern fn set(cx: *mut JSContext,
|
||||||
id: jsid, _strict: bool, vp: *mut JSVal) -> bool {
|
proxy: HandleObject,
|
||||||
|
receiver: HandleObject,
|
||||||
|
id: HandleId,
|
||||||
|
vp: MutableHandleValue,
|
||||||
|
res: *mut ObjectOpResult) -> u8 {
|
||||||
if get_array_index_from_id(cx, id).is_some() {
|
if get_array_index_from_id(cx, id).is_some() {
|
||||||
// Reject (which means throw if and only if strict) the set.
|
// Reject (which means throw if and only if strict) the set.
|
||||||
// FIXME: Throw
|
(*res).code_ = JSErrNum::JSMSG_READ_ONLY as u32;
|
||||||
return true;
|
return JSTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: The receiver should be used, we need something like JS_ForwardSetPropertyTo.
|
let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object());
|
||||||
let target = GetProxyPrivate(proxy).to_object();
|
let receiver = RootedValue::new(cx, ObjectValue(&**receiver.ptr));
|
||||||
JS_SetPropertyById(cx, target, id, vp) != 0
|
JS_ForwardSetPropertyTo(cx, target.handle(), id, HandleValue { ptr: vp.ptr }, receiver.handle(), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PROXY_HANDLER: ProxyTraps = ProxyTraps {
|
static PROXY_HANDLER: ProxyTraps = ProxyTraps {
|
||||||
getPropertyDescriptor: Some(get_property_descriptor
|
enter: None,
|
||||||
as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool,
|
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
|
||||||
*mut JSPropertyDescriptor) -> bool),
|
defineProperty: Some(defineProperty),
|
||||||
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor
|
ownPropertyKeys: None,
|
||||||
as unsafe extern "C" fn(*mut JSContext, *mut JSObject,
|
|
||||||
jsid, bool, *mut JSPropertyDescriptor)
|
|
||||||
-> bool),
|
|
||||||
defineProperty: Some(defineProperty as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid,
|
|
||||||
*mut JSPropertyDescriptor) -> bool),
|
|
||||||
getOwnPropertyNames: None,
|
|
||||||
delete_: None,
|
delete_: None,
|
||||||
enumerate: None,
|
enumerate: None,
|
||||||
|
preventExtensions: None,
|
||||||
|
isExtensible: None,
|
||||||
has: None,
|
has: None,
|
||||||
hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool),
|
get: Some(get),
|
||||||
get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool),
|
set: Some(set),
|
||||||
set: Some(set as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject,
|
|
||||||
jsid, bool, *mut JSVal) -> bool),
|
|
||||||
keys: None,
|
|
||||||
iterate: None,
|
|
||||||
|
|
||||||
call: None,
|
call: None,
|
||||||
construct: None,
|
construct: None,
|
||||||
nativeCall: 0 as *const u8,
|
getPropertyDescriptor: Some(get_property_descriptor),
|
||||||
|
hasOwn: Some(hasOwn),
|
||||||
|
getOwnEnumerablePropertyKeys: None,
|
||||||
|
nativeCall: None,
|
||||||
hasInstance: None,
|
hasInstance: None,
|
||||||
typeOf: None,
|
|
||||||
objectClassIs: None,
|
objectClassIs: None,
|
||||||
obj_toString: None,
|
className: None,
|
||||||
fun_toString: None,
|
fun_toString: None,
|
||||||
//regexp_toShared: 0 as *u8,
|
boxedValue_unbox: None,
|
||||||
defaultValue: None,
|
defaultValue: None,
|
||||||
iteratorNext: None,
|
trace: None,
|
||||||
finalize: None,
|
finalize: None,
|
||||||
getElementIfPresent: None,
|
objectMoved: None,
|
||||||
getPrototypeOf: None,
|
isCallable: None,
|
||||||
trace: None
|
isConstructor: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::CanvasGradientBinding;
|
use dom::bindings::codegen::Bindings::CanvasGradientBinding;
|
||||||
use dom::bindings::codegen::Bindings::CanvasGradientBinding::CanvasGradientMethods;
|
use dom::bindings::codegen::Bindings::CanvasGradientBinding::CanvasGradientMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasrenderingcontext2d::parse_color;
|
use dom::canvasrenderingcontext2d::parse_color;
|
||||||
|
@ -37,13 +37,13 @@ impl CanvasGradient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef, style: CanvasGradientStyle) -> Temporary<CanvasGradient> {
|
pub fn new(global: GlobalRef, style: CanvasGradientStyle) -> Root<CanvasGradient> {
|
||||||
reflect_dom_object(box CanvasGradient::new_inherited(style),
|
reflect_dom_object(box CanvasGradient::new_inherited(style),
|
||||||
global, CanvasGradientBinding::Wrap)
|
global, CanvasGradientBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> {
|
impl<'a> CanvasGradientMethods for &'a CanvasGradient {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
|
// https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
|
||||||
fn AddColorStop(self, offset: Finite<f64>, color: String) {
|
fn AddColorStop(self, offset: Finite<f64>, color: String) {
|
||||||
let default_black = RGBA {
|
let default_black = RGBA {
|
||||||
|
@ -61,11 +61,11 @@ impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToFillOrStrokeStyle {
|
pub trait ToFillOrStrokeStyle {
|
||||||
fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle;
|
fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToFillOrStrokeStyle for JSRef<'a, CanvasGradient> {
|
impl<'a> ToFillOrStrokeStyle for &'a CanvasGradient {
|
||||||
fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle {
|
fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle {
|
||||||
let gradient_stops = self.stops.borrow().clone();
|
let gradient_stops = self.stops.borrow().clone();
|
||||||
match self.style {
|
match self.style {
|
||||||
CanvasGradientStyle::Linear(ref gradient) => {
|
CanvasGradientStyle::Linear(ref gradient) => {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use canvas_traits::{FillOrStrokeStyle, SurfaceStyle, RepetitionStyle};
|
use canvas_traits::{FillOrStrokeStyle, SurfaceStyle, RepetitionStyle};
|
||||||
use dom::bindings::codegen::Bindings::CanvasPatternBinding;
|
use dom::bindings::codegen::Bindings::CanvasPatternBinding;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasgradient::ToFillOrStrokeStyle;
|
use dom::canvasgradient::ToFillOrStrokeStyle;
|
||||||
use euclid::size::Size2D;
|
use euclid::size::Size2D;
|
||||||
|
@ -41,14 +41,14 @@ impl CanvasPattern {
|
||||||
surface_data: Vec<u8>,
|
surface_data: Vec<u8>,
|
||||||
surface_size: Size2D<i32>,
|
surface_size: Size2D<i32>,
|
||||||
repeat: RepetitionStyle)
|
repeat: RepetitionStyle)
|
||||||
-> Temporary<CanvasPattern> {
|
-> Root<CanvasPattern> {
|
||||||
reflect_dom_object(box CanvasPattern::new_inherited(surface_data, surface_size, repeat),
|
reflect_dom_object(box CanvasPattern::new_inherited(surface_data, surface_size, repeat),
|
||||||
global, CanvasPatternBinding::Wrap)
|
global, CanvasPatternBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToFillOrStrokeStyle for JSRef<'a, CanvasPattern> {
|
impl<'a> ToFillOrStrokeStyle for &'a CanvasPattern {
|
||||||
fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle {
|
fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle {
|
||||||
FillOrStrokeStyle::Surface(
|
FillOrStrokeStyle::Surface(
|
||||||
SurfaceStyle::new(self.surface_data.clone(), self.surface_size, self.repeat_x, self.repeat_y))
|
SurfaceStyle::new(self.surface_data.clone(), self.surface_size, self.repeat_x, self.repeat_y))
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
|
||||||
use dom::bindings::error::Error::{IndexSize, NotSupported, Type, InvalidState, Syntax};
|
use dom::bindings::error::Error::{IndexSize, NotSupported, Type, InvalidState, Syntax};
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary, Unrooted};
|
use dom::bindings::js::{JS, LayoutJS, Root};
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
|
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
|
||||||
|
@ -115,20 +115,20 @@ impl CanvasContextState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CanvasRenderingContext2D {
|
impl CanvasRenderingContext2D {
|
||||||
fn new_inherited(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
|
fn new_inherited(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>)
|
||||||
-> CanvasRenderingContext2D {
|
-> CanvasRenderingContext2D {
|
||||||
CanvasRenderingContext2D {
|
CanvasRenderingContext2D {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
global: GlobalField::from_rooted(&global),
|
global: GlobalField::from_rooted(&global),
|
||||||
renderer: CanvasPaintTask::start(size),
|
renderer: CanvasPaintTask::start(size),
|
||||||
canvas: JS::from_rooted(canvas),
|
canvas: JS::from_ref(canvas),
|
||||||
state: RefCell::new(CanvasContextState::new()),
|
state: RefCell::new(CanvasContextState::new()),
|
||||||
saved_states: RefCell::new(Vec::new()),
|
saved_states: RefCell::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>)
|
pub fn new(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>)
|
||||||
-> Temporary<CanvasRenderingContext2D> {
|
-> Root<CanvasRenderingContext2D> {
|
||||||
reflect_dom_object(box CanvasRenderingContext2D::new_inherited(global, canvas, size),
|
reflect_dom_object(box CanvasRenderingContext2D::new_inherited(global, canvas, size),
|
||||||
global, CanvasRenderingContext2DBinding::Wrap)
|
global, CanvasRenderingContext2DBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ impl CanvasRenderingContext2D {
|
||||||
//
|
//
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
||||||
fn draw_html_canvas_element(&self,
|
fn draw_html_canvas_element(&self,
|
||||||
canvas: JSRef<HTMLCanvasElement>,
|
canvas: &HTMLCanvasElement,
|
||||||
sx: f64, sy: f64, sw: f64, sh: f64,
|
sx: f64, sy: f64, sw: f64, sh: f64,
|
||||||
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
|
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
|
||||||
// 1. Check the usability of the image argument
|
// 1. Check the usability of the image argument
|
||||||
|
@ -235,7 +235,7 @@ impl CanvasRenderingContext2D {
|
||||||
CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageSelf(image_size, dest_rect, source_rect, smoothing_enabled))
|
CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageSelf(image_size, dest_rect, source_rect, smoothing_enabled))
|
||||||
} else { // Source and target canvases are different
|
} else { // Source and target canvases are different
|
||||||
let context = match canvas.get_or_init_2d_context() {
|
let context = match canvas.get_or_init_2d_context() {
|
||||||
Some(context) => context.root(),
|
Some(context) => context,
|
||||||
None => return Err(InvalidState),
|
None => return Err(InvalidState),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ impl CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_image_data(&self,
|
fn fetch_image_data(&self,
|
||||||
image_element: &JSRef<HTMLImageElement>)
|
image_element: &&HTMLImageElement)
|
||||||
-> Option<(Vec<u8>, Size2D<f64>)> {
|
-> Option<(Vec<u8>, Size2D<f64>)> {
|
||||||
let url = match image_element.get_url() {
|
let url = match image_element.get_url() {
|
||||||
Some(url) => url,
|
Some(url) => url,
|
||||||
|
@ -302,7 +302,7 @@ impl CanvasRenderingContext2D {
|
||||||
|
|
||||||
fn request_image_from_cache(&self, url: Url) -> ImageResponse {
|
fn request_image_from_cache(&self, url: Url) -> ImageResponse {
|
||||||
let canvas = self.canvas.root();
|
let canvas = self.canvas.root();
|
||||||
let window = window_from_node(canvas.r()).root();
|
let window = window_from_node(canvas.r());
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let image_cache = window.image_cache_task();
|
let image_cache = window.image_cache_task();
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = channel();
|
||||||
|
@ -325,11 +325,11 @@ impl CanvasRenderingContext2D {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CanvasRenderingContext2DHelpers {
|
pub trait CanvasRenderingContext2DHelpers {
|
||||||
fn get_renderer(&self) -> Sender<CanvasMsg>;
|
fn get_renderer(self) -> Sender<CanvasMsg>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CanvasRenderingContext2DHelpers for CanvasRenderingContext2D {
|
impl<'a> CanvasRenderingContext2DHelpers for &'a CanvasRenderingContext2D {
|
||||||
fn get_renderer(&self) -> Sender<CanvasMsg> {
|
fn get_renderer(self) -> Sender<CanvasMsg> {
|
||||||
self.renderer.clone()
|
self.renderer.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,10 +355,10 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D
|
||||||
// Restricted values are guarded in glue code. Therefore we need not add a guard.
|
// Restricted values are guarded in glue code. Therefore we need not add a guard.
|
||||||
//
|
//
|
||||||
// FIXME: this behavior should might be generated by some annotattions to idl.
|
// FIXME: this behavior should might be generated by some annotattions to idl.
|
||||||
impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> {
|
impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-canvas
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-canvas
|
||||||
fn Canvas(self) -> Temporary<HTMLCanvasElement> {
|
fn Canvas(self) -> Root<HTMLCanvasElement> {
|
||||||
Temporary::from_rooted(self.canvas)
|
self.canvas.root()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save
|
||||||
|
@ -552,8 +552,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
let sy: f64 = 0f64;
|
let sy: f64 = 0f64;
|
||||||
|
|
||||||
match image {
|
match image {
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(canvas) => {
|
||||||
let canvas = image.root();
|
|
||||||
let canvas_size = canvas.r().get_size();
|
let canvas_size = canvas.r().get_size();
|
||||||
let dw: f64 = canvas_size.width as f64;
|
let dw: f64 = canvas_size.width as f64;
|
||||||
let dh: f64 = canvas_size.height as f64;
|
let dh: f64 = canvas_size.height as f64;
|
||||||
|
@ -564,9 +563,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
||||||
let image = image.root();
|
|
||||||
let context = image.r();
|
let context = image.r();
|
||||||
let canvas = context.Canvas().root();
|
let canvas = context.Canvas();
|
||||||
let canvas_size = canvas.r().get_size();
|
let canvas_size = canvas.r().get_size();
|
||||||
let dw: f64 = canvas_size.width as f64;
|
let dw: f64 = canvas_size.width as f64;
|
||||||
let dh: f64 = canvas_size.height as f64;
|
let dh: f64 = canvas_size.height as f64;
|
||||||
|
@ -577,7 +575,6 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
||||||
let image = image.root();
|
|
||||||
let image_element = image.r();
|
let image_element = image.r();
|
||||||
// https://html.spec.whatwg.org/multipage/#img-error
|
// https://html.spec.whatwg.org/multipage/#img-error
|
||||||
// If the image argument is an HTMLImageElement object that is in the broken state,
|
// If the image argument is an HTMLImageElement object that is in the broken state,
|
||||||
|
@ -615,8 +612,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
let sy: f64 = 0f64;
|
let sy: f64 = 0f64;
|
||||||
|
|
||||||
match image {
|
match image {
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(canvas) => {
|
||||||
let canvas = image.root();
|
|
||||||
let canvas_size = canvas.r().get_size();
|
let canvas_size = canvas.r().get_size();
|
||||||
let sw: f64 = canvas_size.width as f64;
|
let sw: f64 = canvas_size.width as f64;
|
||||||
let sh: f64 = canvas_size.height as f64;
|
let sh: f64 = canvas_size.height as f64;
|
||||||
|
@ -625,9 +621,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
||||||
let image = image.root();
|
|
||||||
let context = image.r();
|
let context = image.r();
|
||||||
let canvas = context.Canvas().root();
|
let canvas = context.Canvas();
|
||||||
let canvas_size = canvas.r().get_size();
|
let canvas_size = canvas.r().get_size();
|
||||||
let sw: f64 = canvas_size.width as f64;
|
let sw: f64 = canvas_size.width as f64;
|
||||||
let sh: f64 = canvas_size.height as f64;
|
let sh: f64 = canvas_size.height as f64;
|
||||||
|
@ -636,7 +631,6 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
||||||
let image = image.root();
|
|
||||||
let image_element = image.r();
|
let image_element = image.r();
|
||||||
// https://html.spec.whatwg.org/multipage/#img-error
|
// https://html.spec.whatwg.org/multipage/#img-error
|
||||||
// If the image argument is an HTMLImageElement object that is in the broken state,
|
// If the image argument is an HTMLImageElement object that is in the broken state,
|
||||||
|
@ -666,21 +660,18 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
|
|
||||||
match image {
|
match image {
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => {
|
||||||
let canvas = image.root();
|
return self.draw_html_canvas_element(image.r(),
|
||||||
return self.draw_html_canvas_element(canvas.r(),
|
|
||||||
sx, sy, sw, sh,
|
sx, sy, sw, sh,
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => {
|
||||||
let image = image.root();
|
|
||||||
let context = image.r();
|
let context = image.r();
|
||||||
let canvas = context.Canvas().root();
|
let canvas = context.Canvas();
|
||||||
return self.draw_html_canvas_element(canvas.r(),
|
return self.draw_html_canvas_element(canvas.r(),
|
||||||
sx, sy, sw, sh,
|
sx, sy, sw, sh,
|
||||||
dx, dy, dw, dh)
|
dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
||||||
let image = image.root();
|
|
||||||
let image_element = image.r();
|
let image_element = image.r();
|
||||||
// https://html.spec.whatwg.org/multipage/#img-error
|
// https://html.spec.whatwg.org/multipage/#img-error
|
||||||
// If the image argument is an HTMLImageElement object that is in the broken state,
|
// If the image argument is an HTMLImageElement object that is in the broken state,
|
||||||
|
@ -820,7 +811,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
||||||
},
|
},
|
||||||
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
||||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(Unrooted::from_js(gradient))
|
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -840,11 +831,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => {
|
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => {
|
||||||
let gradient_root = gradient.root();
|
|
||||||
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Gradient(
|
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Gradient(
|
||||||
JS::from_rooted(gradient_root.r()));
|
JS::from_ref(gradient.r()));
|
||||||
let msg = CanvasMsg::Canvas2d(
|
let msg = CanvasMsg::Canvas2d(
|
||||||
Canvas2dMsg::SetStrokeStyle(gradient_root.r().to_fill_or_stroke_style()));
|
Canvas2dMsg::SetStrokeStyle(gradient.r().to_fill_or_stroke_style()));
|
||||||
self.renderer.send(msg).unwrap();
|
self.renderer.send(msg).unwrap();
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -860,7 +850,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
||||||
},
|
},
|
||||||
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
||||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(Unrooted::from_js(gradient))
|
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -880,22 +870,21 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => {
|
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => {
|
||||||
let gradient_root = gradient.root();
|
|
||||||
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Gradient(
|
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Gradient(
|
||||||
JS::from_rooted(gradient_root.r()));
|
JS::from_rooted(&gradient));
|
||||||
let msg = CanvasMsg::Canvas2d(
|
let msg = CanvasMsg::Canvas2d(
|
||||||
Canvas2dMsg::SetFillStyle(gradient_root.r().to_fill_or_stroke_style()));
|
Canvas2dMsg::SetFillStyle(gradient.r().to_fill_or_stroke_style()));
|
||||||
self.renderer.send(msg).unwrap();
|
self.renderer.send(msg).unwrap();
|
||||||
}
|
}
|
||||||
StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => {
|
StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => {
|
||||||
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
|
self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
|
||||||
pattern.root().r().to_fill_or_stroke_style()))).unwrap();
|
pattern.r().to_fill_or_stroke_style()))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||||
fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> {
|
fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Root<ImageData>> {
|
||||||
if !(sw.is_finite() && sh.is_finite()) {
|
if !(sw.is_finite() && sh.is_finite()) {
|
||||||
return Err(NotSupported);
|
return Err(NotSupported);
|
||||||
}
|
}
|
||||||
|
@ -908,7 +897,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||||
fn CreateImageData_(self, imagedata: JSRef<ImageData>) -> Fallible<Temporary<ImageData>> {
|
fn CreateImageData_(self, imagedata: &ImageData) -> Fallible<Root<ImageData>> {
|
||||||
Ok(ImageData::new(self.global.root().r(), imagedata.Width(), imagedata.Height(), None))
|
Ok(ImageData::new(self.global.root().r(), imagedata.Width(), imagedata.Height(), None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +906,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
sx: Finite<f64>,
|
sx: Finite<f64>,
|
||||||
sy: Finite<f64>,
|
sy: Finite<f64>,
|
||||||
sw: Finite<f64>,
|
sw: Finite<f64>,
|
||||||
sh: Finite<f64>) -> Fallible<Temporary<ImageData>> {
|
sh: Finite<f64>) -> Fallible<Root<ImageData>> {
|
||||||
let sx = *sx;
|
let sx = *sx;
|
||||||
let sy = *sy;
|
let sy = *sy;
|
||||||
let sw = *sw;
|
let sw = *sw;
|
||||||
|
@ -938,7 +927,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
||||||
fn PutImageData(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>) {
|
fn PutImageData(self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>) {
|
||||||
let dx = *dx;
|
let dx = *dx;
|
||||||
let dy = *dy;
|
let dy = *dy;
|
||||||
|
|
||||||
|
@ -960,7 +949,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
||||||
fn PutImageData_(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>,
|
fn PutImageData_(self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>,
|
||||||
dirtyX: Finite<f64>, dirtyY: Finite<f64>, dirtyWidth: Finite<f64>, dirtyHeight: Finite<f64>) {
|
dirtyX: Finite<f64>, dirtyY: Finite<f64>, dirtyWidth: Finite<f64>, dirtyHeight: Finite<f64>) {
|
||||||
let dx = *dx;
|
let dx = *dx;
|
||||||
let dy = *dy;
|
let dy = *dy;
|
||||||
|
@ -989,7 +978,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
|
||||||
fn CreateLinearGradient(self, x0: Finite<f64>, y0: Finite<f64>,
|
fn CreateLinearGradient(self, x0: Finite<f64>, y0: Finite<f64>,
|
||||||
x1: Finite<f64>, y1: Finite<f64>) -> Fallible<Temporary<CanvasGradient>> {
|
x1: Finite<f64>, y1: Finite<f64>) -> Fallible<Root<CanvasGradient>> {
|
||||||
let x0 = *x0;
|
let x0 = *x0;
|
||||||
let y0 = *y0;
|
let y0 = *y0;
|
||||||
let x1 = *x1;
|
let x1 = *x1;
|
||||||
|
@ -1006,7 +995,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient
|
||||||
fn CreateRadialGradient(self, x0: Finite<f64>, y0: Finite<f64>, r0: Finite<f64>,
|
fn CreateRadialGradient(self, x0: Finite<f64>, y0: Finite<f64>, r0: Finite<f64>,
|
||||||
x1: Finite<f64>, y1: Finite<f64>, r1: Finite<f64>)
|
x1: Finite<f64>, y1: Finite<f64>, r1: Finite<f64>)
|
||||||
-> Fallible<Temporary<CanvasGradient>> {
|
-> Fallible<Root<CanvasGradient>> {
|
||||||
let x0 = *x0;
|
let x0 = *x0;
|
||||||
let y0 = *y0;
|
let y0 = *y0;
|
||||||
let r0 = *r0;
|
let r0 = *r0;
|
||||||
|
@ -1025,10 +1014,9 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
|
||||||
fn CreatePattern(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
|
fn CreatePattern(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
|
||||||
repetition: DOMString) -> Fallible<Temporary<CanvasPattern>> {
|
repetition: DOMString) -> Fallible<Root<CanvasPattern>> {
|
||||||
match image {
|
match image {
|
||||||
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
|
||||||
let image = image.root();
|
|
||||||
let image_element = image.r();
|
let image_element = image.r();
|
||||||
|
|
||||||
let url = match image_element.get_url() {
|
let url = match image_element.get_url() {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||||
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||||
use dom::bindings::error::{Fallible, ErrorResult};
|
use dom::bindings::error::{Fallible, ErrorResult};
|
||||||
use dom::bindings::error::Error::IndexSize;
|
use dom::bindings::error::Error::IndexSize;
|
||||||
use dom::bindings::js::{JSRef, LayoutJS, Temporary};
|
use dom::bindings::js::{LayoutJS, Root};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -39,7 +39,7 @@ impl CharacterDataDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterData {
|
impl CharacterData {
|
||||||
pub fn new_inherited(id: CharacterDataTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData {
|
pub fn new_inherited(id: CharacterDataTypeId, data: DOMString, document: &Document) -> CharacterData {
|
||||||
CharacterData {
|
CharacterData {
|
||||||
node: Node::new_inherited(NodeTypeId::CharacterData(id), document),
|
node: Node::new_inherited(NodeTypeId::CharacterData(id), document),
|
||||||
data: DOMRefCell::new(data),
|
data: DOMRefCell::new(data),
|
||||||
|
@ -47,7 +47,7 @@ impl CharacterData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
impl<'a> CharacterDataMethods for &'a CharacterData {
|
||||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||||
fn Data(self) -> DOMString {
|
fn Data(self) -> DOMString {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
|
@ -136,20 +136,20 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||||
fn Remove(self) {
|
fn Remove(self) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.remove_self();
|
node.remove_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
fn GetPreviousElementSibling(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).preceding_siblings()
|
NodeCast::from_ref(self).preceding_siblings()
|
||||||
.filter_map(ElementCast::to_temporary).next()
|
.filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
fn GetNextElementSibling(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).following_siblings()
|
NodeCast::from_ref(self).following_siblings()
|
||||||
.filter_map(ElementCast::to_temporary).next()
|
.filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,10 +166,10 @@ pub trait CharacterDataHelpers<'a> {
|
||||||
fn data(self) -> Ref<'a, DOMString>;
|
fn data(self) -> Ref<'a, DOMString>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CharacterDataHelpers<'a> for JSRef<'a, CharacterData> {
|
impl<'a> CharacterDataHelpers<'a> for &'a CharacterData {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn data(self) -> Ref<'a, DOMString> {
|
fn data(self) -> Ref<'a, DOMString> {
|
||||||
self.extended_deref().data.borrow()
|
self.data.borrow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::CloseEventBinding::CloseEventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::EventCast;
|
use dom::bindings::codegen::InheritTypes::EventCast;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary, Rootable};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable};
|
||||||
use script_task::ScriptChan;
|
use script_task::ScriptChan;
|
||||||
|
@ -40,21 +40,23 @@ impl CloseEvent {
|
||||||
cancelable: EventCancelable,
|
cancelable: EventCancelable,
|
||||||
wasClean: bool,
|
wasClean: bool,
|
||||||
code: u16,
|
code: u16,
|
||||||
reason: DOMString) -> Temporary<CloseEvent> {
|
reason: DOMString) -> Root<CloseEvent> {
|
||||||
let event = box CloseEvent::new_inherited(EventTypeId::CloseEvent,
|
let event = box CloseEvent::new_inherited(EventTypeId::CloseEvent,
|
||||||
wasClean, code, reason);
|
wasClean, code, reason);
|
||||||
let ev = reflect_dom_object(event, global, CloseEventBinding::Wrap).root();
|
let ev = reflect_dom_object(event, global, CloseEventBinding::Wrap);
|
||||||
let event: JSRef<Event> = EventCast::from_ref(ev.r());
|
{
|
||||||
event.InitEvent(type_,
|
let event = EventCast::from_ref(ev.r());
|
||||||
bubbles == EventBubbles::Bubbles,
|
event.InitEvent(type_,
|
||||||
cancelable == EventCancelable::Cancelable);
|
bubbles == EventBubbles::Bubbles,
|
||||||
Temporary::from_rooted(ev.r())
|
cancelable == EventCancelable::Cancelable);
|
||||||
|
}
|
||||||
|
ev
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef,
|
pub fn Constructor(global: GlobalRef,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &CloseEventBinding::CloseEventInit)
|
init: &CloseEventBinding::CloseEventInit)
|
||||||
-> Fallible<Temporary<CloseEvent>> {
|
-> Fallible<Root<CloseEvent>> {
|
||||||
let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
|
let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
|
||||||
let cancelable = if init.parent.cancelable {
|
let cancelable = if init.parent.cancelable {
|
||||||
EventCancelable::Cancelable
|
EventCancelable::Cancelable
|
||||||
|
@ -66,7 +68,7 @@ impl CloseEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CloseEventMethods for JSRef<'a, CloseEvent> {
|
impl<'a> CloseEventMethods for &'a CloseEvent {
|
||||||
fn WasClean(self) -> bool {
|
fn WasClean(self) -> bool {
|
||||||
self.wasClean
|
self.wasClean
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::CommentDerived;
|
use dom::bindings::codegen::InheritTypes::CommentDerived;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::characterdata::{CharacterData, CharacterDataTypeId};
|
use dom::characterdata::{CharacterData, CharacterDataTypeId};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -27,19 +27,19 @@ impl CommentDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Comment {
|
impl Comment {
|
||||||
fn new_inherited(text: DOMString, document: JSRef<Document>) -> Comment {
|
fn new_inherited(text: DOMString, document: &Document) -> Comment {
|
||||||
Comment {
|
Comment {
|
||||||
characterdata: CharacterData::new_inherited(CharacterDataTypeId::Comment, text, document)
|
characterdata: CharacterData::new_inherited(CharacterDataTypeId::Comment, text, document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(text: DOMString, document: JSRef<Document>) -> Temporary<Comment> {
|
pub fn new(text: DOMString, document: &Document) -> Root<Comment> {
|
||||||
Node::reflect_node(box Comment::new_inherited(text, document),
|
Node::reflect_node(box Comment::new_inherited(text, document),
|
||||||
document, CommentBinding::Wrap)
|
document, CommentBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef, data: DOMString) -> Fallible<Temporary<Comment>> {
|
pub fn Constructor(global: GlobalRef, data: DOMString) -> Fallible<Root<Comment>> {
|
||||||
let document = global.as_window().Document().root();
|
let document = global.as_window().Document();
|
||||||
Ok(Comment::new(data, document.r()))
|
Ok(Comment::new(data, document.r()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::ConsoleBinding;
|
use dom::bindings::codegen::Bindings::ConsoleBinding;
|
||||||
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
|
||||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::window::WindowHelpers;
|
use dom::window::WindowHelpers;
|
||||||
use devtools_traits::{DevtoolsControlMsg, ConsoleMessage, LogLevel};
|
use devtools_traits::{DevtoolsControlMsg, ConsoleMessage, LogLevel};
|
||||||
|
@ -26,12 +26,12 @@ impl Console {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef) -> Temporary<Console> {
|
pub fn new(global: GlobalRef) -> Root<Console> {
|
||||||
reflect_dom_object(box Console::new_inherited(global), global, ConsoleBinding::Wrap)
|
reflect_dom_object(box Console::new_inherited(global), global, ConsoleBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ConsoleMethods for JSRef<'a, Console> {
|
impl<'a> ConsoleMethods for &'a Console {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Console/log
|
// https://developer.mozilla.org/en-US/docs/Web/API/Console/log
|
||||||
fn Log(self, messages: Vec<DOMString>) {
|
fn Log(self, messages: Vec<DOMString>) {
|
||||||
for message in messages {
|
for message in messages {
|
||||||
|
@ -95,7 +95,7 @@ fn prepare_message(logLevel: LogLevel, message: String) -> ConsoleMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagate_console_msg(console: &JSRef<Console>, console_message: ConsoleMessage) {
|
fn propagate_console_msg(console: &&Console, console_message: ConsoleMessage) {
|
||||||
let global = console.global.root();
|
let global = console.global.root();
|
||||||
match global.r() {
|
match global.r() {
|
||||||
GlobalRef::Window(window_ref) => {
|
GlobalRef::Window(window_ref) => {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::codegen::InheritTypes::ElementCast;
|
use dom::bindings::codegen::InheritTypes::ElementCast;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::element::ElementCreator;
|
use dom::element::ElementCreator;
|
||||||
|
@ -81,8 +81,8 @@ use string_cache::{Atom, QualName};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
||||||
pub fn create_element(name: QualName, prefix: Option<Atom>,
|
pub fn create_element(name: QualName, prefix: Option<Atom>,
|
||||||
document: JSRef<Document>, creator: ElementCreator)
|
document: &Document, creator: ElementCreator)
|
||||||
-> Temporary<Element> {
|
-> Root<Element> {
|
||||||
let prefix = prefix.map(|p| (*p).to_owned());
|
let prefix = prefix.map(|p| (*p).to_owned());
|
||||||
|
|
||||||
if name.ns != ns!(HTML) {
|
if name.ns != ns!(HTML) {
|
||||||
|
@ -92,11 +92,11 @@ pub fn create_element(name: QualName, prefix: Option<Atom>,
|
||||||
macro_rules! make(
|
macro_rules! make(
|
||||||
($ctor:ident) => ({
|
($ctor:ident) => ({
|
||||||
let obj = $ctor::new((*name.local).to_owned(), prefix, document);
|
let obj = $ctor::new((*name.local).to_owned(), prefix, document);
|
||||||
ElementCast::from_temporary(obj)
|
ElementCast::from_root(obj)
|
||||||
});
|
});
|
||||||
($ctor:ident, $($arg:expr),+) => ({
|
($ctor:ident, $($arg:expr),+) => ({
|
||||||
let obj = $ctor::new((*name.local).to_owned(), prefix, document, $($arg),+);
|
let obj = $ctor::new((*name.local).to_owned(), prefix, document, $($arg),+);
|
||||||
ElementCast::from_temporary(obj)
|
ElementCast::from_root(obj)
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyl
|
||||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
|
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::document::DocumentHelpers;
|
use dom::document::DocumentHelpers;
|
||||||
use dom::element::{Element, ElementHelpers, StylePriority};
|
use dom::element::{ElementHelpers, StylePriority};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{window_from_node, document_from_node, NodeDamage, Node};
|
use dom::node::{window_from_node, document_from_node, NodeDamage};
|
||||||
use dom::window::{Window, WindowHelpers};
|
use dom::window::{Window, WindowHelpers};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
@ -55,17 +55,17 @@ fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSSStyleDeclaration {
|
impl CSSStyleDeclaration {
|
||||||
pub fn new_inherited(owner: JSRef<HTMLElement>,
|
pub fn new_inherited(owner: &HTMLElement,
|
||||||
modification_access: CSSModificationAccess) -> CSSStyleDeclaration {
|
modification_access: CSSModificationAccess) -> CSSStyleDeclaration {
|
||||||
CSSStyleDeclaration {
|
CSSStyleDeclaration {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
owner: JS::from_rooted(owner),
|
owner: JS::from_ref(owner),
|
||||||
readonly: modification_access == CSSModificationAccess::Readonly,
|
readonly: modification_access == CSSModificationAccess::Readonly,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>,
|
pub fn new(global: &Window, owner: &HTMLElement,
|
||||||
modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> {
|
modification_access: CSSModificationAccess) -> Root<CSSStyleDeclaration> {
|
||||||
reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner, modification_access),
|
reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner, modification_access),
|
||||||
GlobalRef::Window(global),
|
GlobalRef::Window(global),
|
||||||
CSSStyleDeclarationBinding::Wrap)
|
CSSStyleDeclarationBinding::Wrap)
|
||||||
|
@ -77,25 +77,25 @@ trait PrivateCSSStyleDeclarationHelpers {
|
||||||
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> {
|
impl<'a> PrivateCSSStyleDeclarationHelpers for &'a CSSStyleDeclaration {
|
||||||
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let element = ElementCast::from_ref(owner.r());
|
||||||
element.get_inline_style_declaration(property).map(|decl| decl.clone())
|
element.get_inline_style_declaration(property).map(|decl| decl.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let element = ElementCast::from_ref(owner.r());
|
||||||
element.get_important_inline_style_declaration(property).map(|decl| decl.clone())
|
element.get_important_inline_style_declaration(property).map(|decl| decl.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
|
||||||
// http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
|
// http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
|
||||||
fn Length(self) -> u32 {
|
fn Length(self) -> u32 {
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let elem = ElementCast::from_ref(owner.r());
|
||||||
let len = match *elem.style_attribute().borrow() {
|
let len = match *elem.style_attribute().borrow() {
|
||||||
Some(ref declarations) => declarations.normal.len() + declarations.important.len(),
|
Some(ref declarations) => declarations.normal.len() + declarations.important.len(),
|
||||||
None => 0
|
None => 0
|
||||||
|
@ -107,7 +107,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
fn Item(self, index: u32) -> DOMString {
|
fn Item(self, index: u32) -> DOMString {
|
||||||
let index = index as usize;
|
let index = index as usize;
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let elem = ElementCast::from_ref(owner.r());
|
||||||
let style_attribute = elem.style_attribute().borrow();
|
let style_attribute = elem.style_attribute().borrow();
|
||||||
let result = style_attribute.as_ref().and_then(|declarations| {
|
let result = style_attribute.as_ref().and_then(|declarations| {
|
||||||
if index > declarations.normal.len() {
|
if index > declarations.normal.len() {
|
||||||
|
@ -216,7 +216,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
synthesized_declaration.push_str(&value);
|
synthesized_declaration.push_str(&value);
|
||||||
|
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let window = window_from_node(owner.r()).root();
|
let window = window_from_node(owner.r());
|
||||||
let decl_block = parse_style_attribute(&synthesized_declaration, &window.r().get_url());
|
let decl_block = parse_style_attribute(&synthesized_declaration, &window.r().get_url());
|
||||||
|
|
||||||
// Step 7
|
// Step 7
|
||||||
|
@ -225,7 +225,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let element = ElementCast::from_ref(owner.r());
|
||||||
|
|
||||||
// Step 8
|
// Step 8
|
||||||
for decl in decl_block.normal.iter() {
|
for decl in decl_block.normal.iter() {
|
||||||
|
@ -238,8 +238,8 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
element.update_inline_style(decl.clone(), style_priority);
|
element.update_inline_style(decl.clone(), style_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
let document = document_from_node(element).root();
|
let document = document_from_node(element);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(element);
|
let node = NodeCast::from_ref(element);
|
||||||
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -266,9 +266,9 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let window = window_from_node(owner.r()).root();
|
let window = window_from_node(owner.r());
|
||||||
let decl_block = parse_style_attribute(&property, &window.r().get_url());
|
let decl_block = parse_style_attribute(&property, &window.r().get_url());
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let element = ElementCast::from_ref(owner.r());
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
for decl in decl_block.normal.iter() {
|
for decl in decl_block.normal.iter() {
|
||||||
|
@ -281,8 +281,8 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
element.update_inline_style(decl.clone(), style_priority);
|
element.update_inline_style(decl.clone(), style_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
let document = document_from_node(element).root();
|
let document = document_from_node(element);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(element);
|
let node = NodeCast::from_ref(element);
|
||||||
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> {
|
||||||
None => {
|
None => {
|
||||||
// Step 5
|
// Step 5
|
||||||
let owner = self.owner.root();
|
let owner = self.owner.root();
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(owner.r());
|
let elem = ElementCast::from_ref(owner.r());
|
||||||
elem.remove_inline_style_property(property)
|
elem.remove_inline_style_property(property)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,18 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, CustomEventDerived};
|
use dom::bindings::codegen::InheritTypes::{EventCast, CustomEventDerived};
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, MutHeap, Rootable, Temporary};
|
use dom::bindings::js::{Root, MutHeapJSVal};
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::event::{Event, EventTypeId};
|
use dom::event::{Event, EventTypeId};
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::{JSContext, HandleValue};
|
||||||
use js::jsval::{JSVal, NullValue};
|
use js::jsval::JSVal;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#interface-customevent
|
// https://dom.spec.whatwg.org/#interface-customevent
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct CustomEvent {
|
pub struct CustomEvent {
|
||||||
event: Event,
|
event: Event,
|
||||||
detail: MutHeap<JSVal>,
|
detail: MutHeapJSVal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CustomEventDerived for Event {
|
impl CustomEventDerived for Event {
|
||||||
|
@ -32,11 +32,11 @@ impl CustomEvent {
|
||||||
fn new_inherited(type_id: EventTypeId) -> CustomEvent {
|
fn new_inherited(type_id: EventTypeId) -> CustomEvent {
|
||||||
CustomEvent {
|
CustomEvent {
|
||||||
event: Event::new_inherited(type_id),
|
event: Event::new_inherited(type_id),
|
||||||
detail: MutHeap::new(NullValue()),
|
detail: MutHeapJSVal::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_uninitialized(global: GlobalRef) -> Temporary<CustomEvent> {
|
pub fn new_uninitialized(global: GlobalRef) -> Root<CustomEvent> {
|
||||||
reflect_dom_object(box CustomEvent::new_inherited(EventTypeId::CustomEvent),
|
reflect_dom_object(box CustomEvent::new_inherited(EventTypeId::CustomEvent),
|
||||||
global,
|
global,
|
||||||
CustomEventBinding::Wrap)
|
CustomEventBinding::Wrap)
|
||||||
|
@ -45,19 +45,23 @@ impl CustomEvent {
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
bubbles: bool,
|
bubbles: bool,
|
||||||
cancelable: bool,
|
cancelable: bool,
|
||||||
detail: JSVal) -> Temporary<CustomEvent> {
|
detail: HandleValue) -> Root<CustomEvent> {
|
||||||
let ev = CustomEvent::new_uninitialized(global).root();
|
let ev = CustomEvent::new_uninitialized(global);
|
||||||
ev.r().InitCustomEvent(global.get_cx(), type_, bubbles, cancelable, detail);
|
ev.r().InitCustomEvent(global.get_cx(), type_, bubbles, cancelable, detail);
|
||||||
Temporary::from_rooted(ev.r())
|
ev
|
||||||
}
|
}
|
||||||
pub fn Constructor(global: GlobalRef,
|
pub fn Constructor(global: GlobalRef,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &CustomEventBinding::CustomEventInit) -> Fallible<Temporary<CustomEvent>>{
|
init: &CustomEventBinding::CustomEventInit) -> Fallible<Root<CustomEvent>>{
|
||||||
Ok(CustomEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable, init.detail))
|
Ok(CustomEvent::new(global,
|
||||||
|
type_,
|
||||||
|
init.parent.bubbles,
|
||||||
|
init.parent.cancelable,
|
||||||
|
HandleValue { ptr: &init.detail }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CustomEventMethods for JSRef<'a, CustomEvent> {
|
impl<'a> CustomEventMethods for &'a CustomEvent {
|
||||||
// https://dom.spec.whatwg.org/#dom-customevent-detail
|
// https://dom.spec.whatwg.org/#dom-customevent-detail
|
||||||
fn Detail(self, _cx: *mut JSContext) -> JSVal {
|
fn Detail(self, _cx: *mut JSContext) -> JSVal {
|
||||||
self.detail.get()
|
self.detail.get()
|
||||||
|
@ -69,13 +73,13 @@ impl<'a> CustomEventMethods for JSRef<'a, CustomEvent> {
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
can_bubble: bool,
|
can_bubble: bool,
|
||||||
cancelable: bool,
|
cancelable: bool,
|
||||||
detail: JSVal) {
|
detail: HandleValue) {
|
||||||
let event: JSRef<Event> = EventCast::from_ref(self);
|
let event = EventCast::from_ref(self);
|
||||||
if event.dispatching() {
|
if event.dispatching() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.detail.set(detail);
|
self.detail.set(detail.get());
|
||||||
event.InitEvent(type_, can_bubble, cancelable);
|
event.InitEvent(type_, can_bubble, cancelable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods;
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived;
|
use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast};
|
use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast};
|
||||||
use dom::bindings::error::ErrorResult;
|
use dom::bindings::error::{ErrorResult, report_pending_exception};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, RootCollection, Rootable, Temporary};
|
use dom::bindings::js::{RootCollection, Root};
|
||||||
use dom::bindings::refcounted::LiveDOMReferences;
|
use dom::bindings::refcounted::LiveDOMReferences;
|
||||||
use dom::bindings::structuredclone::StructuredCloneData;
|
use dom::bindings::structuredclone::StructuredCloneData;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::utils::Reflectable;
|
||||||
|
@ -33,8 +33,9 @@ use util::task::spawn_named;
|
||||||
use util::task_state;
|
use util::task_state;
|
||||||
use util::task_state::{SCRIPT, IN_WORKER};
|
use util::task_state::{SCRIPT, IN_WORKER};
|
||||||
|
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::{JSContext, RootedValue, HandleValue};
|
||||||
use js::jsval::JSVal;
|
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -69,12 +70,12 @@ impl ScriptChan for SendableWorkerScriptChan {
|
||||||
/// object only lives as long as necessary (ie. while events are being executed), while
|
/// object only lives as long as necessary (ie. while events are being executed), while
|
||||||
/// providing a reference that can be cloned freely.
|
/// providing a reference that can be cloned freely.
|
||||||
struct AutoWorkerReset<'a> {
|
struct AutoWorkerReset<'a> {
|
||||||
workerscope: JSRef<'a, DedicatedWorkerGlobalScope>,
|
workerscope: &'a DedicatedWorkerGlobalScope,
|
||||||
old_worker: Option<TrustedWorkerAddress>,
|
old_worker: Option<TrustedWorkerAddress>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AutoWorkerReset<'a> {
|
impl<'a> AutoWorkerReset<'a> {
|
||||||
fn new(workerscope: JSRef<'a, DedicatedWorkerGlobalScope>, worker: TrustedWorkerAddress) -> AutoWorkerReset<'a> {
|
fn new(workerscope: &'a DedicatedWorkerGlobalScope, worker: TrustedWorkerAddress) -> AutoWorkerReset<'a> {
|
||||||
let reset = AutoWorkerReset {
|
let reset = AutoWorkerReset {
|
||||||
workerscope: workerscope,
|
workerscope: workerscope,
|
||||||
old_worker: workerscope.worker.borrow().clone()
|
old_worker: workerscope.worker.borrow().clone()
|
||||||
|
@ -132,7 +133,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
parent_sender: Box<ScriptChan+Send>,
|
parent_sender: Box<ScriptChan+Send>,
|
||||||
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
|
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
|
||||||
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
|
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
|
||||||
-> Temporary<DedicatedWorkerGlobalScope> {
|
-> Root<DedicatedWorkerGlobalScope> {
|
||||||
let scope = box DedicatedWorkerGlobalScope::new_inherited(
|
let scope = box DedicatedWorkerGlobalScope::new_inherited(
|
||||||
worker_url, id, devtools_chan, runtime.clone(), resource_task,
|
worker_url, id, devtools_chan, runtime.clone(), resource_task,
|
||||||
parent_sender, own_sender, receiver);
|
parent_sender, own_sender, receiver);
|
||||||
|
@ -170,7 +171,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
|
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
|
||||||
let global = DedicatedWorkerGlobalScope::new(
|
let global = DedicatedWorkerGlobalScope::new(
|
||||||
worker_url, id, devtools_chan, runtime.clone(), resource_task,
|
worker_url, id, devtools_chan, runtime.clone(), resource_task,
|
||||||
parent_sender, own_sender, receiver).root();
|
parent_sender, own_sender, receiver);
|
||||||
|
|
||||||
{
|
{
|
||||||
let _ar = AutoWorkerReset::new(global.r(), worker);
|
let _ar = AutoWorkerReset::new(global.r(), worker);
|
||||||
|
@ -178,7 +179,13 @@ impl DedicatedWorkerGlobalScope {
|
||||||
match runtime.evaluate_script(
|
match runtime.evaluate_script(
|
||||||
global.r().reflector().get_jsobject(), source, url.serialize(), 1) {
|
global.r().reflector().get_jsobject(), source, url.serialize(), 1) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => println!("evaluate_script failed")
|
Err(_) => {
|
||||||
|
// TODO: An error needs to be dispatched to the parent.
|
||||||
|
// https://github.com/servo/servo/issues/6422
|
||||||
|
println!("evaluate_script failed");
|
||||||
|
let _ar = JSAutoRequest::new(runtime.cx());
|
||||||
|
report_pending_exception(runtime.cx(), global.r().reflector().get_jsobject().get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +209,7 @@ pub trait DedicatedWorkerGlobalScopeHelpers {
|
||||||
fn process_event(self, msg: ScriptMsg);
|
fn process_event(self, msg: ScriptMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> {
|
impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
|
||||||
fn script_chan(self) -> Box<ScriptChan+Send> {
|
fn script_chan(self) -> Box<ScriptChan+Send> {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let worker = self.worker.borrow();
|
let worker = self.worker.borrow();
|
||||||
|
@ -232,34 +239,37 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalSc
|
||||||
|
|
||||||
trait PrivateDedicatedWorkerGlobalScopeHelpers {
|
trait PrivateDedicatedWorkerGlobalScopeHelpers {
|
||||||
fn handle_event(self, msg: ScriptMsg);
|
fn handle_event(self, msg: ScriptMsg);
|
||||||
fn dispatch_error_to_worker(self, JSRef<ErrorEvent>);
|
fn dispatch_error_to_worker(self, &ErrorEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> {
|
impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
|
||||||
fn handle_event(self, msg: ScriptMsg) {
|
fn handle_event(self, msg: ScriptMsg) {
|
||||||
match msg {
|
match msg {
|
||||||
ScriptMsg::DOMMessage(data) => {
|
ScriptMsg::DOMMessage(data) => {
|
||||||
let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self);
|
let scope = WorkerGlobalScopeCast::from_ref(self);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
let message = data.read(GlobalRef::Worker(scope));
|
let _ar = JSAutoRequest::new(scope.get_cx());
|
||||||
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message);
|
let _ac = JSAutoCompartment::new(scope.get_cx(), scope.reflector().get_jsobject().get());
|
||||||
|
let mut message = RootedValue::new(scope.get_cx(), UndefinedValue());
|
||||||
|
data.read(GlobalRef::Worker(scope), message.handle_mut());
|
||||||
|
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
|
||||||
},
|
},
|
||||||
ScriptMsg::RunnableMsg(runnable) => {
|
ScriptMsg::RunnableMsg(runnable) => {
|
||||||
runnable.handler()
|
runnable.handler()
|
||||||
},
|
},
|
||||||
ScriptMsg::RefcountCleanup(addr) => {
|
ScriptMsg::RefcountCleanup(addr) => {
|
||||||
let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self);
|
let scope = WorkerGlobalScopeCast::from_ref(self);
|
||||||
LiveDOMReferences::cleanup(scope.get_cx(), addr);
|
LiveDOMReferences::cleanup(scope.get_cx(), addr);
|
||||||
}
|
}
|
||||||
ScriptMsg::FireTimer(TimerSource::FromWorker, timer_id) => {
|
ScriptMsg::FireTimer(TimerSource::FromWorker, timer_id) => {
|
||||||
let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self);
|
let scope = WorkerGlobalScopeCast::from_ref(self);
|
||||||
scope.handle_fire_timer(timer_id);
|
scope.handle_fire_timer(timer_id);
|
||||||
}
|
}
|
||||||
_ => panic!("Unexpected message"),
|
_ => panic!("Unexpected message"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_error_to_worker(self, errorevent: JSRef<ErrorEvent>) {
|
fn dispatch_error_to_worker(self, errorevent: &ErrorEvent) {
|
||||||
let msg = errorevent.Message();
|
let msg = errorevent.Message();
|
||||||
let file_name = errorevent.Filename();
|
let file_name = errorevent.Filename();
|
||||||
let line_num = errorevent.Lineno();
|
let line_num = errorevent.Lineno();
|
||||||
|
@ -270,9 +280,9 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> {
|
impl<'a> DedicatedWorkerGlobalScopeMethods for &'a DedicatedWorkerGlobalScope {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
|
// https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
|
||||||
fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult {
|
fn PostMessage(self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
|
||||||
let data = try!(StructuredCloneData::write(cx, message));
|
let data = try!(StructuredCloneData::write(cx, message));
|
||||||
let worker = self.worker.borrow().as_ref().unwrap().clone();
|
let worker = self.worker.borrow().as_ref().unwrap().clone();
|
||||||
self.parent_sender.send(ScriptMsg::RunnableMsg(
|
self.parent_sender.send(ScriptMsg::RunnableMsg(
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::DocumentFragmentDerived;
|
use dom::bindings::codegen::InheritTypes::DocumentFragmentDerived;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
|
||||||
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
|
@ -33,40 +33,39 @@ impl DocumentFragmentDerived for EventTarget {
|
||||||
|
|
||||||
impl DocumentFragment {
|
impl DocumentFragment {
|
||||||
/// Creates a new DocumentFragment.
|
/// Creates a new DocumentFragment.
|
||||||
fn new_inherited(document: JSRef<Document>) -> DocumentFragment {
|
fn new_inherited(document: &Document) -> DocumentFragment {
|
||||||
DocumentFragment {
|
DocumentFragment {
|
||||||
node: Node::new_inherited(NodeTypeId::DocumentFragment, document),
|
node: Node::new_inherited(NodeTypeId::DocumentFragment, document),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(document: JSRef<Document>) -> Temporary<DocumentFragment> {
|
pub fn new(document: &Document) -> Root<DocumentFragment> {
|
||||||
Node::reflect_node(box DocumentFragment::new_inherited(document),
|
Node::reflect_node(box DocumentFragment::new_inherited(document),
|
||||||
document, DocumentFragmentBinding::Wrap)
|
document, DocumentFragmentBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<DocumentFragment>> {
|
pub fn Constructor(global: GlobalRef) -> Fallible<Root<DocumentFragment>> {
|
||||||
let document = global.as_window().Document();
|
let document = global.as_window().Document();
|
||||||
let document = document.root();
|
|
||||||
|
|
||||||
Ok(DocumentFragment::new(document.r()))
|
Ok(DocumentFragment::new(document.r()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> {
|
impl<'a> DocumentFragmentMethods for &'a DocumentFragment {
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-children
|
// https://dom.spec.whatwg.org/#dom-parentnode-children
|
||||||
fn Children(self) -> Temporary<HTMLCollection> {
|
fn Children(self) -> Root<HTMLCollection> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
|
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
|
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
|
||||||
fn GetFirstElementChild(self) -> Option<Temporary<Element>> {
|
fn GetFirstElementChild(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).child_elements().next()
|
NodeCast::from_ref(self).child_elements().next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
|
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
|
||||||
fn GetLastElementChild(self) -> Option<Temporary<Element>> {
|
fn GetLastElementChild(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_temporary).next()
|
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
|
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
|
||||||
|
@ -85,14 +84,14 @@ impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
||||||
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
root.query_selector(selectors)
|
root.query_selector(selectors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||||
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
root.query_selector_all(selectors)
|
root.query_selector_all(selectors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DocumentTypeBinding::DocumentTypeMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{DocumentTypeDerived, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{DocumentTypeDerived, NodeCast};
|
||||||
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
use dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||||
use dom::bindings::error::ErrorResult;
|
use dom::bindings::error::ErrorResult;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::node::{Node, NodeHelpers, NodeTypeId};
|
use dom::node::{Node, NodeHelpers, NodeTypeId};
|
||||||
|
@ -35,7 +35,7 @@ impl DocumentType {
|
||||||
fn new_inherited(name: DOMString,
|
fn new_inherited(name: DOMString,
|
||||||
public_id: Option<DOMString>,
|
public_id: Option<DOMString>,
|
||||||
system_id: Option<DOMString>,
|
system_id: Option<DOMString>,
|
||||||
document: JSRef<Document>)
|
document: &Document)
|
||||||
-> DocumentType {
|
-> DocumentType {
|
||||||
DocumentType {
|
DocumentType {
|
||||||
node: Node::new_inherited(NodeTypeId::DocumentType, document),
|
node: Node::new_inherited(NodeTypeId::DocumentType, document),
|
||||||
|
@ -48,8 +48,8 @@ impl DocumentType {
|
||||||
pub fn new(name: DOMString,
|
pub fn new(name: DOMString,
|
||||||
public_id: Option<DOMString>,
|
public_id: Option<DOMString>,
|
||||||
system_id: Option<DOMString>,
|
system_id: Option<DOMString>,
|
||||||
document: JSRef<Document>)
|
document: &Document)
|
||||||
-> Temporary<DocumentType> {
|
-> Root<DocumentType> {
|
||||||
let documenttype = DocumentType::new_inherited(name,
|
let documenttype = DocumentType::new_inherited(name,
|
||||||
public_id,
|
public_id,
|
||||||
system_id,
|
system_id,
|
||||||
|
@ -73,7 +73,7 @@ impl DocumentType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DocumentTypeMethods for JSRef<'a, DocumentType> {
|
impl<'a> DocumentTypeMethods for &'a DocumentType {
|
||||||
// https://dom.spec.whatwg.org/#dom-documenttype-name
|
// https://dom.spec.whatwg.org/#dom-documenttype-name
|
||||||
fn Name(self) -> DOMString {
|
fn Name(self) -> DOMString {
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
|
@ -106,7 +106,7 @@ impl<'a> DocumentTypeMethods for JSRef<'a, DocumentType> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||||
fn Remove(self) {
|
fn Remove(self) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.remove_self();
|
node.remove_self();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding;
|
||||||
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants;
|
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants;
|
||||||
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
|
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ impl DOMException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef, code: DOMErrorName) -> Temporary<DOMException> {
|
pub fn new(global: GlobalRef, code: DOMErrorName) -> Root<DOMException> {
|
||||||
reflect_dom_object(box DOMException::new_inherited(code), global, DOMExceptionBinding::Wrap)
|
reflect_dom_object(box DOMException::new_inherited(code), global, DOMExceptionBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> {
|
impl<'a> DOMExceptionMethods for &'a DOMException {
|
||||||
// https://heycam.github.io/webidl/#dfn-DOMException
|
// https://heycam.github.io/webidl/#dfn-DOMException
|
||||||
fn Code(self) -> u16 {
|
fn Code(self) -> u16 {
|
||||||
match self.code {
|
match self.code {
|
||||||
|
|
|
@ -10,8 +10,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, OptionalRootable, Root, Rootable};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::js::Temporary;
|
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::bindings::utils::validate_qualified_name;
|
use dom::bindings::utils::validate_qualified_name;
|
||||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
||||||
|
@ -21,7 +20,6 @@ use dom::htmlbodyelement::HTMLBodyElement;
|
||||||
use dom::htmlheadelement::HTMLHeadElement;
|
use dom::htmlheadelement::HTMLHeadElement;
|
||||||
use dom::htmlhtmlelement::HTMLHtmlElement;
|
use dom::htmlhtmlelement::HTMLHtmlElement;
|
||||||
use dom::htmltitleelement::HTMLTitleElement;
|
use dom::htmltitleelement::HTMLTitleElement;
|
||||||
use dom::node::Node;
|
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
@ -35,15 +33,15 @@ pub struct DOMImplementation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DOMImplementation {
|
impl DOMImplementation {
|
||||||
fn new_inherited(document: JSRef<Document>) -> DOMImplementation {
|
fn new_inherited(document: &Document) -> DOMImplementation {
|
||||||
DOMImplementation {
|
DOMImplementation {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
document: JS::from_rooted(document),
|
document: JS::from_ref(document),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(document: JSRef<Document>) -> Temporary<DOMImplementation> {
|
pub fn new(document: &Document) -> Root<DOMImplementation> {
|
||||||
let window = document.window().root();
|
let window = document.window();
|
||||||
reflect_dom_object(box DOMImplementation::new_inherited(document),
|
reflect_dom_object(box DOMImplementation::new_inherited(document),
|
||||||
GlobalRef::Window(window.r()),
|
GlobalRef::Window(window.r()),
|
||||||
DOMImplementationBinding::Wrap)
|
DOMImplementationBinding::Wrap)
|
||||||
|
@ -51,10 +49,10 @@ impl DOMImplementation {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#domimplementation
|
// https://dom.spec.whatwg.org/#domimplementation
|
||||||
impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
impl<'a> DOMImplementationMethods for &'a DOMImplementation {
|
||||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
||||||
fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
|
fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
|
||||||
-> Fallible<Temporary<DocumentType>> {
|
-> Fallible<Root<DocumentType>> {
|
||||||
try!(validate_qualified_name(&qualified_name));
|
try!(validate_qualified_name(&qualified_name));
|
||||||
let document = self.document.root();
|
let document = self.document.root();
|
||||||
Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
|
Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
|
||||||
|
@ -62,15 +60,15 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
|
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
|
||||||
fn CreateDocument(self, namespace: Option<DOMString>, qname: DOMString,
|
fn CreateDocument(self, namespace: Option<DOMString>, qname: DOMString,
|
||||||
maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<Temporary<Document>> {
|
maybe_doctype: Option<&DocumentType>) -> Fallible<Root<Document>> {
|
||||||
let doc = self.document.root();
|
let doc = self.document.root();
|
||||||
let doc = doc.r();
|
let doc = doc.r();
|
||||||
let win = doc.window().root();
|
let win = doc.window();
|
||||||
let loader = DocumentLoader::new(&*doc.loader());
|
let loader = DocumentLoader::new(&*doc.loader());
|
||||||
|
|
||||||
// Step 1.
|
// Step 1.
|
||||||
let doc = Document::new(win.r(), None, IsHTMLDocument::NonHTMLDocument,
|
let doc = Document::new(win.r(), None, IsHTMLDocument::NonHTMLDocument,
|
||||||
None, None, DocumentSource::NotFromParser, loader).root();
|
None, None, DocumentSource::NotFromParser, loader);
|
||||||
// Step 2-3.
|
// Step 2-3.
|
||||||
let maybe_elem = if qname.is_empty() {
|
let maybe_elem = if qname.is_empty() {
|
||||||
None
|
None
|
||||||
|
@ -82,19 +80,19 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
let doc_node = NodeCast::from_ref(doc.r());
|
||||||
|
|
||||||
// Step 4.
|
// Step 4.
|
||||||
match maybe_doctype {
|
match maybe_doctype {
|
||||||
None => (),
|
None => (),
|
||||||
Some(ref doctype) => {
|
Some(ref doctype) => {
|
||||||
let doc_type: JSRef<Node> = NodeCast::from_ref(*doctype);
|
let doc_type = NodeCast::from_ref(*doctype);
|
||||||
assert!(doc_node.AppendChild(doc_type).is_ok())
|
assert!(doc_node.AppendChild(doc_type).is_ok())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5.
|
// Step 5.
|
||||||
match maybe_elem.root() {
|
match maybe_elem {
|
||||||
None => (),
|
None => (),
|
||||||
Some(ref elem) => {
|
Some(ref elem) => {
|
||||||
assert!(doc_node.AppendChild(NodeCast::from_ref(elem.r())).is_ok())
|
assert!(doc_node.AppendChild(NodeCast::from_ref(elem.r())).is_ok())
|
||||||
|
@ -106,37 +104,38 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1522
|
// FIXME: https://github.com/mozilla/servo/issues/1522
|
||||||
|
|
||||||
// Step 7.
|
// Step 7.
|
||||||
Ok(Temporary::from_rooted(doc.r()))
|
Ok(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||||||
fn CreateHTMLDocument(self, title: Option<DOMString>) -> Temporary<Document> {
|
fn CreateHTMLDocument(self, title: Option<DOMString>) -> Root<Document> {
|
||||||
let document = self.document.root();
|
let document = self.document.root();
|
||||||
let document = document.r();
|
let document = document.r();
|
||||||
let win = document.window().root();
|
let win = document.window();
|
||||||
let loader = DocumentLoader::new(&*document.loader());
|
let loader = DocumentLoader::new(&*document.loader());
|
||||||
|
|
||||||
// Step 1-2.
|
// Step 1-2.
|
||||||
let doc = Document::new(win.r(), None, IsHTMLDocument::HTMLDocument, None, None,
|
let doc = Document::new(win.r(), None, IsHTMLDocument::HTMLDocument, None, None,
|
||||||
DocumentSource::NotFromParser, loader).root();
|
DocumentSource::NotFromParser, loader);
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Step 3.
|
// Step 3.
|
||||||
let doc_type = DocumentType::new("html".to_owned(), None, None, doc.r()).root();
|
let doc_node = NodeCast::from_ref(doc.r());
|
||||||
|
let doc_type = DocumentType::new("html".to_owned(), None, None, doc.r());
|
||||||
assert!(doc_node.AppendChild(NodeCast::from_ref(doc_type.r())).is_ok());
|
assert!(doc_node.AppendChild(NodeCast::from_ref(doc_type.r())).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Step 4.
|
// Step 4.
|
||||||
let doc_html: Root<Node> = NodeCast::from_temporary(
|
let doc_node = NodeCast::from_ref(doc.r());
|
||||||
HTMLHtmlElement::new("html".to_owned(), None, doc.r())).root();
|
let doc_html = NodeCast::from_root(
|
||||||
|
HTMLHtmlElement::new("html".to_owned(), None, doc.r()));
|
||||||
assert!(doc_node.AppendChild(doc_html.r()).is_ok());
|
assert!(doc_node.AppendChild(doc_html.r()).is_ok());
|
||||||
|
|
||||||
{
|
{
|
||||||
// Step 5.
|
// Step 5.
|
||||||
let doc_head: Root<Node> = NodeCast::from_temporary(
|
let doc_head = NodeCast::from_root(
|
||||||
HTMLHeadElement::new("head".to_owned(), None, doc.r())).root();
|
HTMLHeadElement::new("head".to_owned(), None, doc.r()));
|
||||||
assert!(doc_html.r().AppendChild(doc_head.r()).is_ok());
|
assert!(doc_html.r().AppendChild(doc_head.r()).is_ok());
|
||||||
|
|
||||||
// Step 6.
|
// Step 6.
|
||||||
|
@ -144,19 +143,19 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||||
None => (),
|
None => (),
|
||||||
Some(title_str) => {
|
Some(title_str) => {
|
||||||
// Step 6.1.
|
// Step 6.1.
|
||||||
let doc_title: Root<Node> = NodeCast::from_temporary(
|
let doc_title = NodeCast::from_root(
|
||||||
HTMLTitleElement::new("title".to_owned(), None, doc.r())).root();
|
HTMLTitleElement::new("title".to_owned(), None, doc.r()));
|
||||||
assert!(doc_head.r().AppendChild(doc_title.r()).is_ok());
|
assert!(doc_head.r().AppendChild(doc_title.r()).is_ok());
|
||||||
|
|
||||||
// Step 6.2.
|
// Step 6.2.
|
||||||
let title_text: Root<Text> = Text::new(title_str, doc.r()).root();
|
let title_text = Text::new(title_str, doc.r());
|
||||||
assert!(doc_title.r().AppendChild(NodeCast::from_ref(title_text.r())).is_ok());
|
assert!(doc_title.r().AppendChild(NodeCast::from_ref(title_text.r())).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7.
|
// Step 7.
|
||||||
let doc_body: Root<HTMLBodyElement> = HTMLBodyElement::new("body".to_owned(), None, doc.r()).root();
|
let doc_body = HTMLBodyElement::new("body".to_owned(), None, doc.r());
|
||||||
assert!(doc_html.r().AppendChild(NodeCast::from_ref(doc_body.r())).is_ok());
|
assert!(doc_html.r().AppendChild(NodeCast::from_ref(doc_body.r())).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +163,7 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1522
|
// FIXME: https://github.com/mozilla/servo/issues/1522
|
||||||
|
|
||||||
// Step 9.
|
// Step 9.
|
||||||
Temporary::from_rooted(doc.r())
|
doc
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
|
// https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::{Text_htm
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, Rootable, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
||||||
use dom::document::DocumentSource;
|
use dom::document::DocumentSource;
|
||||||
|
@ -27,33 +27,33 @@ pub struct DOMParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DOMParser {
|
impl DOMParser {
|
||||||
fn new_inherited(window: JSRef<Window>) -> DOMParser {
|
fn new_inherited(window: &Window) -> DOMParser {
|
||||||
DOMParser {
|
DOMParser {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
window: JS::from_rooted(window),
|
window: JS::from_ref(window),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(window: JSRef<Window>) -> Temporary<DOMParser> {
|
pub fn new(window: &Window) -> Root<DOMParser> {
|
||||||
reflect_dom_object(box DOMParser::new_inherited(window), GlobalRef::Window(window),
|
reflect_dom_object(box DOMParser::new_inherited(window), GlobalRef::Window(window),
|
||||||
DOMParserBinding::Wrap)
|
DOMParserBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<DOMParser>> {
|
pub fn Constructor(global: GlobalRef) -> Fallible<Root<DOMParser>> {
|
||||||
Ok(DOMParser::new(global.as_window()))
|
Ok(DOMParser::new(global.as_window()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DOMParserMethods for JSRef<'a, DOMParser> {
|
impl<'a> DOMParserMethods for &'a DOMParser {
|
||||||
// https://domparsing.spec.whatwg.org/#the-domparser-interface
|
// https://domparsing.spec.whatwg.org/#the-domparser-interface
|
||||||
fn ParseFromString(self,
|
fn ParseFromString(self,
|
||||||
s: DOMString,
|
s: DOMString,
|
||||||
ty: DOMParserBinding::SupportedType)
|
ty: DOMParserBinding::SupportedType)
|
||||||
-> Fallible<Temporary<Document>> {
|
-> Fallible<Root<Document>> {
|
||||||
let window = self.window.root();
|
let window = self.window.root();
|
||||||
let url = window.r().get_url();
|
let url = window.r().get_url();
|
||||||
let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned();
|
let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned();
|
||||||
let doc = window.r().Document().root();
|
let doc = window.r().Document();
|
||||||
let doc = doc.r();
|
let doc = doc.r();
|
||||||
let loader = DocumentLoader::new(&*doc.loader());
|
let loader = DocumentLoader::new(&*doc.loader());
|
||||||
match ty {
|
match ty {
|
||||||
|
@ -63,10 +63,10 @@ impl<'a> DOMParserMethods for JSRef<'a, DOMParser> {
|
||||||
Some(content_type),
|
Some(content_type),
|
||||||
None,
|
None,
|
||||||
DocumentSource::FromParser,
|
DocumentSource::FromParser,
|
||||||
loader).root();
|
loader);
|
||||||
parse_html(document.r(), s, &url, ParseContext::Owner(None));
|
parse_html(document.r(), s, &url, ParseContext::Owner(None));
|
||||||
document.r().set_ready_state(DocumentReadyState::Complete);
|
document.r().set_ready_state(DocumentReadyState::Complete);
|
||||||
Ok(Temporary::from_rooted(document.r()))
|
Ok(document)
|
||||||
}
|
}
|
||||||
Text_xml => {
|
Text_xml => {
|
||||||
//FIXME: this should probably be FromParser when we actually parse the string (#3756).
|
//FIXME: this should probably be FromParser when we actually parse the string (#3756).
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::DOMRectBinding;
|
use dom::bindings::codegen::Bindings::DOMRectBinding;
|
||||||
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
|
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::num::Finite;
|
use dom::bindings::num::Finite;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
@ -32,15 +32,15 @@ impl DOMRect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(window: JSRef<Window>,
|
pub fn new(window: &Window,
|
||||||
top: Au, bottom: Au,
|
top: Au, bottom: Au,
|
||||||
left: Au, right: Au) -> Temporary<DOMRect> {
|
left: Au, right: Au) -> Root<DOMRect> {
|
||||||
reflect_dom_object(box DOMRect::new_inherited(top, bottom, left, right),
|
reflect_dom_object(box DOMRect::new_inherited(top, bottom, left, right),
|
||||||
GlobalRef::Window(window), DOMRectBinding::Wrap)
|
GlobalRef::Window(window), DOMRectBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DOMRectMethods for JSRef<'a, DOMRect> {
|
impl<'a> DOMRectMethods for &'a DOMRect {
|
||||||
fn Top(self) -> Finite<f32> {
|
fn Top(self) -> Finite<f32> {
|
||||||
Finite::wrap(self.top)
|
Finite::wrap(self.top)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::DOMRectListBinding;
|
use dom::bindings::codegen::Bindings::DOMRectListBinding;
|
||||||
use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods;
|
use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::domrect::DOMRect;
|
use dom::domrect::DOMRect;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
@ -18,37 +18,37 @@ pub struct DOMRectList {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DOMRectList {
|
impl DOMRectList {
|
||||||
fn new_inherited<T>(window: JSRef<Window>, rects: T) -> DOMRectList
|
fn new_inherited<T>(window: &Window, rects: T) -> DOMRectList
|
||||||
where T: Iterator<Item=Temporary<DOMRect>> {
|
where T: Iterator<Item=Root<DOMRect>> {
|
||||||
DOMRectList {
|
DOMRectList {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
rects: rects.map(JS::from_rooted).collect(),
|
rects: rects.map(|r| JS::from_rooted(&r)).collect(),
|
||||||
window: JS::from_rooted(window),
|
window: JS::from_ref(window),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<T>(window: JSRef<Window>, rects: T) -> Temporary<DOMRectList>
|
pub fn new<T>(window: &Window, rects: T) -> Root<DOMRectList>
|
||||||
where T: Iterator<Item=Temporary<DOMRect>> {
|
where T: Iterator<Item=Root<DOMRect>> {
|
||||||
reflect_dom_object(box DOMRectList::new_inherited(window, rects),
|
reflect_dom_object(box DOMRectList::new_inherited(window, rects),
|
||||||
GlobalRef::Window(window), DOMRectListBinding::Wrap)
|
GlobalRef::Window(window), DOMRectListBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DOMRectListMethods for JSRef<'a, DOMRectList> {
|
impl<'a> DOMRectListMethods for &'a DOMRectList {
|
||||||
fn Length(self) -> u32 {
|
fn Length(self) -> u32 {
|
||||||
self.rects.len() as u32
|
self.rects.len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Item(self, index: u32) -> Option<Temporary<DOMRect>> {
|
fn Item(self, index: u32) -> Option<Root<DOMRect>> {
|
||||||
let rects = &self.rects;
|
let rects = &self.rects;
|
||||||
if index < rects.len() as u32 {
|
if index < rects.len() as u32 {
|
||||||
Some(Temporary::from_rooted(rects[index as usize].clone()))
|
Some(rects[index as usize].root())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<DOMRect>> {
|
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<DOMRect>> {
|
||||||
*found = index < self.rects.len() as u32;
|
*found = index < self.rects.len() as u32;
|
||||||
self.Item(index)
|
self.Item(index)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMStringMapBinding;
|
||||||
use dom::bindings::codegen::Bindings::DOMStringMapBinding::DOMStringMapMethods;
|
use dom::bindings::codegen::Bindings::DOMStringMapBinding::DOMStringMapMethods;
|
||||||
use dom::bindings::error::ErrorResult;
|
use dom::bindings::error::ErrorResult;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, Rootable, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::node::window_from_node;
|
use dom::node::window_from_node;
|
||||||
use dom::htmlelement::{HTMLElement, HTMLElementCustomAttributeHelpers};
|
use dom::htmlelement::{HTMLElement, HTMLElementCustomAttributeHelpers};
|
||||||
|
@ -19,22 +19,22 @@ pub struct DOMStringMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DOMStringMap {
|
impl DOMStringMap {
|
||||||
fn new_inherited(element: JSRef<HTMLElement>) -> DOMStringMap {
|
fn new_inherited(element: &HTMLElement) -> DOMStringMap {
|
||||||
DOMStringMap {
|
DOMStringMap {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
element: JS::from_rooted(element),
|
element: JS::from_ref(element),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(element: JSRef<HTMLElement>) -> Temporary<DOMStringMap> {
|
pub fn new(element: &HTMLElement) -> Root<DOMStringMap> {
|
||||||
let window = window_from_node(element).root();
|
let window = window_from_node(element);
|
||||||
reflect_dom_object(box DOMStringMap::new_inherited(element),
|
reflect_dom_object(box DOMStringMap::new_inherited(element),
|
||||||
GlobalRef::Window(window.r()), DOMStringMapBinding::Wrap)
|
GlobalRef::Window(window.r()), DOMStringMapBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/#domstringmap
|
// https://html.spec.whatwg.org/#domstringmap
|
||||||
impl<'a> DOMStringMapMethods for JSRef<'a, DOMStringMap> {
|
impl<'a> DOMStringMapMethods for &'a DOMStringMap {
|
||||||
fn NamedCreator(self, name: DOMString, value: DOMString) -> ErrorResult {
|
fn NamedCreator(self, name: DOMString, value: DOMString) -> ErrorResult {
|
||||||
self.NamedSetter(name, value)
|
self.NamedSetter(name, value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::element::{Element, AttributeHandlers};
|
use dom::element::{Element, AttributeHandlers};
|
||||||
use dom::node::window_from_node;
|
use dom::node::window_from_node;
|
||||||
|
@ -26,16 +26,16 @@ pub struct DOMTokenList {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DOMTokenList {
|
impl DOMTokenList {
|
||||||
pub fn new_inherited(element: JSRef<Element>, local_name: Atom) -> DOMTokenList {
|
pub fn new_inherited(element: &Element, local_name: Atom) -> DOMTokenList {
|
||||||
DOMTokenList {
|
DOMTokenList {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
element: JS::from_rooted(element),
|
element: JS::from_ref(element),
|
||||||
local_name: local_name,
|
local_name: local_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(element: JSRef<Element>, local_name: &Atom) -> Temporary<DOMTokenList> {
|
pub fn new(element: &Element, local_name: &Atom) -> Root<DOMTokenList> {
|
||||||
let window = window_from_node(element).root();
|
let window = window_from_node(element);
|
||||||
reflect_dom_object(box DOMTokenList::new_inherited(element, local_name.clone()),
|
reflect_dom_object(box DOMTokenList::new_inherited(element, local_name.clone()),
|
||||||
GlobalRef::Window(window.r()),
|
GlobalRef::Window(window.r()),
|
||||||
DOMTokenListBinding::Wrap)
|
DOMTokenListBinding::Wrap)
|
||||||
|
@ -43,12 +43,12 @@ impl DOMTokenList {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateDOMTokenListHelpers {
|
trait PrivateDOMTokenListHelpers {
|
||||||
fn attribute(self) -> Option<Temporary<Attr>>;
|
fn attribute(self) -> Option<Root<Attr>>;
|
||||||
fn check_token_exceptions(self, token: &str) -> Fallible<Atom>;
|
fn check_token_exceptions(self, token: &str) -> Fallible<Atom>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> {
|
impl<'a> PrivateDOMTokenListHelpers for &'a DOMTokenList {
|
||||||
fn attribute(self) -> Option<Temporary<Attr>> {
|
fn attribute(self) -> Option<Root<Attr>> {
|
||||||
let element = self.element.root();
|
let element = self.element.root();
|
||||||
element.r().get_attribute(&ns!(""), &self.local_name)
|
element.r().get_attribute(&ns!(""), &self.local_name)
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,10 @@ impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#domtokenlist
|
// https://dom.spec.whatwg.org/#domtokenlist
|
||||||
impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
|
impl<'a> DOMTokenListMethods for &'a DOMTokenList {
|
||||||
// https://dom.spec.whatwg.org/#dom-domtokenlist-length
|
// https://dom.spec.whatwg.org/#dom-domtokenlist-length
|
||||||
fn Length(self) -> u32 {
|
fn Length(self) -> u32 {
|
||||||
self.attribute().root().map(|attr| {
|
self.attribute().map(|attr| {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -76,7 +76,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-domtokenlist-item
|
// https://dom.spec.whatwg.org/#dom-domtokenlist-item
|
||||||
fn Item(self, index: u32) -> Option<DOMString> {
|
fn Item(self, index: u32) -> Option<DOMString> {
|
||||||
self.attribute().root().and_then(|attr| {
|
self.attribute().and_then(|attr| {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -95,7 +95,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
|
||||||
// https://dom.spec.whatwg.org/#dom-domtokenlist-contains
|
// https://dom.spec.whatwg.org/#dom-domtokenlist-contains
|
||||||
fn Contains(self, token: DOMString) -> Fallible<bool> {
|
fn Contains(self, token: DOMString) -> Fallible<bool> {
|
||||||
self.check_token_exceptions(&token).map(|token| {
|
self.check_token_exceptions(&token).map(|token| {
|
||||||
self.attribute().root().map(|attr| {
|
self.attribute().map(|attr| {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
|
|
@ -29,9 +29,8 @@ use dom::bindings::codegen::UnionTypes::NodeOrString;
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
||||||
use dom::bindings::error::Error::NoModificationAllowed;
|
use dom::bindings::error::Error::NoModificationAllowed;
|
||||||
use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::js::{OptionalRootable, Rootable, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::bindings::js::{Temporary, TemporaryPushable};
|
|
||||||
use dom::bindings::trace::RootedVec;
|
use dom::bindings::trace::RootedVec;
|
||||||
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
||||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||||
|
@ -42,7 +41,6 @@ use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers};
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::event::{Event, EventHelpers};
|
use dom::event::{Event, EventHelpers};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
|
||||||
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers};
|
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::HTMLCollection;
|
||||||
use dom::htmlelement::HTMLElementTypeId;
|
use dom::htmlelement::HTMLElementTypeId;
|
||||||
|
@ -113,6 +111,12 @@ impl ElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Element {
|
||||||
|
fn eq(&self, other: &Element) -> bool {
|
||||||
|
self as *const Element == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
pub enum ElementTypeId {
|
pub enum ElementTypeId {
|
||||||
|
@ -131,14 +135,14 @@ pub enum ElementCreator {
|
||||||
//
|
//
|
||||||
impl Element {
|
impl Element {
|
||||||
pub fn create(name: QualName, prefix: Option<Atom>,
|
pub fn create(name: QualName, prefix: Option<Atom>,
|
||||||
document: JSRef<Document>, creator: ElementCreator)
|
document: &Document, creator: ElementCreator)
|
||||||
-> Temporary<Element> {
|
-> Root<Element> {
|
||||||
create_element(name, prefix, document, creator)
|
create_element(name, prefix, document, creator)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_inherited(type_id: ElementTypeId, local_name: DOMString,
|
pub fn new_inherited(type_id: ElementTypeId, local_name: DOMString,
|
||||||
namespace: Namespace, prefix: Option<DOMString>,
|
namespace: Namespace, prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Element {
|
document: &Document) -> Element {
|
||||||
Element {
|
Element {
|
||||||
node: Node::new_inherited(NodeTypeId::Element(type_id), document),
|
node: Node::new_inherited(NodeTypeId::Element(type_id), document),
|
||||||
local_name: Atom::from_slice(&local_name),
|
local_name: Atom::from_slice(&local_name),
|
||||||
|
@ -154,7 +158,7 @@ impl Element {
|
||||||
pub fn new(local_name: DOMString,
|
pub fn new(local_name: DOMString,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<Element> {
|
document: &Document) -> Root<Element> {
|
||||||
Node::reflect_node(
|
Node::reflect_node(
|
||||||
box Element::new_inherited(ElementTypeId::Element, local_name, namespace, prefix, document),
|
box Element::new_inherited(ElementTypeId::Element, local_name, namespace, prefix, document),
|
||||||
document,
|
document,
|
||||||
|
@ -181,8 +185,6 @@ pub trait RawLayoutElementHelpers {
|
||||||
-> Option<u32>;
|
-> Option<u32>;
|
||||||
|
|
||||||
fn local_name<'a>(&'a self) -> &'a Atom;
|
fn local_name<'a>(&'a self) -> &'a Atom;
|
||||||
fn namespace<'a>(&'a self) -> &'a Namespace;
|
|
||||||
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -504,14 +506,6 @@ impl RawLayoutElementHelpers for Element {
|
||||||
fn local_name<'a>(&'a self) -> &'a Atom {
|
fn local_name<'a>(&'a self) -> &'a Atom {
|
||||||
&self.local_name
|
&self.local_name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn namespace<'a>(&'a self) -> &'a Namespace {
|
|
||||||
&self.namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
|
|
||||||
&self.style_attribute
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayoutElementHelpers {
|
pub trait LayoutElementHelpers {
|
||||||
|
@ -560,18 +554,18 @@ pub trait ElementHelpers<'a> {
|
||||||
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
|
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
|
||||||
fn get_root_element(self) -> Temporary<Element>;
|
fn get_root_element(self) -> Root<Element>;
|
||||||
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>;
|
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
impl<'a> ElementHelpers<'a> for &'a Element {
|
||||||
fn html_element_in_html_document(self) -> bool {
|
fn html_element_in_html_document(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
self.namespace == ns!(HTML) && node.is_in_html_doc()
|
self.namespace == ns!(HTML) && node.is_in_html_doc()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_name(self) -> &'a Atom {
|
fn local_name(self) -> &'a Atom {
|
||||||
&self.extended_deref().local_name
|
&self.local_name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parsed_name(self, name: DOMString) -> DOMString {
|
fn parsed_name(self, name: DOMString) -> DOMString {
|
||||||
|
@ -583,30 +577,30 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn namespace(self) -> &'a Namespace {
|
fn namespace(self) -> &'a Namespace {
|
||||||
&self.extended_deref().namespace
|
&self.namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix(self) -> &'a Option<DOMString> {
|
fn prefix(self) -> &'a Option<DOMString> {
|
||||||
&self.extended_deref().prefix
|
&self.prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attrs(&self) -> Ref<Vec<JS<Attr>>> {
|
fn attrs(&self) -> Ref<Vec<JS<Attr>>> {
|
||||||
self.extended_deref().attrs.borrow()
|
self.attrs.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> {
|
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> {
|
||||||
self.extended_deref().attrs.borrow_mut()
|
self.attrs.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
|
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
|
||||||
&self.extended_deref().style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
fn summarize(self) -> Vec<AttrInfo> {
|
fn summarize(self) -> Vec<AttrInfo> {
|
||||||
let attrs = self.Attributes().root();
|
let attrs = self.Attributes();
|
||||||
let mut summarized = vec!();
|
let mut summarized = vec!();
|
||||||
for i in 0..attrs.r().Length() {
|
for i in 0..attrs.r().Length() {
|
||||||
let attr = attrs.r().Item(i).unwrap().root();
|
let attr = attrs.r().Item(i).unwrap();
|
||||||
summarized.push(attr.r().summarize());
|
summarized.push(attr.r().summarize());
|
||||||
}
|
}
|
||||||
summarized
|
summarized
|
||||||
|
@ -702,7 +696,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
|
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let mut writer = vec![];
|
let mut writer = vec![];
|
||||||
match serialize(&mut writer, &node,
|
match serialize(&mut writer, &node,
|
||||||
SerializeOpts {
|
SerializeOpts {
|
||||||
|
@ -715,10 +709,10 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#root-element
|
// https://html.spec.whatwg.org/multipage/#root-element
|
||||||
fn get_root_element(self) -> Temporary<Element> {
|
fn get_root_element(self) -> Root<Element> {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.inclusive_ancestors()
|
node.inclusive_ancestors()
|
||||||
.filter_map(ElementCast::to_temporary)
|
.filter_map(ElementCast::to_root)
|
||||||
.last()
|
.last()
|
||||||
.expect("We know inclusive_ancestors will return `self` which is an element")
|
.expect("We know inclusive_ancestors will return `self` which is an element")
|
||||||
}
|
}
|
||||||
|
@ -726,7 +720,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
// https://dom.spec.whatwg.org/#locate-a-namespace-prefix
|
// https://dom.spec.whatwg.org/#locate-a-namespace-prefix
|
||||||
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString> {
|
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString> {
|
||||||
for node in NodeCast::from_ref(self).inclusive_ancestors() {
|
for node in NodeCast::from_ref(self).inclusive_ancestors() {
|
||||||
match ElementCast::to_ref(node.root().r()) {
|
match ElementCast::to_ref(node.r()) {
|
||||||
Some(element) => {
|
Some(element) => {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
if *element.namespace() == namespace {
|
if *element.namespace() == namespace {
|
||||||
|
@ -736,9 +730,9 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2.
|
// Step 2.
|
||||||
let attrs = element.Attributes().root();
|
let attrs = element.Attributes();
|
||||||
for i in 0..attrs.r().Length() {
|
for i in 0..attrs.r().Length() {
|
||||||
let attr = attrs.r().Item(i).unwrap().root();
|
let attr = attrs.r().Item(i).unwrap();
|
||||||
if *attr.r().prefix() == Some(atom!("xmlns")) &&
|
if *attr.r().prefix() == Some(atom!("xmlns")) &&
|
||||||
**attr.r().value() == *namespace.0 {
|
**attr.r().value() == *namespace.0 {
|
||||||
return Some(attr.r().LocalName());
|
return Some(attr.r().LocalName());
|
||||||
|
@ -760,13 +754,13 @@ pub trait FocusElementHelpers {
|
||||||
fn is_actually_disabled(self) -> bool;
|
fn is_actually_disabled(self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FocusElementHelpers for JSRef<'a, Element> {
|
impl<'a> FocusElementHelpers for &'a Element {
|
||||||
fn is_focusable_area(self) -> bool {
|
fn is_focusable_area(self) -> bool {
|
||||||
if self.is_actually_disabled() {
|
if self.is_actually_disabled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Check whether the element is being rendered (i.e. not hidden).
|
// TODO: Check whether the element is being rendered (i.e. not hidden).
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if node.get_flag(SEQUENTIALLY_FOCUSABLE) {
|
if node.get_flag(SEQUENTIALLY_FOCUSABLE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -783,7 +777,7 @@ impl<'a> FocusElementHelpers for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_actually_disabled(self) -> bool {
|
fn is_actually_disabled(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
match node.type_id() {
|
match node.type_id() {
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
||||||
|
@ -805,10 +799,10 @@ pub trait AttributeHandlers {
|
||||||
/// Returns the attribute with given namespace and case-sensitive local
|
/// Returns the attribute with given namespace and case-sensitive local
|
||||||
/// name, if any.
|
/// name, if any.
|
||||||
fn get_attribute(self, namespace: &Namespace, local_name: &Atom)
|
fn get_attribute(self, namespace: &Namespace, local_name: &Atom)
|
||||||
-> Option<Temporary<Attr>>;
|
-> Option<Root<Attr>>;
|
||||||
/// Returns the first attribute with any namespace and given case-sensitive
|
/// Returns the first attribute with any namespace and given case-sensitive
|
||||||
/// name, if any.
|
/// name, if any.
|
||||||
fn get_attribute_by_name(self, name: DOMString) -> Option<Temporary<Attr>>;
|
fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>>;
|
||||||
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>);
|
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>);
|
||||||
fn set_attribute_from_parser(self,
|
fn set_attribute_from_parser(self,
|
||||||
name: QualName,
|
name: QualName,
|
||||||
|
@ -819,19 +813,19 @@ pub trait AttributeHandlers {
|
||||||
fn do_set_attribute<F>(self, local_name: Atom, value: AttrValue,
|
fn do_set_attribute<F>(self, local_name: Atom, value: AttrValue,
|
||||||
name: Atom, namespace: Namespace,
|
name: Atom, namespace: Namespace,
|
||||||
prefix: Option<Atom>, cb: F)
|
prefix: Option<Atom>, cb: F)
|
||||||
where F: Fn(JSRef<Attr>) -> bool;
|
where F: Fn(&Attr) -> bool;
|
||||||
fn parse_attribute(self, namespace: &Namespace, local_name: &Atom,
|
fn parse_attribute(self, namespace: &Namespace, local_name: &Atom,
|
||||||
value: DOMString) -> AttrValue;
|
value: DOMString) -> AttrValue;
|
||||||
|
|
||||||
/// Removes the first attribute with any given namespace and case-sensitive local
|
/// Removes the first attribute with any given namespace and case-sensitive local
|
||||||
/// name, if any.
|
/// name, if any.
|
||||||
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
|
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
|
||||||
-> Option<Temporary<Attr>>;
|
-> Option<Root<Attr>>;
|
||||||
/// Removes the first attribute with any namespace and given case-sensitive name.
|
/// Removes the first attribute with any namespace and given case-sensitive name.
|
||||||
fn remove_attribute_by_name(self, name: &Atom) -> Option<Temporary<Attr>>;
|
fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>>;
|
||||||
/// Removes the first attribute that satisfies `find`.
|
/// Removes the first attribute that satisfies `find`.
|
||||||
fn do_remove_attribute<F>(self, find: F) -> Option<Temporary<Attr>>
|
fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>>
|
||||||
where F: Fn(JSRef<Attr>) -> bool;
|
where F: Fn(&Attr) -> bool;
|
||||||
|
|
||||||
fn has_class(self, name: &Atom) -> bool;
|
fn has_class(self, name: &Atom) -> bool;
|
||||||
|
|
||||||
|
@ -851,36 +845,34 @@ pub trait AttributeHandlers {
|
||||||
fn set_uint_attribute(self, local_name: &Atom, value: u32);
|
fn set_uint_attribute(self, local_name: &Atom, value: u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
impl<'a> AttributeHandlers for &'a Element {
|
||||||
fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Temporary<Attr>> {
|
fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> {
|
||||||
let mut attributes = RootedVec::new();
|
let mut attributes = RootedVec::new();
|
||||||
self.get_attributes(local_name, &mut attributes);
|
self.get_attributes(local_name, &mut attributes);
|
||||||
attributes.iter()
|
attributes.iter()
|
||||||
.map(|attr| attr.root())
|
.map(|attr| attr.root())
|
||||||
.find(|attr| attr.r().namespace() == namespace)
|
.find(|attr| attr.r().namespace() == namespace)
|
||||||
.map(|x| Temporary::from_rooted(x.r()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
||||||
fn get_attribute_by_name(self, name: DOMString) -> Option<Temporary<Attr>> {
|
fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>> {
|
||||||
let name = &Atom::from_slice(&self.parsed_name(name));
|
let name = &Atom::from_slice(&self.parsed_name(name));
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attrs = self.attrs.borrow();
|
let attrs = self.attrs.borrow();
|
||||||
attrs.iter().map(|attr| attr.root())
|
attrs.iter().map(|attr| attr.root())
|
||||||
.find(|a| a.r().name() == name)
|
.find(|a| a.r().name() == name)
|
||||||
.map(|x| Temporary::from_rooted(x.r()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
|
||||||
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>) {
|
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>) {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attrs = self.attrs.borrow();
|
let attrs = self.attrs.borrow();
|
||||||
for ref attr in attrs.iter().map(|attr| attr.root()) {
|
for ref attr in attrs.iter() {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.root();
|
||||||
let attr_local_name = attr.local_name();
|
let attr_local_name = attr.r().local_name();
|
||||||
if attr_local_name == local_name {
|
if attr_local_name == local_name {
|
||||||
attributes.push(JS::from_rooted(attr));
|
attributes.push(JS::from_rooted(&attr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,7 +930,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<Atom>,
|
prefix: Option<Atom>,
|
||||||
cb: F)
|
cb: F)
|
||||||
where F: Fn(JSRef<Attr>) -> bool
|
where F: Fn(&Attr) -> bool
|
||||||
{
|
{
|
||||||
let idx = self.attrs.borrow().iter()
|
let idx = self.attrs.borrow().iter()
|
||||||
.map(|attr| attr.root())
|
.map(|attr| attr.root())
|
||||||
|
@ -946,10 +938,10 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
let (idx, set_type) = match idx {
|
let (idx, set_type) = match idx {
|
||||||
Some(idx) => (idx, AttrSettingType::ReplacedAttr),
|
Some(idx) => (idx, AttrSettingType::ReplacedAttr),
|
||||||
None => {
|
None => {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let attr = Attr::new(window.r(), local_name, value.clone(),
|
let attr = Attr::new(window.r(), local_name, value.clone(),
|
||||||
name, namespace.clone(), prefix, Some(self));
|
name, namespace.clone(), prefix, Some(self));
|
||||||
self.attrs.borrow_mut().push_unrooted(&attr);
|
self.attrs.borrow_mut().push(JS::from_rooted(&attr));
|
||||||
(self.attrs.borrow().len() - 1, AttrSettingType::FirstSetAttr)
|
(self.attrs.borrow().len() - 1, AttrSettingType::FirstSetAttr)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -968,18 +960,18 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
|
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
|
||||||
-> Option<Temporary<Attr>> {
|
-> Option<Root<Attr>> {
|
||||||
self.do_remove_attribute(|attr| {
|
self.do_remove_attribute(|attr| {
|
||||||
attr.namespace() == namespace && attr.local_name() == local_name
|
attr.namespace() == namespace && attr.local_name() == local_name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_attribute_by_name(self, name: &Atom) -> Option<Temporary<Attr>> {
|
fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>> {
|
||||||
self.do_remove_attribute(|attr| attr.name() == name)
|
self.do_remove_attribute(|attr| attr.name() == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_remove_attribute<F>(self, find: F) -> Option<Temporary<Attr>>
|
fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>>
|
||||||
where F: Fn(JSRef<Attr>) -> bool
|
where F: Fn(&Attr) -> bool
|
||||||
{
|
{
|
||||||
let idx = self.attrs.borrow().iter()
|
let idx = self.attrs.borrow().iter()
|
||||||
.map(|attr| attr.root())
|
.map(|attr| attr.root())
|
||||||
|
@ -997,9 +989,9 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
vtable_for(&NodeCast::from_ref(self)).after_remove_attr(attr.r().name());
|
vtable_for(&NodeCast::from_ref(self)).after_remove_attr(attr.r().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let document = document_from_node(self).root();
|
let document = document_from_node(self);
|
||||||
let damage = if attr.r().local_name() == &atom!("style") {
|
let damage = if attr.r().local_name() == &atom!("style") {
|
||||||
NodeDamage::NodeStyleDamaged
|
NodeDamage::NodeStyleDamaged
|
||||||
} else {
|
} else {
|
||||||
|
@ -1007,21 +999,21 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
};
|
};
|
||||||
document.r().content_changed(node, damage);
|
document.r().content_changed(node, damage);
|
||||||
}
|
}
|
||||||
Temporary::from_rooted(attr.r())
|
attr
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_class(self, name: &Atom) -> bool {
|
fn has_class(self, name: &Atom) -> bool {
|
||||||
let quirks_mode = {
|
let quirks_mode = {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let owner_doc = node.owner_doc().root();
|
let owner_doc = node.owner_doc();
|
||||||
owner_doc.r().quirks_mode()
|
owner_doc.r().quirks_mode()
|
||||||
};
|
};
|
||||||
let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode {
|
let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode {
|
||||||
NoQuirks | LimitedQuirks => lhs == rhs,
|
NoQuirks | LimitedQuirks => lhs == rhs,
|
||||||
Quirks => lhs.eq_ignore_ascii_case(&rhs)
|
Quirks => lhs.eq_ignore_ascii_case(&rhs)
|
||||||
};
|
};
|
||||||
self.get_attribute(&ns!(""), &atom!("class")).root().map(|attr| {
|
self.get_attribute(&ns!(""), &atom!("class")).map(|attr| {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -1063,7 +1055,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
return "".to_owned();
|
return "".to_owned();
|
||||||
}
|
}
|
||||||
let url = self.get_string_attribute(local_name);
|
let url = self.get_string_attribute(local_name);
|
||||||
let doc = document_from_node(self).root();
|
let doc = document_from_node(self);
|
||||||
let base = doc.r().url();
|
let base = doc.r().url();
|
||||||
// https://html.spec.whatwg.org/multipage/#reflect
|
// https://html.spec.whatwg.org/multipage/#reflect
|
||||||
// XXXManishearth this doesn't handle `javascript:` urls properly
|
// XXXManishearth this doesn't handle `javascript:` urls properly
|
||||||
|
@ -1078,7 +1070,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
|
|
||||||
fn get_string_attribute(self, local_name: &Atom) -> DOMString {
|
fn get_string_attribute(self, local_name: &Atom) -> DOMString {
|
||||||
match self.get_attribute(&ns!(""), local_name) {
|
match self.get_attribute(&ns!(""), local_name) {
|
||||||
Some(x) => x.root().r().Value(),
|
Some(x) => x.r().Value(),
|
||||||
None => "".to_owned()
|
None => "".to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1080,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tokenlist_attribute(self, local_name: &Atom) -> Vec<Atom> {
|
fn get_tokenlist_attribute(self, local_name: &Atom) -> Vec<Atom> {
|
||||||
self.get_attribute(&ns!(""), local_name).root().map(|attr| {
|
self.get_attribute(&ns!(""), local_name).map(|attr| {
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -1112,7 +1104,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
assert!(local_name.chars().all(|ch| {
|
assert!(local_name.chars().all(|ch| {
|
||||||
!ch.is_ascii() || ch.to_ascii_lowercase() == ch
|
!ch.is_ascii() || ch.to_ascii_lowercase() == ch
|
||||||
}));
|
}));
|
||||||
let attribute = self.get_attribute(&ns!(""), local_name).root();
|
let attribute = self.get_attribute(&ns!(""), local_name);
|
||||||
match attribute {
|
match attribute {
|
||||||
Some(ref attribute) => {
|
Some(ref attribute) => {
|
||||||
match *attribute.r().value() {
|
match *attribute.r().value() {
|
||||||
|
@ -1130,7 +1122,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ElementMethods for JSRef<'a, Element> {
|
impl<'a> ElementMethods for &'a Element {
|
||||||
// https://dom.spec.whatwg.org/#dom-element-namespaceuri
|
// https://dom.spec.whatwg.org/#dom-element-namespaceuri
|
||||||
fn GetNamespaceURI(self) -> Option<DOMString> {
|
fn GetNamespaceURI(self) -> Option<DOMString> {
|
||||||
match self.namespace {
|
match self.namespace {
|
||||||
|
@ -1185,25 +1177,25 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-classlist
|
// https://dom.spec.whatwg.org/#dom-element-classlist
|
||||||
fn ClassList(self) -> Temporary<DOMTokenList> {
|
fn ClassList(self) -> Root<DOMTokenList> {
|
||||||
self.class_list.or_init(|| DOMTokenList::new(self, &atom!("class")))
|
self.class_list.or_init(|| DOMTokenList::new(self, &atom!("class")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-attributes
|
// https://dom.spec.whatwg.org/#dom-element-attributes
|
||||||
fn Attributes(self) -> Temporary<NamedNodeMap> {
|
fn Attributes(self) -> Root<NamedNodeMap> {
|
||||||
self.attr_list.or_init(|| {
|
self.attr_list.or_init(|| {
|
||||||
let doc = {
|
let doc = {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.owner_doc().root()
|
node.owner_doc()
|
||||||
};
|
};
|
||||||
let window = doc.r().window().root();
|
let window = doc.r().window();
|
||||||
NamedNodeMap::new(window.r(), self)
|
NamedNodeMap::new(window.r(), self)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-getattribute
|
// https://dom.spec.whatwg.org/#dom-element-getattribute
|
||||||
fn GetAttribute(self, name: DOMString) -> Option<DOMString> {
|
fn GetAttribute(self, name: DOMString) -> Option<DOMString> {
|
||||||
self.get_attribute_by_name(name).root()
|
self.get_attribute_by_name(name)
|
||||||
.map(|s| s.r().Value())
|
.map(|s| s.r().Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1212,7 +1204,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
namespace: Option<DOMString>,
|
namespace: Option<DOMString>,
|
||||||
local_name: DOMString) -> Option<DOMString> {
|
local_name: DOMString) -> Option<DOMString> {
|
||||||
let namespace = &namespace::from_domstring(namespace);
|
let namespace = &namespace::from_domstring(namespace);
|
||||||
self.get_attribute(namespace, &Atom::from_slice(&local_name)).root()
|
self.get_attribute(namespace, &Atom::from_slice(&local_name))
|
||||||
.map(|attr| attr.r().Value())
|
.map(|attr| attr.r().Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,28 +1274,28 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagname
|
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagname
|
||||||
fn GetElementsByTagName(self, localname: DOMString) -> Temporary<HTMLCollection> {
|
fn GetElementsByTagName(self, localname: DOMString) -> Root<HTMLCollection> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), localname)
|
HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), localname)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens
|
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens
|
||||||
fn GetElementsByTagNameNS(self, maybe_ns: Option<DOMString>,
|
fn GetElementsByTagNameNS(self, maybe_ns: Option<DOMString>,
|
||||||
localname: DOMString) -> Temporary<HTMLCollection> {
|
localname: DOMString) -> Root<HTMLCollection> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), localname, maybe_ns)
|
HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), localname, maybe_ns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-getelementsbyclassname
|
// https://dom.spec.whatwg.org/#dom-element-getelementsbyclassname
|
||||||
fn GetElementsByClassName(self, classes: DOMString) -> Temporary<HTMLCollection> {
|
fn GetElementsByClassName(self, classes: DOMString) -> Root<HTMLCollection> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes)
|
HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects
|
// http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects
|
||||||
fn GetClientRects(self) -> Temporary<DOMRectList> {
|
fn GetClientRects(self) -> Root<DOMRectList> {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let raw_rects = node.get_content_boxes();
|
let raw_rects = node.get_content_boxes();
|
||||||
let rects = raw_rects.iter().map(|rect| {
|
let rects = raw_rects.iter().map(|rect| {
|
||||||
DOMRect::new(win.r(),
|
DOMRect::new(win.r(),
|
||||||
|
@ -1314,9 +1306,9 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect
|
// http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect
|
||||||
fn GetBoundingClientRect(self) -> Temporary<DOMRect> {
|
fn GetBoundingClientRect(self) -> Root<DOMRect> {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let rect = node.get_bounding_content_box();
|
let rect = node.get_bounding_content_box();
|
||||||
DOMRect::new(
|
DOMRect::new(
|
||||||
win.r(),
|
win.r(),
|
||||||
|
@ -1334,11 +1326,11 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML
|
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML
|
||||||
fn SetInnerHTML(self, value: DOMString) -> Fallible<()> {
|
fn SetInnerHTML(self, value: DOMString) -> Fallible<()> {
|
||||||
let context_node: JSRef<Node> = NodeCast::from_ref(self);
|
let context_node = NodeCast::from_ref(self);
|
||||||
// Step 1.
|
// Step 1.
|
||||||
let frag = try!(context_node.parse_fragment(value));
|
let frag = try!(context_node.parse_fragment(value));
|
||||||
// Step 2.
|
// Step 2.
|
||||||
Node::replace_all(Some(NodeCast::from_ref(frag.root().r())), context_node);
|
Node::replace_all(Some(NodeCast::from_ref(frag.r())), context_node);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1349,8 +1341,8 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML
|
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML
|
||||||
fn SetOuterHTML(self, value: DOMString) -> Fallible<()> {
|
fn SetOuterHTML(self, value: DOMString) -> Fallible<()> {
|
||||||
let context_document = document_from_node(self).root();
|
let context_document = document_from_node(self);
|
||||||
let context_node: JSRef<Node> = NodeCast::from_ref(self);
|
let context_node = NodeCast::from_ref(self);
|
||||||
// Step 1.
|
// Step 1.
|
||||||
let context_parent = match context_node.GetParentNode() {
|
let context_parent = match context_node.GetParentNode() {
|
||||||
None => {
|
None => {
|
||||||
|
@ -1358,7 +1350,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
Some(parent) => parent,
|
Some(parent) => parent,
|
||||||
}.root();
|
};
|
||||||
|
|
||||||
let parent = match context_parent.r().type_id() {
|
let parent = match context_parent.r().type_id() {
|
||||||
// Step 3.
|
// Step 3.
|
||||||
|
@ -1369,45 +1361,45 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
let body_elem = Element::create(QualName::new(ns!(HTML), atom!(body)),
|
let body_elem = Element::create(QualName::new(ns!(HTML), atom!(body)),
|
||||||
None, context_document.r(),
|
None, context_document.r(),
|
||||||
ElementCreator::ScriptCreated);
|
ElementCreator::ScriptCreated);
|
||||||
NodeCast::from_temporary(body_elem)
|
NodeCast::from_root(body_elem)
|
||||||
},
|
},
|
||||||
_ => context_node.GetParentNode().unwrap()
|
_ => context_node.GetParentNode().unwrap()
|
||||||
}.root();
|
};
|
||||||
|
|
||||||
// Step 5.
|
// Step 5.
|
||||||
let frag = try!(parent.r().parse_fragment(value));
|
let frag = try!(parent.r().parse_fragment(value));
|
||||||
// Step 6.
|
// Step 6.
|
||||||
try!(context_parent.r().ReplaceChild(NodeCast::from_ref(frag.root().r()),
|
try!(context_parent.r().ReplaceChild(NodeCast::from_ref(frag.r()),
|
||||||
context_node));
|
context_node));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
fn GetPreviousElementSibling(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).preceding_siblings()
|
NodeCast::from_ref(self).preceding_siblings()
|
||||||
.filter_map(ElementCast::to_temporary).next()
|
.filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
fn GetNextElementSibling(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).following_siblings()
|
NodeCast::from_ref(self).following_siblings()
|
||||||
.filter_map(ElementCast::to_temporary).next()
|
.filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-children
|
// https://dom.spec.whatwg.org/#dom-parentnode-children
|
||||||
fn Children(self) -> Temporary<HTMLCollection> {
|
fn Children(self) -> Root<HTMLCollection> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
|
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
|
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
|
||||||
fn GetFirstElementChild(self) -> Option<Temporary<Element>> {
|
fn GetFirstElementChild(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).child_elements().next()
|
NodeCast::from_ref(self).child_elements().next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
|
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
|
||||||
fn GetLastElementChild(self) -> Option<Temporary<Element>> {
|
fn GetLastElementChild(self) -> Option<Root<Element>> {
|
||||||
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_temporary).next()
|
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
|
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
|
||||||
|
@ -1426,14 +1418,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
||||||
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
root.query_selector(selectors)
|
root.query_selector(selectors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||||
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
root.query_selector_all(selectors)
|
root.query_selector_all(selectors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1454,7 +1446,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
// https://dom.spec.whatwg.org/#dom-childnode-remove
|
||||||
fn Remove(self) {
|
fn Remove(self) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.remove_self();
|
node.remove_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1463,23 +1455,22 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
match parse_author_origin_selector_list_from_str(&selectors) {
|
match parse_author_origin_selector_list_from_str(&selectors) {
|
||||||
Err(()) => Err(Syntax),
|
Err(()) => Err(Syntax),
|
||||||
Ok(ref selectors) => {
|
Ok(ref selectors) => {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
Ok(matches(selectors, &root, &mut None))
|
Ok(matches(selectors, &root, &mut None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-closest
|
// https://dom.spec.whatwg.org/#dom-element-closest
|
||||||
fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
fn Closest(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
|
||||||
match parse_author_origin_selector_list_from_str(&selectors) {
|
match parse_author_origin_selector_list_from_str(&selectors) {
|
||||||
Err(()) => Err(Syntax),
|
Err(()) => Err(Syntax),
|
||||||
Ok(ref selectors) => {
|
Ok(ref selectors) => {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root = NodeCast::from_ref(self);
|
||||||
for element in root.inclusive_ancestors() {
|
for element in root.inclusive_ancestors() {
|
||||||
let element = element.root();
|
|
||||||
if let Some(element) = ElementCast::to_ref(element.r()) {
|
if let Some(element) = ElementCast::to_ref(element.r()) {
|
||||||
if matches(selectors, &NodeCast::from_ref(element), &mut None) {
|
if matches(selectors, &NodeCast::from_ref(element), &mut None) {
|
||||||
return Ok(Some(Temporary::from_rooted(element)));
|
return Ok(Some(Root::from_ref(element)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1489,22 +1480,22 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, Element> {
|
impl<'a> VirtualMethods for &'a Element {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let node: &JSRef<Node> = NodeCast::from_borrowed_ref(self);
|
let node: &&Node = NodeCast::from_borrowed_ref(self);
|
||||||
Some(node as &VirtualMethods)
|
Some(node as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("style") => {
|
&atom!("style") => {
|
||||||
// Modifying the `style` attribute might change style.
|
// Modifying the `style` attribute might change style.
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let base_url = doc.r().url();
|
let base_url = doc.r().url();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
let style = Some(parse_style_attribute(&value, &base_url));
|
let style = Some(parse_style_attribute(&value, &base_url));
|
||||||
|
@ -1517,7 +1508,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
&atom!("class") => {
|
&atom!("class") => {
|
||||||
// Modifying a class can change style.
|
// Modifying a class can change style.
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let document = document_from_node(*self).root();
|
let document = document_from_node(*self);
|
||||||
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1525,7 +1516,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
// Modifying an ID might change style.
|
// Modifying an ID might change style.
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
let value = value.atom().unwrap().clone();
|
let value = value.atom().unwrap().clone();
|
||||||
doc.r().register_named_element(*self, value);
|
doc.r().register_named_element(*self, value);
|
||||||
|
@ -1536,26 +1527,26 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
_ => {
|
_ => {
|
||||||
// Modifying any other attribute might change arbitrary things.
|
// Modifying any other attribute might change arbitrary things.
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let document = document_from_node(*self).root();
|
let document = document_from_node(*self);
|
||||||
document.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
document.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("style") => {
|
&atom!("style") => {
|
||||||
// Modifying the `style` attribute might change style.
|
// Modifying the `style` attribute might change style.
|
||||||
*self.style_attribute.borrow_mut() = None;
|
*self.style_attribute.borrow_mut() = None;
|
||||||
|
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1563,7 +1554,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
// Modifying an ID can change style.
|
// Modifying an ID can change style.
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
let value = value.atom().unwrap().clone();
|
let value = value.atom().unwrap().clone();
|
||||||
doc.r().unregister_named_element(*self, value);
|
doc.r().unregister_named_element(*self, value);
|
||||||
|
@ -1574,14 +1565,14 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
&atom!("class") => {
|
&atom!("class") => {
|
||||||
// Modifying a class can change style.
|
// Modifying a class can change style.
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let document = document_from_node(*self).root();
|
let document = document_from_node(*self);
|
||||||
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Modifying any other attribute might change arbitrary things.
|
// Modifying any other attribute might change arbitrary things.
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
doc.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
doc.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1603,8 +1594,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
if !tree_in_doc { return; }
|
if !tree_in_doc { return; }
|
||||||
|
|
||||||
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")).root() {
|
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let value = attr.r().Value();
|
let value = attr.r().Value();
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
let value = Atom::from_slice(&value);
|
let value = Atom::from_slice(&value);
|
||||||
|
@ -1620,8 +1611,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
if !tree_in_doc { return; }
|
if !tree_in_doc { return; }
|
||||||
|
|
||||||
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")).root() {
|
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let value = attr.r().Value();
|
let value = attr.r().Value();
|
||||||
if !value.is_empty() {
|
if !value.is_empty() {
|
||||||
let value = Atom::from_slice(&value);
|
let value = Atom::from_slice(&value);
|
||||||
|
@ -1631,10 +1622,10 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
impl<'a> style::node::TElement<'a> for &'a Element {
|
||||||
fn is_link(self) -> bool {
|
fn is_link(self) -> bool {
|
||||||
// FIXME: This is HTML only.
|
// FIXME: This is HTML only.
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
match node.type_id() {
|
match node.type_id() {
|
||||||
// https://html.spec.whatwg.org/multipage/#selector-link
|
// https://html.spec.whatwg.org/multipage/#selector-link
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||||
|
@ -1675,19 +1666,18 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
||||||
get_namespace(self)
|
get_namespace(self)
|
||||||
}
|
}
|
||||||
fn get_hover_state(self) -> bool {
|
fn get_hover_state(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.get_hover_state()
|
node.get_hover_state()
|
||||||
}
|
}
|
||||||
fn get_focus_state(self) -> bool {
|
fn get_focus_state(self) -> bool {
|
||||||
// TODO: Also check whether the top-level browsing context has the system focus,
|
// TODO: Also check whether the top-level browsing context has the system focus,
|
||||||
// and whether this element is a browsing context container.
|
// and whether this element is a browsing context container.
|
||||||
// https://html.spec.whatwg.org/multipage/#selector-focus
|
// https://html.spec.whatwg.org/multipage/#selector-focus
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.get_focus_state()
|
node.get_focus_state()
|
||||||
}
|
}
|
||||||
fn get_id(self) -> Option<Atom> {
|
fn get_id(self) -> Option<Atom> {
|
||||||
self.get_attribute(&ns!(""), &atom!("id")).map(|attr| {
|
self.get_attribute(&ns!(""), &atom!("id")).map(|attr| {
|
||||||
let attr = attr.root();
|
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -1698,22 +1688,22 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn get_disabled_state(self) -> bool {
|
fn get_disabled_state(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.get_disabled_state()
|
node.get_disabled_state()
|
||||||
}
|
}
|
||||||
fn get_enabled_state(self) -> bool {
|
fn get_enabled_state(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.get_enabled_state()
|
node.get_enabled_state()
|
||||||
}
|
}
|
||||||
fn get_checked_state(self) -> bool {
|
fn get_checked_state(self) -> bool {
|
||||||
let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self);
|
let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self);
|
||||||
match input_element {
|
match input_element {
|
||||||
Some(input) => input.Checked(),
|
Some(input) => input.Checked(),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_indeterminate_state(self) -> bool {
|
fn get_indeterminate_state(self) -> bool {
|
||||||
let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self);
|
let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self);
|
||||||
match input_element {
|
match input_element {
|
||||||
Some(input) => input.get_indeterminate_state(),
|
Some(input) => input.get_indeterminate_state(),
|
||||||
None => false,
|
None => false,
|
||||||
|
@ -1731,7 +1721,7 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
||||||
fn each_class<F>(self, mut callback: F)
|
fn each_class<F>(self, mut callback: F)
|
||||||
where F: FnMut(&Atom)
|
where F: FnMut(&Atom)
|
||||||
{
|
{
|
||||||
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("class")).root() {
|
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("class")) {
|
||||||
if let Some(tokens) = attr.r().value().tokens() {
|
if let Some(tokens) = attr.r().value().tokens() {
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
callback(token)
|
callback(token)
|
||||||
|
@ -1740,7 +1730,7 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn has_nonzero_border(self) -> bool {
|
fn has_nonzero_border(self) -> bool {
|
||||||
let table_element: Option<JSRef<HTMLTableElement>> = HTMLTableElementCast::to_ref(self);
|
let table_element: Option<&HTMLTableElement> = HTMLTableElementCast::to_ref(self);
|
||||||
match table_element {
|
match table_element {
|
||||||
None => false,
|
None => false,
|
||||||
Some(this) => {
|
Some(this) => {
|
||||||
|
@ -1757,20 +1747,20 @@ pub trait ActivationElementHelpers<'a> {
|
||||||
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)>;
|
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)>;
|
||||||
fn click_in_progress(self) -> bool;
|
fn click_in_progress(self) -> bool;
|
||||||
fn set_click_in_progress(self, click: bool);
|
fn set_click_in_progress(self, click: bool);
|
||||||
fn nearest_activable_element(self) -> Option<Temporary<Element>>;
|
fn nearest_activable_element(self) -> Option<Root<Element>>;
|
||||||
fn authentic_click_activation<'b>(self, event: JSRef<'b, Event>);
|
fn authentic_click_activation<'b>(self, event: &'b Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> {
|
impl<'a> ActivationElementHelpers<'a> for &'a Element {
|
||||||
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)> {
|
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)> {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
let element = match node.type_id() {
|
let element = match node.type_id() {
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
|
||||||
let element: &'a JSRef<'a, HTMLInputElement> = HTMLInputElementCast::to_borrowed_ref(self).unwrap();
|
let element = HTMLInputElementCast::to_borrowed_ref(self).unwrap();
|
||||||
Some(element as &'a (Activatable + 'a))
|
Some(element as &'a (Activatable + 'a))
|
||||||
},
|
},
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => {
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => {
|
||||||
let element: &'a JSRef<'a, HTMLAnchorElement> = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap();
|
let element = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap();
|
||||||
Some(element as &'a (Activatable + 'a))
|
Some(element as &'a (Activatable + 'a))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1787,26 +1777,25 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn click_in_progress(self) -> bool {
|
fn click_in_progress(self) -> bool {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.get_flag(CLICK_IN_PROGRESS)
|
node.get_flag(CLICK_IN_PROGRESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_click_in_progress(self, click: bool) {
|
fn set_click_in_progress(self, click: bool) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.set_flag(CLICK_IN_PROGRESS, click)
|
node.set_flag(CLICK_IN_PROGRESS, click)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#nearest-activatable-element
|
// https://html.spec.whatwg.org/multipage/#nearest-activatable-element
|
||||||
fn nearest_activable_element(self) -> Option<Temporary<Element>> {
|
fn nearest_activable_element(self) -> Option<Root<Element>> {
|
||||||
match self.as_maybe_activatable() {
|
match self.as_maybe_activatable() {
|
||||||
Some(el) => Some(Temporary::from_rooted(el.as_element().root().r())),
|
Some(el) => Some(Root::from_ref(el.as_element())),
|
||||||
None => {
|
None => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
for node in node.ancestors() {
|
for node in node.ancestors() {
|
||||||
let node = node.root();
|
|
||||||
if let Some(node) = ElementCast::to_ref(node.r()) {
|
if let Some(node) = ElementCast::to_ref(node.r()) {
|
||||||
if node.as_maybe_activatable().is_some() {
|
if node.as_maybe_activatable().is_some() {
|
||||||
return Some(Temporary::from_rooted(node))
|
return Some(Root::from_ref(node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1821,19 +1810,19 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
///
|
///
|
||||||
/// Use an element's synthetic click activation (or handle_event) for any script-triggered clicks.
|
/// Use an element's synthetic click activation (or handle_event) for any script-triggered clicks.
|
||||||
/// If the spec says otherwise, check with Manishearth first
|
/// If the spec says otherwise, check with Manishearth first
|
||||||
fn authentic_click_activation<'b>(self, event: JSRef<'b, Event>) {
|
fn authentic_click_activation<'b>(self, event: &'b Event) {
|
||||||
// Not explicitly part of the spec, however this helps enforce the invariants
|
// Not explicitly part of the spec, however this helps enforce the invariants
|
||||||
// required to save state between pre-activation and post-activation
|
// required to save state between pre-activation and post-activation
|
||||||
// since we cannot nest authentic clicks (unlike synthetic click activation, where
|
// since we cannot nest authentic clicks (unlike synthetic click activation, where
|
||||||
// the script can generate more click events from the handler)
|
// the script can generate more click events from the handler)
|
||||||
assert!(!self.click_in_progress());
|
assert!(!self.click_in_progress());
|
||||||
|
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
// Step 2 (requires canvas support)
|
// Step 2 (requires canvas support)
|
||||||
// Step 3
|
// Step 3
|
||||||
self.set_click_in_progress(true);
|
self.set_click_in_progress(true);
|
||||||
// Step 4
|
// Step 4
|
||||||
let e = self.nearest_activable_element().root();
|
let e = self.nearest_activable_element();
|
||||||
match e {
|
match e {
|
||||||
Some(ref el) => match el.r().as_maybe_activatable() {
|
Some(ref el) => match el.r().as_maybe_activatable() {
|
||||||
Some(elem) => {
|
Some(elem) => {
|
||||||
|
|
|
@ -8,8 +8,8 @@ use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, ErrorEventDerived};
|
use dom::bindings::codegen::InheritTypes::{EventCast, ErrorEventDerived};
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, MutHeap, Rootable, Temporary};
|
use dom::bindings::js::{Root, MutHeapJSVal};
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::{JSContext, HandleValue};
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
|
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
|
@ -18,8 +18,8 @@ use util::str::DOMString;
|
||||||
|
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::{Cell};
|
use std::cell::Cell;
|
||||||
use js::jsval::{JSVal, NullValue};
|
use js::jsval::JSVal;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct ErrorEvent {
|
pub struct ErrorEvent {
|
||||||
|
@ -28,7 +28,7 @@ pub struct ErrorEvent {
|
||||||
filename: DOMRefCell<DOMString>,
|
filename: DOMRefCell<DOMString>,
|
||||||
lineno: Cell<u32>,
|
lineno: Cell<u32>,
|
||||||
colno: Cell<u32>,
|
colno: Cell<u32>,
|
||||||
error: MutHeap<JSVal>,
|
error: MutHeapJSVal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorEventDerived for Event {
|
impl ErrorEventDerived for Event {
|
||||||
|
@ -45,11 +45,11 @@ impl ErrorEvent {
|
||||||
filename: DOMRefCell::new("".to_owned()),
|
filename: DOMRefCell::new("".to_owned()),
|
||||||
lineno: Cell::new(0),
|
lineno: Cell::new(0),
|
||||||
colno: Cell::new(0),
|
colno: Cell::new(0),
|
||||||
error: MutHeap::new(NullValue())
|
error: MutHeapJSVal::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_uninitialized(global: GlobalRef) -> Temporary<ErrorEvent> {
|
pub fn new_uninitialized(global: GlobalRef) -> Root<ErrorEvent> {
|
||||||
reflect_dom_object(box ErrorEvent::new_inherited(EventTypeId::ErrorEvent),
|
reflect_dom_object(box ErrorEvent::new_inherited(EventTypeId::ErrorEvent),
|
||||||
global,
|
global,
|
||||||
ErrorEventBinding::Wrap)
|
ErrorEventBinding::Wrap)
|
||||||
|
@ -63,24 +63,26 @@ impl ErrorEvent {
|
||||||
filename: DOMString,
|
filename: DOMString,
|
||||||
lineno: u32,
|
lineno: u32,
|
||||||
colno: u32,
|
colno: u32,
|
||||||
error: JSVal) -> Temporary<ErrorEvent> {
|
error: HandleValue) -> Root<ErrorEvent> {
|
||||||
let ev = ErrorEvent::new_uninitialized(global).root();
|
let ev = ErrorEvent::new_uninitialized(global);
|
||||||
let event: JSRef<Event> = EventCast::from_ref(ev.r());
|
|
||||||
event.InitEvent(type_, bubbles == EventBubbles::Bubbles,
|
|
||||||
cancelable == EventCancelable::Cancelable);
|
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let ev = ev.r();
|
{
|
||||||
*ev.message.borrow_mut() = message;
|
let ev = ev.r();
|
||||||
*ev.filename.borrow_mut() = filename;
|
let event = EventCast::from_ref(ev);
|
||||||
ev.lineno.set(lineno);
|
event.InitEvent(type_, bubbles == EventBubbles::Bubbles,
|
||||||
ev.colno.set(colno);
|
cancelable == EventCancelable::Cancelable);
|
||||||
ev.error.set(error);
|
*ev.message.borrow_mut() = message;
|
||||||
Temporary::from_rooted(ev)
|
*ev.filename.borrow_mut() = filename;
|
||||||
|
ev.lineno.set(lineno);
|
||||||
|
ev.colno.set(colno);
|
||||||
|
}
|
||||||
|
ev.error.set(error.get());
|
||||||
|
ev
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef,
|
pub fn Constructor(global: GlobalRef,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Temporary<ErrorEvent>>{
|
init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Root<ErrorEvent>>{
|
||||||
let msg = match init.message.as_ref() {
|
let msg = match init.message.as_ref() {
|
||||||
Some(message) => message.clone(),
|
Some(message) => message.clone(),
|
||||||
None => "".to_owned(),
|
None => "".to_owned(),
|
||||||
|
@ -106,13 +108,14 @@ impl ErrorEvent {
|
||||||
let event = ErrorEvent::new(global, type_,
|
let event = ErrorEvent::new(global, type_,
|
||||||
bubbles, cancelable,
|
bubbles, cancelable,
|
||||||
msg, file_name,
|
msg, file_name,
|
||||||
line_num, col_num, init.error);
|
line_num, col_num,
|
||||||
|
HandleValue { ptr: &init.error });
|
||||||
Ok(event)
|
Ok(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ErrorEventMethods for JSRef<'a, ErrorEvent> {
|
impl<'a> ErrorEventMethods for &'a ErrorEvent {
|
||||||
fn Lineno(self) -> u32 {
|
fn Lineno(self) -> u32 {
|
||||||
self.lineno.get()
|
self.lineno.get()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::EventBinding;
|
||||||
use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods};
|
use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods};
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetHelpers};
|
use dom::eventtarget::{EventTarget, EventTargetHelpers};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
@ -95,7 +95,7 @@ impl Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_uninitialized(global: GlobalRef) -> Temporary<Event> {
|
pub fn new_uninitialized(global: GlobalRef) -> Root<Event> {
|
||||||
reflect_dom_object(box Event::new_inherited(EventTypeId::HTMLEvent),
|
reflect_dom_object(box Event::new_inherited(EventTypeId::HTMLEvent),
|
||||||
global,
|
global,
|
||||||
EventBinding::Wrap)
|
EventBinding::Wrap)
|
||||||
|
@ -104,15 +104,15 @@ impl Event {
|
||||||
pub fn new(global: GlobalRef,
|
pub fn new(global: GlobalRef,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
bubbles: EventBubbles,
|
bubbles: EventBubbles,
|
||||||
cancelable: EventCancelable) -> Temporary<Event> {
|
cancelable: EventCancelable) -> Root<Event> {
|
||||||
let event = Event::new_uninitialized(global).root();
|
let event = Event::new_uninitialized(global);
|
||||||
event.r().InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
|
event.r().InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable);
|
||||||
Temporary::from_rooted(event.r())
|
event
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef,
|
pub fn Constructor(global: GlobalRef,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
init: &EventBinding::EventInit) -> Fallible<Temporary<Event>> {
|
init: &EventBinding::EventInit) -> Fallible<Root<Event>> {
|
||||||
let bubbles = if init.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
|
let bubbles = if init.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble };
|
||||||
let cancelable = if init.cancelable { EventCancelable::Cancelable } else { EventCancelable::NotCancelable };
|
let cancelable = if init.cancelable { EventCancelable::Cancelable } else { EventCancelable::NotCancelable };
|
||||||
Ok(Event::new(global, type_, bubbles, cancelable))
|
Ok(Event::new(global, type_, bubbles, cancelable))
|
||||||
|
@ -129,13 +129,13 @@ impl Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_current_target(&self, val: JSRef<EventTarget>) {
|
pub fn set_current_target(&self, val: &EventTarget) {
|
||||||
self.current_target.set(Some(JS::from_rooted(val)));
|
self.current_target.set(Some(JS::from_ref(val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_target(&self, val: JSRef<EventTarget>) {
|
pub fn set_target(&self, val: &EventTarget) {
|
||||||
self.target.set(Some(JS::from_rooted(val)));
|
self.target.set(Some(JS::from_ref(val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -174,7 +174,7 @@ impl Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventMethods for JSRef<'a, Event> {
|
impl<'a> EventMethods for &'a Event {
|
||||||
// https://dom.spec.whatwg.org/#dom-event-eventphase
|
// https://dom.spec.whatwg.org/#dom-event-eventphase
|
||||||
fn EventPhase(self) -> u16 {
|
fn EventPhase(self) -> u16 {
|
||||||
self.phase.get() as u16
|
self.phase.get() as u16
|
||||||
|
@ -188,13 +188,13 @@ impl<'a> EventMethods for JSRef<'a, Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-event-target
|
// https://dom.spec.whatwg.org/#dom-event-target
|
||||||
fn GetTarget(self) -> Option<Temporary<EventTarget>> {
|
fn GetTarget(self) -> Option<Root<EventTarget>> {
|
||||||
self.target.get().map(Temporary::from_rooted)
|
self.target.get().map(Root::from_rooted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-event-currenttarget
|
// https://dom.spec.whatwg.org/#dom-event-currenttarget
|
||||||
fn GetCurrentTarget(self) -> Option<Temporary<EventTarget>> {
|
fn GetCurrentTarget(self) -> Option<Root<EventTarget>> {
|
||||||
self.current_target.get().map(Temporary::from_rooted)
|
self.current_target.get().map(Root::from_rooted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-event-defaultprevented
|
// https://dom.spec.whatwg.org/#dom-event-defaultprevented
|
||||||
|
@ -263,16 +263,16 @@ impl<'a> EventMethods for JSRef<'a, Event> {
|
||||||
|
|
||||||
pub trait EventHelpers {
|
pub trait EventHelpers {
|
||||||
fn set_trusted(self, trusted: bool);
|
fn set_trusted(self, trusted: bool);
|
||||||
fn fire(self, target: JSRef<EventTarget>) -> bool;
|
fn fire(self, target: &EventTarget) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventHelpers for JSRef<'a, Event> {
|
impl<'a> EventHelpers for &'a Event {
|
||||||
fn set_trusted(self, trusted: bool) {
|
fn set_trusted(self, trusted: bool) {
|
||||||
self.trusted.set(trusted);
|
self.trusted.set(trusted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event
|
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event
|
||||||
fn fire(self, target: JSRef<EventTarget>) -> bool {
|
fn fire(self, target: &EventTarget) -> bool {
|
||||||
self.set_trusted(true);
|
self.set_trusted(true);
|
||||||
target.dispatch_event(self)
|
target.dispatch_event(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::callback::ExceptionHandling::Report;
|
use dom::bindings::callback::ExceptionHandling::Report;
|
||||||
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast};
|
||||||
use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable};
|
use dom::bindings::js::JS;
|
||||||
use dom::bindings::trace::RootedVec;
|
use dom::bindings::trace::RootedVec;
|
||||||
use dom::eventtarget::{EventTarget, ListenerPhase};
|
use dom::eventtarget::{EventTarget, ListenerPhase};
|
||||||
use dom::event::{Event, EventPhase};
|
use dom::event::{Event, EventPhase};
|
||||||
|
@ -13,9 +13,9 @@ use dom::node::{Node, NodeHelpers};
|
||||||
use dom::virtualmethods::vtable_for;
|
use dom::virtualmethods::vtable_for;
|
||||||
|
|
||||||
// See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
|
// See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
|
||||||
pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
|
pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
|
||||||
pseudo_target: Option<JSRef<'b, EventTarget>>,
|
pseudo_target: Option<&'b EventTarget>,
|
||||||
event: JSRef<Event>) -> bool {
|
event: &Event) -> bool {
|
||||||
assert!(!event.dispatching());
|
assert!(!event.dispatching());
|
||||||
assert!(event.initialized());
|
assert!(event.initialized());
|
||||||
|
|
||||||
|
@ -31,9 +31,8 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
|
||||||
let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new();
|
let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new();
|
||||||
if let Some(target_node) = NodeCast::to_ref(target) {
|
if let Some(target_node) = NodeCast::to_ref(target) {
|
||||||
for ancestor in target_node.ancestors() {
|
for ancestor in target_node.ancestors() {
|
||||||
let ancestor = ancestor.root();
|
|
||||||
let ancestor_target = EventTargetCast::from_ref(ancestor.r());
|
let ancestor_target = EventTargetCast::from_ref(ancestor.r());
|
||||||
chain.push(JS::from_rooted(ancestor_target))
|
chain.push(JS::from_ref(ancestor_target))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,10 +112,10 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default action */
|
/* default action */
|
||||||
let target = event.GetTarget().root();
|
let target = event.GetTarget();
|
||||||
match target {
|
match target {
|
||||||
Some(ref target) => {
|
Some(ref target) => {
|
||||||
let node: Option<JSRef<Node>> = NodeCast::to_ref(target.r());
|
let node: Option<&Node> = NodeCast::to_ref(target.r());
|
||||||
match node {
|
match node {
|
||||||
Some(node) => {
|
Some(node) => {
|
||||||
let vtable = vtable_for(&node);
|
let vtable = vtable_for(&node);
|
||||||
|
|
|
@ -9,7 +9,6 @@ use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
|
||||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||||
use dom::bindings::error::{Fallible, report_pending_exception};
|
use dom::bindings::error::{Fallible, report_pending_exception};
|
||||||
use dom::bindings::error::Error::InvalidState;
|
use dom::bindings::error::Error::InvalidState;
|
||||||
use dom::bindings::js::JSRef;
|
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::event::{Event, EventHelpers};
|
use dom::event::{Event, EventHelpers};
|
||||||
use dom::eventdispatcher::dispatch_event;
|
use dom::eventdispatcher::dispatch_event;
|
||||||
|
@ -17,8 +16,10 @@ use dom::node::NodeTypeId;
|
||||||
use dom::workerglobalscope::WorkerGlobalScopeTypeId;
|
use dom::workerglobalscope::WorkerGlobalScopeTypeId;
|
||||||
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTargetTypeId;
|
use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTargetTypeId;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObject};
|
use js::jsapi::{CompileFunction, JS_GetFunctionObject};
|
||||||
use js::jsapi::{JSContext, JSObject};
|
use js::jsapi::{JSContext, RootedFunction, HandleObject};
|
||||||
|
use js::jsapi::{JSAutoCompartment, JSAutoRequest};
|
||||||
|
use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
|
@ -30,6 +31,7 @@ use std::default::Default;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::intrinsics;
|
use std::intrinsics;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -88,23 +90,23 @@ impl EventTargetTypeId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
pub enum EventListenerType {
|
pub enum EventListenerType {
|
||||||
Additive(EventListener),
|
Additive(Rc<EventListener>),
|
||||||
Inline(EventListener),
|
Inline(Rc<EventListener>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventListenerType {
|
impl EventListenerType {
|
||||||
fn get_listener(&self) -> EventListener {
|
fn get_listener(&self) -> Rc<EventListener> {
|
||||||
match *self {
|
match *self {
|
||||||
EventListenerType::Additive(listener) |
|
EventListenerType::Additive(ref listener) |
|
||||||
EventListenerType::Inline(listener) => listener
|
EventListenerType::Inline(ref listener) => listener.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
#[privatize]
|
#[privatize]
|
||||||
pub struct EventListenerEntry {
|
pub struct EventListenerEntry {
|
||||||
|
@ -128,14 +130,14 @@ impl EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListener>> {
|
pub fn get_listeners(&self, type_: &str) -> Option<Vec<Rc<EventListener>>> {
|
||||||
self.handlers.borrow().get(type_).map(|listeners| {
|
self.handlers.borrow().get(type_).map(|listeners| {
|
||||||
listeners.iter().map(|entry| entry.listener.get_listener()).collect()
|
listeners.iter().map(|entry| entry.listener.get_listener()).collect()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
|
pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
|
||||||
-> Option<Vec<EventListener>> {
|
-> Option<Vec<Rc<EventListener>>> {
|
||||||
self.handlers.borrow().get(type_).map(|listeners| {
|
self.handlers.borrow().get(type_).map(|listeners| {
|
||||||
let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
|
let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
|
||||||
filtered.map(|entry| entry.listener.get_listener()).collect()
|
filtered.map(|entry| entry.listener.get_listener()).collect()
|
||||||
|
@ -150,47 +152,47 @@ impl EventTarget {
|
||||||
|
|
||||||
pub trait EventTargetHelpers {
|
pub trait EventTargetHelpers {
|
||||||
fn dispatch_event_with_target(self,
|
fn dispatch_event_with_target(self,
|
||||||
target: JSRef<EventTarget>,
|
target: &EventTarget,
|
||||||
event: JSRef<Event>) -> bool;
|
event: &Event) -> bool;
|
||||||
fn dispatch_event(self, event: JSRef<Event>) -> bool;
|
fn dispatch_event(self, event: &Event) -> bool;
|
||||||
fn set_inline_event_listener(self,
|
fn set_inline_event_listener(self,
|
||||||
ty: DOMString,
|
ty: DOMString,
|
||||||
listener: Option<EventListener>);
|
listener: Option<Rc<EventListener>>);
|
||||||
fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener>;
|
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>>;
|
||||||
fn set_event_handler_uncompiled(self,
|
fn set_event_handler_uncompiled(self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
url: Url,
|
url: Url,
|
||||||
scope: *mut JSObject,
|
scope: HandleObject,
|
||||||
ty: &str,
|
ty: &str,
|
||||||
source: DOMString);
|
source: DOMString);
|
||||||
fn set_event_handler_common<T: CallbackContainer>(self, ty: &str,
|
fn set_event_handler_common<T: CallbackContainer>(self, ty: &str,
|
||||||
listener: Option<T>);
|
listener: Option<Rc<T>>);
|
||||||
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T>;
|
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>>;
|
||||||
|
|
||||||
fn has_handlers(self) -> bool;
|
fn has_handlers(self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
impl<'a> EventTargetHelpers for &'a EventTarget {
|
||||||
fn dispatch_event_with_target(self,
|
fn dispatch_event_with_target(self,
|
||||||
target: JSRef<EventTarget>,
|
target: &EventTarget,
|
||||||
event: JSRef<Event>) -> bool {
|
event: &Event) -> bool {
|
||||||
dispatch_event(self, Some(target), event)
|
dispatch_event(self, Some(target), event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_event(self, event: JSRef<Event>) -> bool {
|
fn dispatch_event(self, event: &Event) -> bool {
|
||||||
dispatch_event(self, None, event)
|
dispatch_event(self, None, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_inline_event_listener(self,
|
fn set_inline_event_listener(self,
|
||||||
ty: DOMString,
|
ty: DOMString,
|
||||||
listener: Option<EventListener>) {
|
listener: Option<Rc<EventListener>>) {
|
||||||
let mut handlers = self.handlers.borrow_mut();
|
let mut handlers = self.handlers.borrow_mut();
|
||||||
let entries = match handlers.entry(ty) {
|
let entries = match handlers.entry(ty) {
|
||||||
Occupied(entry) => entry.into_mut(),
|
Occupied(entry) => entry.into_mut(),
|
||||||
Vacant(entry) => entry.insert(vec!()),
|
Vacant(entry) => entry.insert(vec!()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let idx = entries.iter().position(|&entry| {
|
let idx = entries.iter().position(|ref entry| {
|
||||||
match entry.listener {
|
match entry.listener {
|
||||||
EventListenerType::Inline(_) => true,
|
EventListenerType::Inline(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -217,7 +219,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener> {
|
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>> {
|
||||||
let handlers = self.handlers.borrow();
|
let handlers = self.handlers.borrow();
|
||||||
let entries = handlers.get(&ty);
|
let entries = handlers.get(&ty);
|
||||||
entries.and_then(|entries| entries.iter().find(|entry| {
|
entries.and_then(|entries| entries.iter().find(|entry| {
|
||||||
|
@ -232,7 +234,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
||||||
fn set_event_handler_uncompiled(self,
|
fn set_event_handler_uncompiled(self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
url: Url,
|
url: Url,
|
||||||
scope: *mut JSObject,
|
scope: HandleObject,
|
||||||
ty: &str,
|
ty: &str,
|
||||||
source: DOMString) {
|
source: DOMString) {
|
||||||
let url = CString::new(url.serialize()).unwrap();
|
let url = CString::new(url.serialize()).unwrap();
|
||||||
|
@ -243,38 +245,42 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
||||||
static mut ARG_NAMES: [*const c_char; 1] = [b"event\0" as *const u8 as *const c_char];
|
static mut ARG_NAMES: [*const c_char; 1] = [b"event\0" as *const u8 as *const c_char];
|
||||||
|
|
||||||
let source: Vec<u16> = source.utf16_units().collect();
|
let source: Vec<u16> = source.utf16_units().collect();
|
||||||
let handler = unsafe {
|
let options = CompileOptionsWrapper::new(cx, url.as_ptr(), lineno);
|
||||||
JS_CompileUCFunction(cx,
|
let scopechain = AutoObjectVectorWrapper::new(cx);
|
||||||
ptr::null_mut(),
|
|
||||||
name.as_ptr(),
|
let _ar = JSAutoRequest::new(cx);
|
||||||
nargs,
|
let _ac = JSAutoCompartment::new(cx, scope.get());
|
||||||
ARG_NAMES.as_mut_ptr(),
|
let mut handler = RootedFunction::new(cx, ptr::null_mut());
|
||||||
source.as_ptr(),
|
let rv = unsafe {
|
||||||
source.len() as size_t,
|
CompileFunction(cx,
|
||||||
url.as_ptr(),
|
scopechain.ptr,
|
||||||
lineno)
|
options.ptr,
|
||||||
|
name.as_ptr(),
|
||||||
|
nargs,
|
||||||
|
ARG_NAMES.as_mut_ptr(),
|
||||||
|
source.as_ptr() as *const i16,
|
||||||
|
source.len() as size_t,
|
||||||
|
handler.handle_mut())
|
||||||
};
|
};
|
||||||
if handler.is_null() {
|
if rv == 0 || handler.ptr.is_null() {
|
||||||
report_pending_exception(cx, self.reflector().get_jsobject());
|
report_pending_exception(cx, self.reflector().get_jsobject().get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let funobj = unsafe {
|
let funobj = unsafe { JS_GetFunctionObject(handler.ptr) };
|
||||||
JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope)
|
|
||||||
};
|
|
||||||
assert!(!funobj.is_null());
|
assert!(!funobj.is_null());
|
||||||
self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
|
self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_event_handler_common<T: CallbackContainer>(
|
fn set_event_handler_common<T: CallbackContainer>(
|
||||||
self, ty: &str, listener: Option<T>)
|
self, ty: &str, listener: Option<Rc<T>>)
|
||||||
{
|
{
|
||||||
let event_listener = listener.map(|listener|
|
let event_listener = listener.map(|listener|
|
||||||
EventListener::new(listener.callback()));
|
EventListener::new(listener.callback()));
|
||||||
self.set_inline_event_listener(ty.to_owned(), event_listener);
|
self.set_inline_event_listener(ty.to_owned(), event_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T> {
|
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>> {
|
||||||
let listener = self.get_inline_event_listener(ty.to_owned());
|
let listener = self.get_inline_event_listener(ty.to_owned());
|
||||||
listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
|
listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
|
||||||
}
|
}
|
||||||
|
@ -286,10 +292,10 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
|
impl<'a> EventTargetMethods for &'a EventTarget {
|
||||||
fn AddEventListener(self,
|
fn AddEventListener(self,
|
||||||
ty: DOMString,
|
ty: DOMString,
|
||||||
listener: Option<EventListener>,
|
listener: Option<Rc<EventListener>>,
|
||||||
capture: bool) {
|
capture: bool) {
|
||||||
match listener {
|
match listener {
|
||||||
Some(listener) => {
|
Some(listener) => {
|
||||||
|
@ -314,17 +320,17 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
|
||||||
|
|
||||||
fn RemoveEventListener(self,
|
fn RemoveEventListener(self,
|
||||||
ty: DOMString,
|
ty: DOMString,
|
||||||
listener: Option<EventListener>,
|
listener: Option<Rc<EventListener>>,
|
||||||
capture: bool) {
|
capture: bool) {
|
||||||
match listener {
|
match listener {
|
||||||
Some(listener) => {
|
Some(ref listener) => {
|
||||||
let mut handlers = self.handlers.borrow_mut();
|
let mut handlers = self.handlers.borrow_mut();
|
||||||
let mut entry = handlers.get_mut(&ty);
|
let mut entry = handlers.get_mut(&ty);
|
||||||
for entry in entry.iter_mut() {
|
for entry in entry.iter_mut() {
|
||||||
let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling };
|
let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling };
|
||||||
let old_entry = EventListenerEntry {
|
let old_entry = EventListenerEntry {
|
||||||
phase: phase,
|
phase: phase,
|
||||||
listener: EventListenerType::Additive(listener)
|
listener: EventListenerType::Additive(listener.clone())
|
||||||
};
|
};
|
||||||
let position = entry.position_elem(&old_entry);
|
let position = entry.position_elem(&old_entry);
|
||||||
for &position in position.iter() {
|
for &position in position.iter() {
|
||||||
|
@ -336,7 +342,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn DispatchEvent(self, event: JSRef<Event>) -> Fallible<bool> {
|
fn DispatchEvent(self, event: &Event) -> Fallible<bool> {
|
||||||
if event.dispatching() || !event.initialized() {
|
if event.dispatching() || !event.initialized() {
|
||||||
return Err(InvalidState);
|
return Err(InvalidState);
|
||||||
}
|
}
|
||||||
|
@ -345,7 +351,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, EventTarget> {
|
impl<'a> VirtualMethods for &'a EventTarget {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::FileBinding;
|
use dom::bindings::codegen::Bindings::FileBinding;
|
||||||
use dom::bindings::codegen::Bindings::FileBinding::FileMethods;
|
use dom::bindings::codegen::Bindings::FileBinding::FileMethods;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::reflect_dom_object;
|
use dom::bindings::utils::reflect_dom_object;
|
||||||
use dom::blob::{Blob, BlobTypeId};
|
use dom::blob::{Blob, BlobTypeId};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
@ -18,7 +18,7 @@ pub struct File {
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
fn new_inherited(global: GlobalRef, type_: BlobTypeId,
|
fn new_inherited(global: GlobalRef, type_: BlobTypeId,
|
||||||
_file_bits: JSRef<Blob>, name: DOMString) -> File {
|
_file_bits: &Blob, name: DOMString) -> File {
|
||||||
File {
|
File {
|
||||||
//TODO: get type from the underlying filesystem instead of "".to_string()
|
//TODO: get type from the underlying filesystem instead of "".to_string()
|
||||||
blob: Blob::new_inherited(global, type_, None, ""),
|
blob: Blob::new_inherited(global, type_, None, ""),
|
||||||
|
@ -28,7 +28,7 @@ impl File {
|
||||||
// the relevant subfields of file_bits should be copied over
|
// the relevant subfields of file_bits should be copied over
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: GlobalRef, file_bits: JSRef<Blob>, name: DOMString) -> Temporary<File> {
|
pub fn new(global: GlobalRef, file_bits: &Blob, name: DOMString) -> Root<File> {
|
||||||
reflect_dom_object(box File::new_inherited(global, BlobTypeId::File, file_bits, name),
|
reflect_dom_object(box File::new_inherited(global, BlobTypeId::File, file_bits, name),
|
||||||
global,
|
global,
|
||||||
FileBinding::Wrap)
|
FileBinding::Wrap)
|
||||||
|
@ -39,7 +39,7 @@ impl File {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FileMethods for JSRef<'a, File> {
|
impl<'a> FileMethods for &'a File {
|
||||||
fn Name(self) -> DOMString {
|
fn Name(self) -> DOMString {
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::UnionTypes::FileOrString;
|
||||||
use dom::bindings::codegen::UnionTypes::FileOrString::{eFile, eString};
|
use dom::bindings::codegen::UnionTypes::FileOrString::{eFile, eString};
|
||||||
use dom::bindings::error::{Fallible};
|
use dom::bindings::error::{Fallible};
|
||||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||||
use dom::bindings::js::{JS, JSRef, Temporary, Unrooted};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::blob::Blob;
|
use dom::blob::Blob;
|
||||||
use dom::file::File;
|
use dom::file::File;
|
||||||
|
@ -38,29 +38,29 @@ pub struct FormData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormData {
|
impl FormData {
|
||||||
fn new_inherited(form: Option<JSRef<HTMLFormElement>>, global: GlobalRef) -> FormData {
|
fn new_inherited(form: Option<&HTMLFormElement>, global: GlobalRef) -> FormData {
|
||||||
FormData {
|
FormData {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
data: DOMRefCell::new(HashMap::new()),
|
data: DOMRefCell::new(HashMap::new()),
|
||||||
global: GlobalField::from_rooted(&global),
|
global: GlobalField::from_rooted(&global),
|
||||||
form: form.map(|f| JS::from_rooted(f)),
|
form: form.map(|f| JS::from_ref(f)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(form: Option<JSRef<HTMLFormElement>>, global: GlobalRef) -> Temporary<FormData> {
|
pub fn new(form: Option<&HTMLFormElement>, global: GlobalRef) -> Root<FormData> {
|
||||||
reflect_dom_object(box FormData::new_inherited(form, global),
|
reflect_dom_object(box FormData::new_inherited(form, global),
|
||||||
global, FormDataBinding::Wrap)
|
global, FormDataBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: GlobalRef, form: Option<JSRef<HTMLFormElement>>) -> Fallible<Temporary<FormData>> {
|
pub fn Constructor(global: GlobalRef, form: Option<&HTMLFormElement>) -> Fallible<Root<FormData>> {
|
||||||
Ok(FormData::new(form, global))
|
Ok(FormData::new(form, global))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FormDataMethods for JSRef<'a, FormData> {
|
impl<'a> FormDataMethods for &'a FormData {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
fn Append(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
|
fn Append(self, name: DOMString, value: &Blob, filename: Option<DOMString>) {
|
||||||
let file = FormDatum::FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
|
let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename)));
|
||||||
let mut data = self.data.borrow_mut();
|
let mut data = self.data.borrow_mut();
|
||||||
match data.entry(name) {
|
match data.entry(name) {
|
||||||
Occupied(entry) => entry.into_mut().push(file),
|
Occupied(entry) => entry.into_mut().push(file),
|
||||||
|
@ -90,7 +90,7 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> {
|
||||||
match data[&name][0].clone() {
|
match data[&name][0].clone() {
|
||||||
FormDatum::StringData(ref s) => Some(eString(s.clone())),
|
FormDatum::StringData(ref s) => Some(eString(s.clone())),
|
||||||
FormDatum::FileData(ref f) => {
|
FormDatum::FileData(ref f) => {
|
||||||
Some(eFile(Unrooted::from_js(*f)))
|
Some(eFile(f.root()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,8 +104,8 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> {
|
||||||
data.contains_key(&name)
|
data.contains_key(&name)
|
||||||
}
|
}
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
fn Set(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) {
|
fn Set(self, name: DOMString, value: &Blob, filename: Option<DOMString>) {
|
||||||
let file = FormDatum::FileData(JS::from_rooted(self.get_file_from_blob(value, filename)));
|
let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename)));
|
||||||
self.data.borrow_mut().insert(name, vec!(file));
|
self.data.borrow_mut().insert(name, vec!(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +115,13 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateFormDataHelpers{
|
trait PrivateFormDataHelpers{
|
||||||
fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File>;
|
fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrivateFormDataHelpers for FormData {
|
impl<'a> PrivateFormDataHelpers for &'a FormData {
|
||||||
fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File> {
|
fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File> {
|
||||||
let global = self.global.root();
|
let global = self.global.root();
|
||||||
let f: Option<JSRef<File>> = FileCast::to_ref(value);
|
let f: Option<&File> = FileCast::to_ref(value);
|
||||||
let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".to_owned()));
|
let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".to_owned()));
|
||||||
File::new(global.r(), value, name)
|
File::new(global.r(), value, name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLImageElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLImageElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{MouseEventCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{MouseEventCast, NodeCast};
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::js::OptionalRootable;
|
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::element::{Element, AttributeHandlers, ElementTypeId};
|
use dom::element::{Element, AttributeHandlers, ElementTypeId};
|
||||||
|
@ -47,7 +46,7 @@ impl HTMLAnchorElementDerived for EventTarget {
|
||||||
impl HTMLAnchorElement {
|
impl HTMLAnchorElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLAnchorElement {
|
document: &Document) -> HTMLAnchorElement {
|
||||||
HTMLAnchorElement {
|
HTMLAnchorElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLAnchorElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLAnchorElement, localName, prefix, document),
|
||||||
|
@ -58,19 +57,19 @@ impl HTMLAnchorElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLAnchorElement> {
|
document: &Document) -> Root<HTMLAnchorElement> {
|
||||||
let element = HTMLAnchorElement::new_inherited(localName, prefix, document);
|
let element = HTMLAnchorElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLAnchorElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLAnchorElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> {
|
impl<'a> VirtualMethods for &'a HTMLAnchorElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_event(&self, event: JSRef<Event>) {
|
fn handle_event(&self, event: &Event) {
|
||||||
match self.super_type() {
|
match self.super_type() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
s.handle_event(event);
|
s.handle_event(event);
|
||||||
|
@ -87,27 +86,27 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLAnchorElementMethods for JSRef<'a, HTMLAnchorElement> {
|
impl<'a> HTMLAnchorElementMethods for &'a HTMLAnchorElement {
|
||||||
fn Text(self) -> DOMString {
|
fn Text(self) -> DOMString {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.GetTextContent().unwrap()
|
node.GetTextContent().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetText(self, value: DOMString) {
|
fn SetText(self, value: DOMString) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.SetTextContent(Some(value))
|
node.SetTextContent(Some(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn RelList(self) -> Temporary<DOMTokenList> {
|
fn RelList(self) -> Root<DOMTokenList> {
|
||||||
self.rel_list.or_init(|| {
|
self.rel_list.or_init(|| {
|
||||||
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> {
|
impl<'a> Activatable for &'a HTMLAnchorElement {
|
||||||
fn as_element(&self) -> Temporary<Element> {
|
fn as_element<'b>(&'b self) -> &'b Element {
|
||||||
Temporary::from_rooted(ElementCast::from_ref(*self))
|
ElementCast::from_ref(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_instance_activatable(&self) -> bool {
|
fn is_instance_activatable(&self) -> bool {
|
||||||
|
@ -125,22 +124,22 @@ impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://html.spec.whatwg.org/multipage/#the-a-element:activation-behaviour
|
//https://html.spec.whatwg.org/multipage/#the-a-element:activation-behaviour
|
||||||
fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>) {
|
fn activation_behavior(&self, event: &Event, target: &EventTarget) {
|
||||||
//Step 1. If the node document is not fully active, abort.
|
//Step 1. If the node document is not fully active, abort.
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
if !doc.r().is_fully_active() {
|
if !doc.r().is_fully_active() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//TODO: Step 2. Check if browsing context is specified and act accordingly.
|
//TODO: Step 2. Check if browsing context is specified and act accordingly.
|
||||||
//Step 3. Handle <img ismap/>.
|
//Step 3. Handle <img ismap/>.
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(*self);
|
let element = ElementCast::from_ref(*self);
|
||||||
let mouse_event = MouseEventCast::to_ref(event).unwrap();
|
let mouse_event = MouseEventCast::to_ref(event).unwrap();
|
||||||
let mut ismap_suffix = None;
|
let mut ismap_suffix = None;
|
||||||
if let Some(element) = ElementCast::to_ref(target) {
|
if let Some(element) = ElementCast::to_ref(target) {
|
||||||
if target.is_htmlimageelement() && element.has_attribute(&atom!("ismap")) {
|
if target.is_htmlimageelement() && element.has_attribute(&atom!("ismap")) {
|
||||||
|
|
||||||
let target_node = NodeCast::to_ref(target).unwrap();
|
let target_node = NodeCast::to_ref(target).unwrap();
|
||||||
let rect = window_from_node(target_node).root().r().content_box_query(
|
let rect = window_from_node(target_node).r().content_box_query(
|
||||||
target_node.to_trusted_node_address());
|
target_node.to_trusted_node_address());
|
||||||
ismap_suffix = Some(
|
ismap_suffix = Some(
|
||||||
format!("?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(),
|
format!("?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(),
|
||||||
|
@ -151,7 +150,7 @@ impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> {
|
||||||
|
|
||||||
//TODO: Step 4. Download the link is `download` attribute is set.
|
//TODO: Step 4. Download the link is `download` attribute is set.
|
||||||
|
|
||||||
let attr = element.get_attribute(&ns!(""), &atom!("href")).root();
|
let attr = element.get_attribute(&ns!(""), &atom!("href"));
|
||||||
match attr {
|
match attr {
|
||||||
Some(ref href) => {
|
Some(ref href) => {
|
||||||
let value = href.r().Value() + ismap_suffix.as_ref().map(|s| &**s).unwrap_or("");
|
let value = href.r().Value() + ismap_suffix.as_ref().map(|s| &**s).unwrap_or("");
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLAppletElementBinding::HTMLAppletElemen
|
||||||
use dom::attr::AttrValue;
|
use dom::attr::AttrValue;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
|
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, ElementTypeId};
|
use dom::element::{AttributeHandlers, ElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLAppletElementDerived for EventTarget {
|
||||||
impl HTMLAppletElement {
|
impl HTMLAppletElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLAppletElement {
|
document: &Document) -> HTMLAppletElement {
|
||||||
HTMLAppletElement {
|
HTMLAppletElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLAppletElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLAppletElement, localName, prefix, document)
|
||||||
|
@ -45,19 +45,19 @@ impl HTMLAppletElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLAppletElement> {
|
document: &Document) -> Root<HTMLAppletElement> {
|
||||||
let element = HTMLAppletElement::new_inherited(localName, prefix, document);
|
let element = HTMLAppletElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLAppletElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLAppletElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLAppletElementMethods for JSRef<'a, HTMLAppletElement> {
|
impl<'a> HTMLAppletElementMethods for &'a HTMLAppletElement {
|
||||||
// https://html.spec.whatwg.org/#the-applet-element:dom-applet-name
|
// https://html.spec.whatwg.org/#the-applet-element:dom-applet-name
|
||||||
make_getter!(Name);
|
make_getter!(Name);
|
||||||
make_atomic_setter!(SetName, "name");
|
make_atomic_setter!(SetName, "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLAppletElement> {
|
impl<'a> VirtualMethods for &'a HTMLAppletElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
|
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLAreaElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLElementCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLElementCast};
|
||||||
use dom::bindings::codegen::InheritTypes::ElementCast;
|
use dom::bindings::codegen::InheritTypes::ElementCast;
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::utils::Reflectable;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
|
@ -36,7 +36,7 @@ impl HTMLAreaElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLAreaElement {
|
impl HTMLAreaElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLAreaElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLAreaElement {
|
||||||
HTMLAreaElement {
|
HTMLAreaElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLAreaElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLAreaElement, localName, prefix, document),
|
||||||
rel_list: Default::default(),
|
rel_list: Default::default(),
|
||||||
|
@ -46,15 +46,15 @@ impl HTMLAreaElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLAreaElement> {
|
document: &Document) -> Root<HTMLAreaElement> {
|
||||||
let element = HTMLAreaElement::new_inherited(localName, prefix, document);
|
let element = HTMLAreaElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLAreaElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLAreaElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLAreaElement> {
|
impl<'a> VirtualMethods for &'a HTMLAreaElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLAreaElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLAreaElementMethods for JSRef<'a, HTMLAreaElement> {
|
impl<'a> HTMLAreaElementMethods for &'a HTMLAreaElement {
|
||||||
fn RelList(self) -> Temporary<DOMTokenList> {
|
fn RelList(self) -> Root<DOMTokenList> {
|
||||||
self.rel_list.or_init(|| {
|
self.rel_list.or_init(|| {
|
||||||
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLAudioElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLAudioElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -30,7 +30,7 @@ impl HTMLAudioElementDerived for EventTarget {
|
||||||
impl HTMLAudioElement {
|
impl HTMLAudioElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLAudioElement {
|
document: &Document) -> HTMLAudioElement {
|
||||||
HTMLAudioElement {
|
HTMLAudioElement {
|
||||||
htmlmediaelement:
|
htmlmediaelement:
|
||||||
HTMLMediaElement::new_inherited(HTMLMediaElementTypeId::HTMLAudioElement, localName, prefix, document)
|
HTMLMediaElement::new_inherited(HTMLMediaElementTypeId::HTMLAudioElement, localName, prefix, document)
|
||||||
|
@ -40,7 +40,7 @@ impl HTMLAudioElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLAudioElement> {
|
document: &Document) -> Root<HTMLAudioElement> {
|
||||||
let element = HTMLAudioElement::new_inherited(localName, prefix, document);
|
let element = HTMLAudioElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLAudioElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLAudioElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLBaseElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLBaseElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLBaseElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLBaseElement {
|
impl HTMLBaseElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLBaseElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLBaseElement {
|
||||||
HTMLBaseElement {
|
HTMLBaseElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBaseElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBaseElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLBaseElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLBaseElement> {
|
document: &Document) -> Root<HTMLBaseElement> {
|
||||||
let element = HTMLBaseElement::new_inherited(localName, prefix, document);
|
let element = HTMLBaseElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLBaseElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLBaseElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyEle
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast};
|
use dom::bindings::codegen::InheritTypes::{EventTargetCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast};
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::utils::Reflectable;
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -25,6 +25,7 @@ use util::str::{self, DOMString};
|
||||||
|
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::rc::Rc;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
/// How long we should wait before performing the initial reflow after `<body>` is parsed, in
|
/// How long we should wait before performing the initial reflow after `<body>` is parsed, in
|
||||||
|
@ -45,7 +46,7 @@ impl HTMLBodyElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLBodyElement {
|
impl HTMLBodyElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document)
|
||||||
-> HTMLBodyElement {
|
-> HTMLBodyElement {
|
||||||
HTMLBodyElement {
|
HTMLBodyElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBodyElement,
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBodyElement,
|
||||||
|
@ -57,43 +58,43 @@ impl HTMLBodyElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
|
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document)
|
||||||
-> Temporary<HTMLBodyElement> {
|
-> Root<HTMLBodyElement> {
|
||||||
let element = HTMLBodyElement::new_inherited(localName, prefix, document);
|
let element = HTMLBodyElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLBodyElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLBodyElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLBodyElementMethods for JSRef<'a, HTMLBodyElement> {
|
impl<'a> HTMLBodyElementMethods for &'a HTMLBodyElement {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/#dom-body-bgcolor
|
// https://html.spec.whatwg.org/#dom-body-bgcolor
|
||||||
make_getter!(BgColor, "bgcolor");
|
make_getter!(BgColor, "bgcolor");
|
||||||
make_setter!(SetBgColor, "bgcolor");
|
make_setter!(SetBgColor, "bgcolor");
|
||||||
|
|
||||||
fn GetOnunload(self) -> Option<EventHandlerNonNull> {
|
fn GetOnunload(self) -> Option<Rc<EventHandlerNonNull>> {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
win.r().GetOnunload()
|
win.r().GetOnunload()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetOnunload(self, listener: Option<EventHandlerNonNull>) {
|
fn SetOnunload(self, listener: Option<Rc<EventHandlerNonNull>>) {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
win.r().SetOnunload(listener)
|
win.r().SetOnunload(listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HTMLBodyElementHelpers {
|
pub trait HTMLBodyElementHelpers {
|
||||||
fn get_background_color(&self) -> Option<RGBA>;
|
fn get_background_color(self) -> Option<RGBA>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLBodyElementHelpers for HTMLBodyElement {
|
impl<'a> HTMLBodyElementHelpers for &'a HTMLBodyElement {
|
||||||
fn get_background_color(&self) -> Option<RGBA> {
|
fn get_background_color(self) -> Option<RGBA> {
|
||||||
self.background_color.get()
|
self.background_color.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
|
impl<'a> VirtualMethods for &'a HTMLBodyElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(element as &VirtualMethods)
|
Some(element as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,15 +107,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let window = window_from_node(*self).root();
|
let window = window_from_node(*self);
|
||||||
let document = window.r().Document().root();
|
let document = window.r().Document();
|
||||||
document.r().set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
document.r().set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
|
||||||
let ConstellationChan(ref chan) = window.r().constellation_chan();
|
let ConstellationChan(ref chan) = window.r().constellation_chan();
|
||||||
let event = ConstellationMsg::HeadParsed;
|
let event = ConstellationMsg::HeadParsed;
|
||||||
chan.send(event).unwrap();
|
chan.send(event).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -126,11 +127,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
|
||||||
"onbeforeunload", "onhashchange", "onlanguagechange", "onmessage",
|
"onbeforeunload", "onhashchange", "onlanguagechange", "onmessage",
|
||||||
"onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate",
|
"onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate",
|
||||||
"onstorage", "onresize", "onunload", "onerror"];
|
"onstorage", "onresize", "onunload", "onerror"];
|
||||||
let window = window_from_node(*self).root();
|
let window = window_from_node(*self);
|
||||||
let (cx, url, reflector) = (window.r().get_cx(),
|
let (cx, url, reflector) = (window.r().get_cx(),
|
||||||
window.r().get_url(),
|
window.r().get_url(),
|
||||||
window.r().reflector().get_jsobject());
|
window.r().reflector().get_jsobject());
|
||||||
let evtarget: JSRef<EventTarget> =
|
let evtarget =
|
||||||
if FORWARDED_EVENTS.iter().any(|&event| &**name == event) {
|
if FORWARDED_EVENTS.iter().any(|&event| &**name == event) {
|
||||||
EventTargetCast::from_ref(window.r())
|
EventTargetCast::from_ref(window.r())
|
||||||
} else {
|
} else {
|
||||||
|
@ -149,7 +150,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
match self.super_type() {
|
match self.super_type() {
|
||||||
Some(ref s) => s.before_remove_attr(attr),
|
Some(ref s) => s.before_remove_attr(attr),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLBRElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLBRElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLBRElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLBRElement {
|
impl HTMLBRElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLBRElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLBRElement {
|
||||||
HTMLBRElement {
|
HTMLBRElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBRElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBRElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLBRElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLBRElement> {
|
document: &Document) -> Root<HTMLBRElement> {
|
||||||
let element = HTMLBRElement::new_inherited(localName, prefix, document);
|
let element = HTMLBRElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLBRElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLBRElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLButtonElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLButtonElementCast, NodeCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, Element, ElementTypeId};
|
use dom::element::{AttributeHandlers, Element, ElementTypeId};
|
||||||
use dom::element::ActivationElementHelpers;
|
use dom::element::ActivationElementHelpers;
|
||||||
|
@ -54,7 +54,7 @@ impl HTMLButtonElementDerived for EventTarget {
|
||||||
impl HTMLButtonElement {
|
impl HTMLButtonElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLButtonElement {
|
document: &Document) -> HTMLButtonElement {
|
||||||
HTMLButtonElement {
|
HTMLButtonElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLButtonElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLButtonElement, localName, prefix, document),
|
||||||
|
@ -66,15 +66,15 @@ impl HTMLButtonElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLButtonElement> {
|
document: &Document) -> Root<HTMLButtonElement> {
|
||||||
let element = HTMLButtonElement::new_inherited(localName, prefix, document);
|
let element = HTMLButtonElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLButtonElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLButtonElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> {
|
impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement {
|
||||||
fn Validity(self) -> Temporary<ValidityState> {
|
fn Validity(self) -> Root<ValidityState> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
ValidityState::new(window.r())
|
ValidityState::new(window.r())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-button-type
|
// https://html.spec.whatwg.org/multipage/#dom-button-type
|
||||||
fn Type(self) -> DOMString {
|
fn Type(self) -> DOMString {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lowercase();
|
let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lowercase();
|
||||||
// https://html.spec.whatwg.org/multipage/#attr-button-type
|
// https://html.spec.whatwg.org/multipage/#attr-button-type
|
||||||
match &*ty {
|
match &*ty {
|
||||||
|
@ -129,20 +129,20 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
make_setter!(SetValue, "value");
|
make_setter!(SetValue, "value");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
impl<'a> VirtualMethods for &'a HTMLButtonElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(true);
|
node.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
node.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
|
@ -150,14 +150,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(false);
|
node.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
node.set_enabled_state(true);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
|
@ -171,7 +171,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +180,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
s.unbind_from_tree(tree_in_doc);
|
s.unbind_from_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) {
|
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
} else {
|
} else {
|
||||||
node.check_disabled_attribute();
|
node.check_disabled_attribute();
|
||||||
|
@ -189,20 +189,20 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FormControl<'a> for JSRef<'a, HTMLButtonElement> {
|
impl<'a> FormControl<'a> for &'a HTMLButtonElement {
|
||||||
fn to_element(self) -> JSRef<'a, Element> {
|
fn to_element(self) -> &'a Element {
|
||||||
ElementCast::from_ref(self)
|
ElementCast::from_ref(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Activatable for JSRef<'a, HTMLButtonElement> {
|
impl<'a> Activatable for &'a HTMLButtonElement {
|
||||||
fn as_element(&self) -> Temporary<Element> {
|
fn as_element<'b>(&'b self) -> &'b Element {
|
||||||
Temporary::from_rooted(ElementCast::from_ref(*self))
|
ElementCast::from_ref(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_instance_activatable(&self) -> bool {
|
fn is_instance_activatable(&self) -> bool {
|
||||||
//https://html.spec.whatwg.org/multipage/#the-button-element
|
//https://html.spec.whatwg.org/multipage/#the-button-element
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
!(node.get_disabled_state())
|
!(node.get_disabled_state())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,14 +216,14 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
||||||
fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) {
|
fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
|
||||||
let ty = self.button_type.get();
|
let ty = self.button_type.get();
|
||||||
match ty {
|
match ty {
|
||||||
//https://html.spec.whatwg.org/multipage/#attr-button-type-submit-state
|
//https://html.spec.whatwg.org/multipage/#attr-button-type-submit-state
|
||||||
ButtonType::ButtonSubmit => {
|
ButtonType::ButtonSubmit => {
|
||||||
self.form_owner().map(|o| {
|
self.form_owner().map(|o| {
|
||||||
o.root().r().submit(SubmittedFrom::NotFromFormSubmitMethod,
|
o.r().submit(SubmittedFrom::NotFromFormSubmitMethod,
|
||||||
FormSubmitter::ButtonElement(self.clone()))
|
FormSubmitter::ButtonElement(self.clone()))
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
|
@ -233,10 +233,10 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
let node = NodeCast::from_ref(doc.r());
|
||||||
let owner = self.form_owner();
|
let owner = self.form_owner();
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(*self);
|
let elem = ElementCast::from_ref(*self);
|
||||||
if owner.is_none() || elem.click_in_progress() {
|
if owner.is_none() || elem.click_in_progress() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -244,8 +244,7 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> {
|
||||||
// and only then performing actions which may modify the DOM tree
|
// and only then performing actions which may modify the DOM tree
|
||||||
unsafe {
|
unsafe {
|
||||||
node.query_selector_iter("button[type=submit]".to_owned()).unwrap()
|
node.query_selector_iter("button[type=submit]".to_owned()).unwrap()
|
||||||
.filter_map(HTMLButtonElementCast::to_temporary)
|
.filter_map(HTMLButtonElementCast::to_root)
|
||||||
.map(|t| t.root())
|
|
||||||
.find(|r| r.r().form_owner() == owner)
|
.find(|r| r.r().form_owner() == owner)
|
||||||
.map(|s| s.r().synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey));
|
.map(|s| s.r().synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,11 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
||||||
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap, HeapGCValue, Rootable};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, HeapGCValue, Root};
|
||||||
use dom::bindings::js::Temporary;
|
|
||||||
use dom::bindings::js::Unrooted;
|
|
||||||
use dom::bindings::utils::{Reflectable};
|
use dom::bindings::utils::{Reflectable};
|
||||||
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{Element, AttributeHandlers};
|
use dom::element::AttributeHandlers;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
||||||
|
@ -27,7 +25,7 @@ use dom::virtualmethods::VirtualMethods;
|
||||||
use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderingContextHelpers};
|
use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderingContextHelpers};
|
||||||
|
|
||||||
use util::str::{DOMString, parse_unsigned_integer};
|
use util::str::{DOMString, parse_unsigned_integer};
|
||||||
use js::jsapi::{JSContext};
|
use js::jsapi::{JSContext, HandleValue};
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use offscreen_gl_context::GLContextAttributes;
|
use offscreen_gl_context::GLContextAttributes;
|
||||||
|
|
||||||
|
@ -58,6 +56,12 @@ pub struct HTMLCanvasElement {
|
||||||
height: Cell<u32>,
|
height: Cell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLCanvasElement {
|
||||||
|
fn eq(&self, other: &HTMLCanvasElement) -> bool {
|
||||||
|
self as *const HTMLCanvasElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HTMLCanvasElementDerived for EventTarget {
|
impl HTMLCanvasElementDerived for EventTarget {
|
||||||
fn is_htmlcanvaselement(&self) -> bool {
|
fn is_htmlcanvaselement(&self) -> bool {
|
||||||
*self.type_id() ==
|
*self.type_id() ==
|
||||||
|
@ -69,7 +73,7 @@ impl HTMLCanvasElementDerived for EventTarget {
|
||||||
impl HTMLCanvasElement {
|
impl HTMLCanvasElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLCanvasElement {
|
document: &Document) -> HTMLCanvasElement {
|
||||||
HTMLCanvasElement {
|
HTMLCanvasElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLCanvasElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLCanvasElement, localName, prefix, document),
|
||||||
|
@ -82,7 +86,7 @@ impl HTMLCanvasElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLCanvasElement> {
|
document: &Document) -> Root<HTMLCanvasElement> {
|
||||||
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
let element = HTMLCanvasElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -139,37 +143,37 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HTMLCanvasElementHelpers {
|
pub trait HTMLCanvasElementHelpers {
|
||||||
fn get_or_init_2d_context(self) -> Option<Temporary<CanvasRenderingContext2D>>;
|
fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>>;
|
||||||
fn get_or_init_webgl_context(self,
|
fn get_or_init_webgl_context(self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
attrs: Option<&JSVal>) -> Option<Temporary<WebGLRenderingContext>>;
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>>;
|
||||||
fn is_valid(self) -> bool;
|
fn is_valid(self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> {
|
impl<'a> HTMLCanvasElementHelpers for &'a HTMLCanvasElement {
|
||||||
fn get_or_init_2d_context(self) -> Option<Temporary<CanvasRenderingContext2D>> {
|
fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||||
if self.context.get().is_none() {
|
if self.context.get().is_none() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let size = self.get_size();
|
let size = self.get_size();
|
||||||
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||||
self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(context))));
|
self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(&context))));
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.context.get().unwrap() {
|
match self.context.get().unwrap() {
|
||||||
CanvasContext::Context2d(context) => Some(Temporary::from_rooted(context)),
|
CanvasContext::Context2d(context) => Some(context.root()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_init_webgl_context(self,
|
fn get_or_init_webgl_context(self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
attrs: Option<&JSVal>) -> Option<Temporary<WebGLRenderingContext>> {
|
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||||
if self.context.get().is_none() {
|
if self.context.get().is_none() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let size = self.get_size();
|
let size = self.get_size();
|
||||||
|
|
||||||
let attrs = if let Some(webgl_attributes) = attrs {
|
let attrs = if let Some(webgl_attributes) = attrs {
|
||||||
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, *webgl_attributes) {
|
if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) {
|
||||||
From::from(attrs)
|
From::from(attrs)
|
||||||
} else {
|
} else {
|
||||||
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||||
|
@ -181,12 +185,12 @@ impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> {
|
||||||
|
|
||||||
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||||
|
|
||||||
self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(ctx))));
|
self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(context) = self.context.get() {
|
if let Some(context) = self.context.get() {
|
||||||
match context {
|
match context {
|
||||||
CanvasContext::WebGL(context) => Some(Temporary::from_rooted(context)),
|
CanvasContext::WebGL(context) => Some(context.root()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,13 +203,13 @@ impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
|
impl<'a> HTMLCanvasElementMethods for &'a HTMLCanvasElement {
|
||||||
fn Width(self) -> u32 {
|
fn Width(self) -> u32 {
|
||||||
self.width.get()
|
self.width.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetWidth(self, width: u32) {
|
fn SetWidth(self, width: u32) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.set_uint_attribute(&atom!("width"), width)
|
elem.set_uint_attribute(&atom!("width"), width)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,38 +218,38 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetHeight(self, height: u32) {
|
fn SetHeight(self, height: u32) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.set_uint_attribute(&atom!("height"), height)
|
elem.set_uint_attribute(&atom!("height"), height)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetContext(self,
|
fn GetContext(self,
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
id: DOMString,
|
id: DOMString,
|
||||||
attributes: Vec<JSVal>)
|
attributes: Vec<HandleValue>)
|
||||||
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
-> Option<CanvasRenderingContext2DOrWebGLRenderingContext> {
|
||||||
match &*id {
|
match &*id {
|
||||||
"2d" => {
|
"2d" => {
|
||||||
self.get_or_init_2d_context()
|
self.get_or_init_2d_context()
|
||||||
.map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(
|
.map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(
|
||||||
Unrooted::from_temporary(ctx)))
|
ctx))
|
||||||
}
|
}
|
||||||
"webgl" | "experimental-webgl" => {
|
"webgl" | "experimental-webgl" => {
|
||||||
self.get_or_init_webgl_context(cx, attributes.get(0))
|
self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p))
|
||||||
.map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(
|
.map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(
|
||||||
Unrooted::from_temporary(ctx)))
|
ctx))
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> {
|
impl<'a> VirtualMethods for &'a HTMLCanvasElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(element as &VirtualMethods)
|
Some(element as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +271,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLCollectionBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
|
use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, Rootable, Temporary};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||||
use dom::element::{Element, AttributeHandlers, ElementHelpers};
|
use dom::element::{Element, AttributeHandlers, ElementHelpers};
|
||||||
|
@ -20,7 +20,7 @@ use std::iter::{FilterMap, Skip};
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
|
|
||||||
pub trait CollectionFilter : JSTraceable {
|
pub trait CollectionFilter : JSTraceable {
|
||||||
fn filter<'a>(&self, elem: JSRef<'a, Element>, root: JSRef<'a, Node>) -> bool;
|
fn filter<'a>(&self, elem: &'a Element, root: &'a Node) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
|
@ -44,26 +44,26 @@ impl HTMLCollection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(window: JSRef<Window>, collection: CollectionTypeId) -> Temporary<HTMLCollection> {
|
pub fn new(window: &Window, collection: CollectionTypeId) -> Root<HTMLCollection> {
|
||||||
reflect_dom_object(box HTMLCollection::new_inherited(collection),
|
reflect_dom_object(box HTMLCollection::new_inherited(collection),
|
||||||
GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
|
GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLCollection {
|
impl HTMLCollection {
|
||||||
pub fn create(window: JSRef<Window>, root: JSRef<Node>,
|
pub fn create(window: &Window, root: &Node,
|
||||||
filter: Box<CollectionFilter+'static>) -> Temporary<HTMLCollection> {
|
filter: Box<CollectionFilter+'static>) -> Root<HTMLCollection> {
|
||||||
HTMLCollection::new(window, CollectionTypeId::Live(JS::from_rooted(root), filter))
|
HTMLCollection::new(window, CollectionTypeId::Live(JS::from_ref(root), filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_elements(window: JSRef<Window>, root: JSRef<Node>,
|
fn all_elements(window: &Window, root: &Node,
|
||||||
namespace_filter: Option<Namespace>) -> Temporary<HTMLCollection> {
|
namespace_filter: Option<Namespace>) -> Root<HTMLCollection> {
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct AllElementFilter {
|
struct AllElementFilter {
|
||||||
namespace_filter: Option<Namespace>
|
namespace_filter: Option<Namespace>
|
||||||
}
|
}
|
||||||
impl CollectionFilter for AllElementFilter {
|
impl CollectionFilter for AllElementFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, _root: &Node) -> bool {
|
||||||
match self.namespace_filter {
|
match self.namespace_filter {
|
||||||
None => true,
|
None => true,
|
||||||
Some(ref namespace) => *elem.namespace() == *namespace
|
Some(ref namespace) => *elem.namespace() == *namespace
|
||||||
|
@ -74,8 +74,8 @@ impl HTMLCollection {
|
||||||
HTMLCollection::create(window, root, box filter)
|
HTMLCollection::create(window, root, box filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_tag_name(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString)
|
pub fn by_tag_name(window: &Window, root: &Node, tag: DOMString)
|
||||||
-> Temporary<HTMLCollection> {
|
-> Root<HTMLCollection> {
|
||||||
if tag == "*" {
|
if tag == "*" {
|
||||||
return HTMLCollection::all_elements(window, root, None);
|
return HTMLCollection::all_elements(window, root, None);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl HTMLCollection {
|
||||||
ascii_lower_tag: Atom,
|
ascii_lower_tag: Atom,
|
||||||
}
|
}
|
||||||
impl CollectionFilter for TagNameFilter {
|
impl CollectionFilter for TagNameFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, _root: &Node) -> bool {
|
||||||
if elem.html_element_in_html_document() {
|
if elem.html_element_in_html_document() {
|
||||||
*elem.local_name() == self.ascii_lower_tag
|
*elem.local_name() == self.ascii_lower_tag
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,8 +101,8 @@ impl HTMLCollection {
|
||||||
HTMLCollection::create(window, root, box filter)
|
HTMLCollection::create(window, root, box filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_tag_name_ns(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString,
|
pub fn by_tag_name_ns(window: &Window, root: &Node, tag: DOMString,
|
||||||
maybe_ns: Option<DOMString>) -> Temporary<HTMLCollection> {
|
maybe_ns: Option<DOMString>) -> Root<HTMLCollection> {
|
||||||
let namespace_filter = match maybe_ns {
|
let namespace_filter = match maybe_ns {
|
||||||
Some(ref namespace) if namespace == &"*" => None,
|
Some(ref namespace) if namespace == &"*" => None,
|
||||||
ns => Some(namespace::from_domstring(ns)),
|
ns => Some(namespace::from_domstring(ns)),
|
||||||
|
@ -117,7 +117,7 @@ impl HTMLCollection {
|
||||||
namespace_filter: Option<Namespace>
|
namespace_filter: Option<Namespace>
|
||||||
}
|
}
|
||||||
impl CollectionFilter for TagNameNSFilter {
|
impl CollectionFilter for TagNameNSFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, _root: &Node) -> bool {
|
||||||
let ns_match = match self.namespace_filter {
|
let ns_match = match self.namespace_filter {
|
||||||
Some(ref namespace) => {
|
Some(ref namespace) => {
|
||||||
*elem.namespace() == *namespace
|
*elem.namespace() == *namespace
|
||||||
|
@ -134,14 +134,14 @@ impl HTMLCollection {
|
||||||
HTMLCollection::create(window, root, box filter)
|
HTMLCollection::create(window, root, box filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_class_name(window: JSRef<Window>, root: JSRef<Node>, classes: DOMString)
|
pub fn by_class_name(window: &Window, root: &Node, classes: DOMString)
|
||||||
-> Temporary<HTMLCollection> {
|
-> Root<HTMLCollection> {
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct ClassNameFilter {
|
struct ClassNameFilter {
|
||||||
classes: Vec<Atom>
|
classes: Vec<Atom>
|
||||||
}
|
}
|
||||||
impl CollectionFilter for ClassNameFilter {
|
impl CollectionFilter for ClassNameFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, _root: &Node) -> bool {
|
||||||
self.classes.iter().all(|class| elem.has_class(class))
|
self.classes.iter().all(|class| elem.has_class(class))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,30 +153,30 @@ impl HTMLCollection {
|
||||||
HTMLCollection::create(window, root, box filter)
|
HTMLCollection::create(window, root, box filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn children(window: JSRef<Window>, root: JSRef<Node>) -> Temporary<HTMLCollection> {
|
pub fn children(window: &Window, root: &Node) -> Root<HTMLCollection> {
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct ElementChildFilter;
|
struct ElementChildFilter;
|
||||||
impl CollectionFilter for ElementChildFilter {
|
impl CollectionFilter for ElementChildFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, root: &Node) -> bool {
|
||||||
root.is_parent_of(NodeCast::from_ref(elem))
|
root.is_parent_of(NodeCast::from_ref(elem))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HTMLCollection::create(window, root, box ElementChildFilter)
|
HTMLCollection::create(window, root, box ElementChildFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse(root: JSRef<Node>)
|
fn traverse(root: &Node)
|
||||||
-> FilterMap<Skip<TreeIterator>,
|
-> FilterMap<Skip<TreeIterator>,
|
||||||
fn(Temporary<Node>) -> Option<Temporary<Element>>> {
|
fn(Root<Node>) -> Option<Root<Element>>> {
|
||||||
fn to_temporary(node: Temporary<Node>) -> Option<Temporary<Element>> {
|
fn to_temporary(node: Root<Node>) -> Option<Root<Element>> {
|
||||||
ElementCast::to_temporary(node)
|
ElementCast::to_root(node)
|
||||||
}
|
}
|
||||||
root.traverse_preorder()
|
root.traverse_preorder()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.filter_map(to_temporary as fn(Temporary<Node>) -> Option<Temporary<Element>>)
|
.filter_map(to_temporary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> {
|
impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
|
||||||
fn Length(self) -> u32 {
|
fn Length(self) -> u32 {
|
||||||
match self.collection {
|
match self.collection {
|
||||||
|
@ -184,30 +184,29 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> {
|
||||||
CollectionTypeId::Live(ref root, ref filter) => {
|
CollectionTypeId::Live(ref root, ref filter) => {
|
||||||
let root = root.root();
|
let root = root.root();
|
||||||
HTMLCollection::traverse(root.r())
|
HTMLCollection::traverse(root.r())
|
||||||
.filter(|element| filter.filter(element.root().r(), root.r()))
|
.filter(|element| filter.filter(element.r(), root.r()))
|
||||||
.count() as u32
|
.count() as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
|
||||||
fn Item(self, index: u32) -> Option<Temporary<Element>> {
|
fn Item(self, index: u32) -> Option<Root<Element>> {
|
||||||
let index = index as usize;
|
let index = index as usize;
|
||||||
match self.collection {
|
match self.collection {
|
||||||
CollectionTypeId::Static(ref elems) => elems
|
CollectionTypeId::Static(ref elems) => elems
|
||||||
.get(index)
|
.get(index).map(|t| t.root()),
|
||||||
.map(|elem| Temporary::from_rooted(elem.clone())),
|
|
||||||
CollectionTypeId::Live(ref root, ref filter) => {
|
CollectionTypeId::Live(ref root, ref filter) => {
|
||||||
let root = root.root();
|
let root = root.root();
|
||||||
HTMLCollection::traverse(root.r())
|
HTMLCollection::traverse(root.r())
|
||||||
.filter(|element| filter.filter(element.root().r(), root.r()))
|
.filter(|element| filter.filter(element.r(), root.r()))
|
||||||
.nth(index)
|
.nth(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
|
||||||
fn NamedItem(self, key: DOMString) -> Option<Temporary<Element>> {
|
fn NamedItem(self, key: DOMString) -> Option<Root<Element>> {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
if key.is_empty() {
|
if key.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -219,28 +218,25 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> {
|
||||||
.map(|elem| elem.root())
|
.map(|elem| elem.root())
|
||||||
.find(|elem| {
|
.find(|elem| {
|
||||||
elem.r().get_string_attribute(&atom!("name")) == key ||
|
elem.r().get_string_attribute(&atom!("name")) == key ||
|
||||||
elem.r().get_string_attribute(&atom!("id")) == key })
|
elem.r().get_string_attribute(&atom!("id")) == key }),
|
||||||
.map(|maybe_elem| Temporary::from_rooted(maybe_elem.r())),
|
|
||||||
CollectionTypeId::Live(ref root, ref filter) => {
|
CollectionTypeId::Live(ref root, ref filter) => {
|
||||||
let root = root.root();
|
let root = root.root();
|
||||||
HTMLCollection::traverse(root.r())
|
HTMLCollection::traverse(root.r())
|
||||||
.map(|element| element.root())
|
|
||||||
.filter(|element| filter.filter(element.r(), root.r()))
|
.filter(|element| filter.filter(element.r(), root.r()))
|
||||||
.find(|elem| {
|
.find(|elem| {
|
||||||
elem.r().get_string_attribute(&atom!("name")) == key ||
|
elem.r().get_string_attribute(&atom!("name")) == key ||
|
||||||
elem.r().get_string_attribute(&atom!("id")) == key })
|
elem.r().get_string_attribute(&atom!("id")) == key })
|
||||||
.map(|elem| Temporary::from_rooted(elem.r()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Element>> {
|
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Element>> {
|
||||||
let maybe_elem = self.Item(index);
|
let maybe_elem = self.Item(index);
|
||||||
*found = maybe_elem.is_some();
|
*found = maybe_elem.is_some();
|
||||||
maybe_elem
|
maybe_elem
|
||||||
}
|
}
|
||||||
|
|
||||||
fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Temporary<Element>> {
|
fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Element>> {
|
||||||
let maybe_elem = self.NamedItem(name);
|
let maybe_elem = self.NamedItem(name);
|
||||||
*found = maybe_elem.is_some();
|
*found = maybe_elem.is_some();
|
||||||
maybe_elem
|
maybe_elem
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLDataElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLDataElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLDataElementDerived for EventTarget {
|
||||||
impl HTMLDataElement {
|
impl HTMLDataElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLDataElement {
|
document: &Document) -> HTMLDataElement {
|
||||||
HTMLDataElement {
|
HTMLDataElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLDataElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDataElement> {
|
document: &Document) -> Root<HTMLDataElement> {
|
||||||
let element = HTMLDataElement::new_inherited(localName, prefix, document);
|
let element = HTMLDataElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDataElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDataElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLDataListElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLDataListElementBinding::HTMLDataListElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLDataListElementBinding::HTMLDataListElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, HTMLOptionElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, HTMLOptionElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -32,7 +32,7 @@ impl HTMLDataListElementDerived for EventTarget {
|
||||||
impl HTMLDataListElement {
|
impl HTMLDataListElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLDataListElement {
|
document: &Document) -> HTMLDataListElement {
|
||||||
HTMLDataListElement {
|
HTMLDataListElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataListElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataListElement, localName, prefix, document)
|
||||||
|
@ -42,24 +42,24 @@ impl HTMLDataListElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDataListElement> {
|
document: &Document) -> Root<HTMLDataListElement> {
|
||||||
let element = HTMLDataListElement::new_inherited(localName, prefix, document);
|
let element = HTMLDataListElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDataListElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDataListElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLDataListElementMethods for JSRef<'a, HTMLDataListElement> {
|
impl<'a> HTMLDataListElementMethods for &'a HTMLDataListElement {
|
||||||
fn Options(self) -> Temporary<HTMLCollection> {
|
fn Options(self) -> Root<HTMLCollection> {
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct HTMLDataListOptionsFilter;
|
struct HTMLDataListOptionsFilter;
|
||||||
impl CollectionFilter for HTMLDataListOptionsFilter {
|
impl CollectionFilter for HTMLDataListOptionsFilter {
|
||||||
fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool {
|
fn filter(&self, elem: &Element, _root: &Node) -> bool {
|
||||||
elem.is_htmloptionelement()
|
elem.is_htmloptionelement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let filter = box HTMLDataListOptionsFilter;
|
let filter = box HTMLDataListOptionsFilter;
|
||||||
let window = window_from_node(node).root();
|
let window = window_from_node(node);
|
||||||
HTMLCollection::create(window.r(), node, filter)
|
HTMLCollection::create(window.r(), node, filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLDialogElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLDialogElementBinding::HTMLDialogElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLDialogElementBinding::HTMLDialogElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLDialogElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLDialogElementDerived;
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -34,7 +34,7 @@ impl HTMLDialogElementDerived for EventTarget {
|
||||||
impl HTMLDialogElement {
|
impl HTMLDialogElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLDialogElement {
|
document: &Document) -> HTMLDialogElement {
|
||||||
HTMLDialogElement {
|
HTMLDialogElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDialogElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDialogElement, localName, prefix, document),
|
||||||
|
@ -45,13 +45,13 @@ impl HTMLDialogElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDialogElement> {
|
document: &Document) -> Root<HTMLDialogElement> {
|
||||||
let element = HTMLDialogElement::new_inherited(localName, prefix, document);
|
let element = HTMLDialogElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDialogElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDialogElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLDialogElementMethods for JSRef<'a, HTMLDialogElement> {
|
impl<'a> HTMLDialogElementMethods for &'a HTMLDialogElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-dialog-open
|
// https://html.spec.whatwg.org/multipage/#dom-dialog-open
|
||||||
make_bool_getter!(Open);
|
make_bool_getter!(Open);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLDirectoryElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLDirectoryElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLDirectoryElementDerived for EventTarget {
|
||||||
impl HTMLDirectoryElement {
|
impl HTMLDirectoryElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLDirectoryElement {
|
document: &Document) -> HTMLDirectoryElement {
|
||||||
HTMLDirectoryElement {
|
HTMLDirectoryElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDirectoryElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDirectoryElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLDirectoryElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDirectoryElement> {
|
document: &Document) -> Root<HTMLDirectoryElement> {
|
||||||
let element = HTMLDirectoryElement::new_inherited(localName, prefix, document);
|
let element = HTMLDirectoryElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDirectoryElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDirectoryElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLDivElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLDivElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLDivElementDerived for EventTarget {
|
||||||
impl HTMLDivElement {
|
impl HTMLDivElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLDivElement {
|
document: &Document) -> HTMLDivElement {
|
||||||
HTMLDivElement {
|
HTMLDivElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDivElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDivElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLDivElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDivElement> {
|
document: &Document) -> Root<HTMLDivElement> {
|
||||||
let element = HTMLDivElement::new_inherited(localName, prefix, document);
|
let element = HTMLDivElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDivElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDivElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLDListElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLDListElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLDListElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLDListElement {
|
impl HTMLDListElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLDListElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLDListElement {
|
||||||
HTMLDListElement {
|
HTMLDListElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDListElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLDListElement, localName, prefix, document)
|
||||||
|
@ -36,7 +36,7 @@ impl HTMLDListElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLDListElement> {
|
document: &Document) -> Root<HTMLDListElement> {
|
||||||
let element = HTMLDListElement::new_inherited(localName, prefix, document);
|
let element = HTMLDListElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLDListElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLDListElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLInputElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLInputElementCast, NodeCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived};
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::error::ErrorResult;
|
use dom::bindings::error::ErrorResult;
|
||||||
use dom::bindings::error::Error::Syntax;
|
use dom::bindings::error::Error::Syntax;
|
||||||
use dom::bindings::utils::Reflectable;
|
use dom::bindings::utils::Reflectable;
|
||||||
|
@ -37,6 +37,7 @@ use string_cache::Atom;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::intrinsics;
|
use std::intrinsics;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct HTMLElement {
|
pub struct HTMLElement {
|
||||||
|
@ -45,6 +46,12 @@ pub struct HTMLElement {
|
||||||
dataset: MutNullableHeap<JS<DOMStringMap>>,
|
dataset: MutNullableHeap<JS<DOMStringMap>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLElement {
|
||||||
|
fn eq(&self, other: &HTMLElement) -> bool {
|
||||||
|
self as *const HTMLElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HTMLElementDerived for EventTarget {
|
impl HTMLElementDerived for EventTarget {
|
||||||
fn is_htmlelement(&self) -> bool {
|
fn is_htmlelement(&self) -> bool {
|
||||||
match *self.type_id() {
|
match *self.type_id() {
|
||||||
|
@ -58,7 +65,7 @@ impl HTMLElement {
|
||||||
pub fn new_inherited(type_id: HTMLElementTypeId,
|
pub fn new_inherited(type_id: HTMLElementTypeId,
|
||||||
tag_name: DOMString,
|
tag_name: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLElement {
|
document: &Document) -> HTMLElement {
|
||||||
HTMLElement {
|
HTMLElement {
|
||||||
element:
|
element:
|
||||||
Element::new_inherited(ElementTypeId::HTMLElement(type_id), tag_name, ns!(HTML), prefix, document),
|
Element::new_inherited(ElementTypeId::HTMLElement(type_id), tag_name, ns!(HTML), prefix, document),
|
||||||
|
@ -68,7 +75,7 @@ impl HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLElement> {
|
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> Root<HTMLElement> {
|
||||||
let element = HTMLElement::new_inherited(HTMLElementTypeId::HTMLElement, localName, prefix, document);
|
let element = HTMLElement::new_inherited(HTMLElementTypeId::HTMLElement, localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -79,9 +86,9 @@ trait PrivateHTMLElementHelpers {
|
||||||
fn update_sequentially_focusable_status(self);
|
fn update_sequentially_focusable_status(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
|
impl<'a> PrivateHTMLElementHelpers for &'a HTMLElement {
|
||||||
fn is_body_or_frameset(self) -> bool {
|
fn is_body_or_frameset(self) -> bool {
|
||||||
let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let eventtarget = EventTargetCast::from_ref(self);
|
||||||
eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement()
|
eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +112,6 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(attr) = element.get_attribute(&ns!(""), &atom!("draggable")) {
|
if let Some(attr) = element.get_attribute(&ns!(""), &atom!("draggable")) {
|
||||||
let attr = attr.root();
|
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
let is_true = match *value {
|
let is_true = match *value {
|
||||||
|
@ -124,10 +130,10 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
impl<'a> HTMLElementMethods for &'a HTMLElement {
|
||||||
fn Style(self) -> Temporary<CSSStyleDeclaration> {
|
fn Style(self) -> Root<CSSStyleDeclaration> {
|
||||||
self.style_decl.or_init(|| {
|
self.style_decl.or_init(|| {
|
||||||
let global = window_from_node(self).root();
|
let global = window_from_node(self);
|
||||||
CSSStyleDeclaration::new(global.r(), self, CSSModificationAccess::ReadWrite)
|
CSSStyleDeclaration::new(global.r(), self, CSSModificationAccess::ReadWrite)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -145,39 +151,39 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
||||||
global_event_handlers!(NoOnload);
|
global_event_handlers!(NoOnload);
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-dataset
|
// https://html.spec.whatwg.org/multipage/#dom-dataset
|
||||||
fn Dataset(self) -> Temporary<DOMStringMap> {
|
fn Dataset(self) -> Root<DOMStringMap> {
|
||||||
self.dataset.or_init(|| DOMStringMap::new(self))
|
self.dataset.or_init(|| DOMStringMap::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetOnload(self) -> Option<EventHandlerNonNull> {
|
fn GetOnload(self) -> Option<Rc<EventHandlerNonNull>> {
|
||||||
if self.is_body_or_frameset() {
|
if self.is_body_or_frameset() {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
win.r().GetOnload()
|
win.r().GetOnload()
|
||||||
} else {
|
} else {
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
target.get_event_handler_common("load")
|
target.get_event_handler_common("load")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetOnload(self, listener: Option<EventHandlerNonNull>) {
|
fn SetOnload(self, listener: Option<Rc<EventHandlerNonNull>>) {
|
||||||
if self.is_body_or_frameset() {
|
if self.is_body_or_frameset() {
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
win.r().SetOnload(listener)
|
win.r().SetOnload(listener)
|
||||||
} else {
|
} else {
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
target.set_event_handler_common("load", listener)
|
target.set_event_handler_common("load", listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-click
|
// https://html.spec.whatwg.org/multipage/#dom-click
|
||||||
fn Click(self) {
|
fn Click(self) {
|
||||||
let maybe_input: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self);
|
let maybe_input: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self);
|
||||||
if let Some(i) = maybe_input {
|
if let Some(i) = maybe_input {
|
||||||
if i.Disabled() {
|
if i.Disabled() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27430 ?
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27430 ?
|
||||||
element.as_maybe_activatable().map(|a| a.synthetic_click_activation(false, false, false, false));
|
element.as_maybe_activatable().map(|a| a.synthetic_click_activation(false, false, false, false));
|
||||||
}
|
}
|
||||||
|
@ -186,8 +192,8 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
||||||
fn Focus(self) {
|
fn Focus(self) {
|
||||||
// TODO: Mark the element as locked for focus and run the focusing steps.
|
// TODO: Mark the element as locked for focus and run the focusing steps.
|
||||||
// https://html.spec.whatwg.org/multipage/#focusing-steps
|
// https://html.spec.whatwg.org/multipage/#focusing-steps
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
let document = document_from_node(self).root();
|
let document = document_from_node(self);
|
||||||
let document = document.r();
|
let document = document.r();
|
||||||
document.begin_focus_transaction();
|
document.begin_focus_transaction();
|
||||||
document.request_focus(element);
|
document.request_focus(element);
|
||||||
|
@ -197,12 +203,12 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-blur
|
// https://html.spec.whatwg.org/multipage/#dom-blur
|
||||||
fn Blur(self) {
|
fn Blur(self) {
|
||||||
// TODO: Run the unfocusing steps.
|
// TODO: Run the unfocusing steps.
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if !node.get_focus_state() {
|
if !node.get_focus_state() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// https://html.spec.whatwg.org/multipage/#unfocusing-steps
|
// https://html.spec.whatwg.org/multipage/#unfocusing-steps
|
||||||
let document = document_from_node(self).root();
|
let document = document_from_node(self);
|
||||||
document.r().begin_focus_transaction();
|
document.r().begin_focus_transaction();
|
||||||
// If `request_focus` is not called, focus will be set to None.
|
// If `request_focus` is not called, focus will be set to None.
|
||||||
document.r().commit_focus_transaction(FocusType::Element);
|
document.r().commit_focus_transaction(FocusType::Element);
|
||||||
|
@ -229,22 +235,21 @@ fn to_snake_case(name: DOMString) -> DOMString {
|
||||||
attr_name
|
attr_name
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
|
impl<'a> HTMLElementCustomAttributeHelpers for &'a HTMLElement {
|
||||||
fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult {
|
fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult {
|
||||||
if name.chars()
|
if name.chars()
|
||||||
.skip_while(|&ch| ch != '\u{2d}')
|
.skip_while(|&ch| ch != '\u{2d}')
|
||||||
.nth(1).map_or(false, |ch| ch >= 'a' && ch <= 'z') {
|
.nth(1).map_or(false, |ch| ch >= 'a' && ch <= 'z') {
|
||||||
return Err(Syntax);
|
return Err(Syntax);
|
||||||
}
|
}
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.set_custom_attribute(to_snake_case(name), value)
|
element.set_custom_attribute(to_snake_case(name), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_custom_attr(self, local_name: DOMString) -> Option<DOMString> {
|
fn get_custom_attr(self, local_name: DOMString) -> Option<DOMString> {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
let local_name = Atom::from_slice(&to_snake_case(local_name));
|
let local_name = Atom::from_slice(&to_snake_case(local_name));
|
||||||
element.get_attribute(&ns!(""), &local_name).map(|attr| {
|
element.get_attribute(&ns!(""), &local_name).map(|attr| {
|
||||||
let attr = attr.root();
|
|
||||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||||
let attr = attr.r();
|
let attr = attr.r();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
|
@ -253,19 +258,19 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_custom_attr(self, local_name: DOMString) {
|
fn delete_custom_attr(self, local_name: DOMString) {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
let local_name = Atom::from_slice(&to_snake_case(local_name));
|
let local_name = Atom::from_slice(&to_snake_case(local_name));
|
||||||
element.remove_attribute(&ns!(""), &local_name);
|
element.remove_attribute(&ns!(""), &local_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
|
impl<'a> VirtualMethods for &'a HTMLElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let element: &JSRef<Element> = ElementCast::from_borrowed_ref(self);
|
let element: &&Element = ElementCast::from_borrowed_ref(self);
|
||||||
Some(element as &VirtualMethods)
|
Some(element as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -278,18 +283,18 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
|
||||||
self.update_sequentially_focusable_status();
|
self.update_sequentially_focusable_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = attr.local_name();
|
let name = attr.local_name();
|
||||||
if name.starts_with("on") {
|
if name.starts_with("on") {
|
||||||
let window = window_from_node(*self).root();
|
let window = window_from_node(*self);
|
||||||
let (cx, url, reflector) = (window.r().get_cx(),
|
let (cx, url, reflector) = (window.r().get_cx(),
|
||||||
window.r().get_url(),
|
window.r().get_url(),
|
||||||
window.r().reflector().get_jsobject());
|
window.r().reflector().get_jsobject());
|
||||||
let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
let evtarget = EventTargetCast::from_ref(*self);
|
||||||
evtarget.set_event_handler_uncompiled(cx, url, reflector,
|
evtarget.set_event_handler_uncompiled(cx, url, reflector,
|
||||||
&name[2..],
|
&name[2..],
|
||||||
(**attr.value()).to_owned());
|
(**attr.value()).to_owned());
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLEmbedElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLEmbedElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLEmbedElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLEmbedElement {
|
impl HTMLEmbedElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLEmbedElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLEmbedElement {
|
||||||
HTMLEmbedElement {
|
HTMLEmbedElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLEmbedElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLEmbedElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLEmbedElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLEmbedElement> {
|
document: &Document) -> Root<HTMLEmbedElement> {
|
||||||
let element = HTMLEmbedElement::new_inherited(localName, prefix, document);
|
let element = HTMLEmbedElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLEmbedElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLEmbedElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLLegendElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLLegendElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Rootable, RootedReference, Temporary};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, Element, ElementHelpers};
|
use dom::element::{AttributeHandlers, Element, ElementHelpers};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLFieldSetElementDerived for EventTarget {
|
||||||
impl HTMLFieldSetElement {
|
impl HTMLFieldSetElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLFieldSetElement {
|
document: &Document) -> HTMLFieldSetElement {
|
||||||
HTMLFieldSetElement {
|
HTMLFieldSetElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLFieldSetElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLFieldSetElement, localName, prefix, document)
|
||||||
|
@ -47,32 +47,32 @@ impl HTMLFieldSetElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLFieldSetElement> {
|
document: &Document) -> Root<HTMLFieldSetElement> {
|
||||||
let element = HTMLFieldSetElement::new_inherited(localName, prefix, document);
|
let element = HTMLFieldSetElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLFieldSetElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLFieldSetElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> {
|
impl<'a> HTMLFieldSetElementMethods for &'a HTMLFieldSetElement {
|
||||||
// https://www.whatwg.org/html/#dom-fieldset-elements
|
// https://www.whatwg.org/html/#dom-fieldset-elements
|
||||||
fn Elements(self) -> Temporary<HTMLCollection> {
|
fn Elements(self) -> Root<HTMLCollection> {
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
struct ElementsFilter;
|
struct ElementsFilter;
|
||||||
impl CollectionFilter for ElementsFilter {
|
impl CollectionFilter for ElementsFilter {
|
||||||
fn filter<'a>(&self, elem: JSRef<'a, Element>, _root: JSRef<'a, Node>) -> bool {
|
fn filter<'a>(&self, elem: &'a Element, _root: &'a Node) -> bool {
|
||||||
static TAG_NAMES: StaticStringVec = &["button", "fieldset", "input",
|
static TAG_NAMES: StaticStringVec = &["button", "fieldset", "input",
|
||||||
"keygen", "object", "output", "select", "textarea"];
|
"keygen", "object", "output", "select", "textarea"];
|
||||||
TAG_NAMES.iter().any(|&tag_name| tag_name == &**elem.local_name())
|
TAG_NAMES.iter().any(|&tag_name| tag_name == &**elem.local_name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let filter = box ElementsFilter;
|
let filter = box ElementsFilter;
|
||||||
let window = window_from_node(node).root();
|
let window = window_from_node(node);
|
||||||
HTMLCollection::create(window.r(), node, filter)
|
HTMLCollection::create(window.r(), node, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Validity(self) -> Temporary<ValidityState> {
|
fn Validity(self) -> Root<ValidityState> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
ValidityState::new(window.r())
|
ValidityState::new(window.r())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,34 +83,31 @@ impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> {
|
||||||
make_bool_setter!(SetDisabled, "disabled");
|
make_bool_setter!(SetDisabled, "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLFieldSetElement> {
|
impl<'a> VirtualMethods for &'a HTMLFieldSetElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(true);
|
node.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
node.set_enabled_state(false);
|
||||||
let maybe_legend = node.children()
|
let maybe_legend = node.children()
|
||||||
.map(|node| node.root())
|
|
||||||
.find(|node| node.r().is_htmllegendelement());
|
.find(|node| node.r().is_htmllegendelement());
|
||||||
|
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
let child = child.root();
|
|
||||||
if Some(child.r()) == maybe_legend.r() {
|
if Some(child.r()) == maybe_legend.r() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for descendant in child.r().traverse_preorder() {
|
for descendant in child.r().traverse_preorder() {
|
||||||
let descendant = descendant.root();
|
|
||||||
match descendant.r().type_id() {
|
match descendant.r().type_id() {
|
||||||
NodeTypeId::Element(
|
NodeTypeId::Element(
|
||||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
||||||
|
@ -132,28 +129,25 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLFieldSetElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(false);
|
node.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
node.set_enabled_state(true);
|
||||||
let maybe_legend = node.children()
|
let maybe_legend = node.children()
|
||||||
.map(|node| node.root())
|
|
||||||
.find(|node| node.r().is_htmllegendelement());
|
.find(|node| node.r().is_htmllegendelement());
|
||||||
|
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
let child = child.root();
|
|
||||||
if Some(child.r()) == maybe_legend.r() {
|
if Some(child.r()) == maybe_legend.r() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for descendant in child.r().traverse_preorder() {
|
for descendant in child.r().traverse_preorder() {
|
||||||
let descendant = descendant.root();
|
|
||||||
match descendant.r().type_id() {
|
match descendant.r().type_id() {
|
||||||
NodeTypeId::Element(
|
NodeTypeId::Element(
|
||||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dom::attr::{Attr, AttrHelpers};
|
||||||
use dom::bindings::codegen::Bindings::HTMLFontElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLFontElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -33,7 +33,7 @@ impl HTMLFontElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLFontElement {
|
impl HTMLFontElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLFontElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLFontElement {
|
||||||
HTMLFontElement {
|
HTMLFontElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document),
|
||||||
color: Cell::new(None),
|
color: Cell::new(None),
|
||||||
|
@ -43,24 +43,24 @@ impl HTMLFontElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLFontElement> {
|
document: &Document) -> Root<HTMLFontElement> {
|
||||||
let element = HTMLFontElement::new_inherited(localName, prefix, document);
|
let element = HTMLFontElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLFontElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLFontElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLFontElementMethods for JSRef<'a, HTMLFontElement> {
|
impl<'a> HTMLFontElementMethods for &'a HTMLFontElement {
|
||||||
make_getter!(Color, "color");
|
make_getter!(Color, "color");
|
||||||
make_setter!(SetColor, "color");
|
make_setter!(SetColor, "color");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a,HTMLFontElement> {
|
impl<'a> VirtualMethods for &'a HTMLFontElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ impl<'a> VirtualMethods for JSRef<'a,HTMLFontElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLInputElementCast;
|
use dom::bindings::codegen::InheritTypes::HTMLInputElementCast;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary};
|
use dom::bindings::js::{Root};
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::{Element, AttributeHandlers};
|
use dom::element::{Element, AttributeHandlers};
|
||||||
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
|
||||||
|
@ -49,6 +49,12 @@ pub struct HTMLFormElement {
|
||||||
marked_for_reset: Cell<bool>,
|
marked_for_reset: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLFormElement {
|
||||||
|
fn eq(&self, other: &HTMLFormElement) -> bool {
|
||||||
|
self as *const HTMLFormElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HTMLFormElementDerived for EventTarget {
|
impl HTMLFormElementDerived for EventTarget {
|
||||||
fn is_htmlformelement(&self) -> bool {
|
fn is_htmlformelement(&self) -> bool {
|
||||||
*self.type_id() ==
|
*self.type_id() ==
|
||||||
|
@ -60,7 +66,7 @@ impl HTMLFormElementDerived for EventTarget {
|
||||||
impl HTMLFormElement {
|
impl HTMLFormElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLFormElement {
|
document: &Document) -> HTMLFormElement {
|
||||||
HTMLFormElement {
|
HTMLFormElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFormElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFormElement, localName, prefix, document),
|
||||||
marked_for_reset: Cell::new(false),
|
marked_for_reset: Cell::new(false),
|
||||||
|
@ -70,13 +76,13 @@ impl HTMLFormElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLFormElement> {
|
document: &Document) -> Root<HTMLFormElement> {
|
||||||
let element = HTMLFormElement::new_inherited(localName, prefix, document);
|
let element = HTMLFormElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
|
impl<'a> HTMLFormElementMethods for &'a HTMLFormElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-form-acceptcharset
|
// https://html.spec.whatwg.org/multipage/#dom-form-acceptcharset
|
||||||
make_getter!(AcceptCharset, "accept-charset");
|
make_getter!(AcceptCharset, "accept-charset");
|
||||||
|
|
||||||
|
@ -165,19 +171,19 @@ pub trait HTMLFormElementHelpers {
|
||||||
fn reset(self, submit_method_flag: ResetFrom);
|
fn reset(self, submit_method_flag: ResetFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
|
impl<'a> HTMLFormElementHelpers for &'a HTMLFormElement {
|
||||||
fn submit(self, _submit_method_flag: SubmittedFrom, submitter: FormSubmitter) {
|
fn submit(self, _submit_method_flag: SubmittedFrom, submitter: FormSubmitter) {
|
||||||
// Step 1
|
// Step 1
|
||||||
let doc = document_from_node(self).root();
|
let doc = document_from_node(self);
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
let base = doc.r().url();
|
let base = doc.r().url();
|
||||||
// TODO: Handle browsing contexts
|
// TODO: Handle browsing contexts
|
||||||
// TODO: Handle validation
|
// TODO: Handle validation
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = Event::new(GlobalRef::Window(win.r()),
|
||||||
"submit".to_owned(),
|
"submit".to_owned(),
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::Cancelable).root();
|
EventCancelable::Cancelable);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
if event.r().DefaultPrevented() {
|
if event.r().DefaultPrevented() {
|
||||||
return;
|
return;
|
||||||
|
@ -262,16 +268,15 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
// TODO: This is an incorrect way of getting controls owned
|
// TODO: This is an incorrect way of getting controls owned
|
||||||
// by the form, but good enough until html5ever lands
|
// by the form, but good enough until html5ever lands
|
||||||
let data_set = node.traverse_preorder().filter_map(|child| {
|
let data_set = node.traverse_preorder().filter_map(|child| {
|
||||||
let child = child.root();
|
|
||||||
if child.r().get_disabled_state() {
|
if child.r().get_disabled_state() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if child.r().ancestors()
|
if child.r().ancestors()
|
||||||
.any(|a| HTMLDataListElementCast::to_temporary(a).is_some()) {
|
.any(|a| HTMLDataListElementCast::to_root(a).is_some()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// XXXManishearth don't include it if it is a button but not the submitter
|
// XXXManishearth don't include it if it is a button but not the submitter
|
||||||
|
@ -365,23 +370,22 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
|
||||||
self.marked_for_reset.set(true);
|
self.marked_for_reset.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = Event::new(GlobalRef::Window(win.r()),
|
||||||
"reset".to_owned(),
|
"reset".to_owned(),
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::Cancelable).root();
|
EventCancelable::Cancelable);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
if event.r().DefaultPrevented() {
|
if event.r().DefaultPrevented() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
|
|
||||||
// TODO: This is an incorrect way of getting controls owned
|
// TODO: This is an incorrect way of getting controls owned
|
||||||
// by the form, but good enough until html5ever lands
|
// by the form, but good enough until html5ever lands
|
||||||
for child in node.traverse_preorder() {
|
for child in node.traverse_preorder() {
|
||||||
let child = child.root();
|
|
||||||
match child.r().type_id() {
|
match child.r().type_id() {
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
|
||||||
let input = HTMLInputElementCast::to_ref(child.r()).unwrap();
|
let input = HTMLInputElementCast::to_ref(child.r()).unwrap();
|
||||||
|
@ -434,9 +438,9 @@ pub enum FormMethod {
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum FormSubmitter<'a> {
|
pub enum FormSubmitter<'a> {
|
||||||
FormElement(JSRef<'a, HTMLFormElement>),
|
FormElement(&'a HTMLFormElement),
|
||||||
InputElement(JSRef<'a, HTMLInputElement>),
|
InputElement(&'a HTMLInputElement),
|
||||||
ButtonElement(JSRef<'a, HTMLButtonElement>)
|
ButtonElement(&'a HTMLButtonElement)
|
||||||
// TODO: image submit, etc etc
|
// TODO: image submit, etc etc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,28 +529,27 @@ impl<'a> FormSubmitter<'a> {
|
||||||
pub trait FormControl<'a> : Copy + Sized {
|
pub trait FormControl<'a> : Copy + Sized {
|
||||||
// FIXME: This is wrong (https://github.com/servo/servo/issues/3553)
|
// FIXME: This is wrong (https://github.com/servo/servo/issues/3553)
|
||||||
// but we need html5ever to do it correctly
|
// but we need html5ever to do it correctly
|
||||||
fn form_owner(self) -> Option<Temporary<HTMLFormElement>> {
|
fn form_owner(self) -> Option<Root<HTMLFormElement>> {
|
||||||
// https://html.spec.whatwg.org/multipage/#reset-the-form-owner
|
// https://html.spec.whatwg.org/multipage/#reset-the-form-owner
|
||||||
let elem = self.to_element();
|
let elem = self.to_element();
|
||||||
let owner = elem.get_string_attribute(&atom!("form"));
|
let owner = elem.get_string_attribute(&atom!("form"));
|
||||||
if !owner.is_empty() {
|
if !owner.is_empty() {
|
||||||
let doc = document_from_node(elem).root();
|
let doc = document_from_node(elem);
|
||||||
let owner = doc.r().GetElementById(owner).root();
|
let owner = doc.r().GetElementById(owner);
|
||||||
match owner {
|
match owner {
|
||||||
Some(ref o) => {
|
Some(ref o) => {
|
||||||
let maybe_form: Option<JSRef<HTMLFormElement>> = HTMLFormElementCast::to_ref(o.r());
|
let maybe_form = HTMLFormElementCast::to_ref(o.r());
|
||||||
if maybe_form.is_some() {
|
if maybe_form.is_some() {
|
||||||
return maybe_form.map(Temporary::from_rooted);
|
return maybe_form.map(Root::from_ref);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(elem);
|
let node = NodeCast::from_ref(elem);
|
||||||
for ancestor in node.ancestors() {
|
for ancestor in node.ancestors() {
|
||||||
let ancestor = ancestor.root();
|
|
||||||
if let Some(ancestor) = HTMLFormElementCast::to_ref(ancestor.r()) {
|
if let Some(ancestor) = HTMLFormElementCast::to_ref(ancestor.r()) {
|
||||||
return Some(Temporary::from_rooted(ancestor))
|
return Some(Root::from_ref(ancestor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -558,19 +561,19 @@ pub trait FormControl<'a> : Copy + Sized {
|
||||||
owner: OwnerFn)
|
owner: OwnerFn)
|
||||||
-> DOMString
|
-> DOMString
|
||||||
where InputFn: Fn(Self) -> DOMString,
|
where InputFn: Fn(Self) -> DOMString,
|
||||||
OwnerFn: Fn(JSRef<HTMLFormElement>) -> DOMString
|
OwnerFn: Fn(&HTMLFormElement) -> DOMString
|
||||||
{
|
{
|
||||||
if self.to_element().has_attribute(attr) {
|
if self.to_element().has_attribute(attr) {
|
||||||
input(self)
|
input(self)
|
||||||
} else {
|
} else {
|
||||||
self.form_owner().map_or("".to_owned(), |t| owner(t.root().r()))
|
self.form_owner().map_or("".to_owned(), |t| owner(t.r()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_element(self) -> JSRef<'a, Element>;
|
fn to_element(self) -> &'a Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLFormElement> {
|
impl<'a> VirtualMethods for &'a HTMLFormElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
|
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLFrameElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLFrameElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLFrameElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLFrameElement {
|
impl HTMLFrameElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLFrameElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLFrameElement {
|
||||||
HTMLFrameElement {
|
HTMLFrameElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLFrameElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLFrameElement> {
|
document: &Document) -> Root<HTMLFrameElement> {
|
||||||
let element = HTMLFrameElement::new_inherited(localName, prefix, document);
|
let element = HTMLFrameElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLFrameElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLFrameElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLFrameSetElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLFrameSetElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLFrameSetElementDerived for EventTarget {
|
||||||
impl HTMLFrameSetElement {
|
impl HTMLFrameSetElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLFrameSetElement {
|
document: &Document) -> HTMLFrameSetElement {
|
||||||
HTMLFrameSetElement {
|
HTMLFrameSetElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameSetElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameSetElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLFrameSetElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLFrameSetElement> {
|
document: &Document) -> Root<HTMLFrameSetElement> {
|
||||||
let element = HTMLFrameSetElement::new_inherited(localName, prefix, document);
|
let element = HTMLFrameSetElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLFrameSetElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLFrameSetElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLHeadElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLHeadElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLHeadElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLHeadElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -30,7 +30,7 @@ impl HTMLHeadElementDerived for EventTarget {
|
||||||
impl HTMLHeadElement {
|
impl HTMLHeadElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLHeadElement {
|
document: &Document) -> HTMLHeadElement {
|
||||||
HTMLHeadElement {
|
HTMLHeadElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHeadElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHeadElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,15 @@ impl HTMLHeadElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLHeadElement> {
|
document: &Document) -> Root<HTMLHeadElement> {
|
||||||
let element = HTMLHeadElement::new_inherited(localName, prefix, document);
|
let element = HTMLHeadElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLHeadElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLHeadElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLHeadElement> {
|
impl<'a> VirtualMethods for &'a HTMLHeadElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
fn bind_to_tree(&self, _tree_in_doc: bool) {
|
fn bind_to_tree(&self, _tree_in_doc: bool) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLHeadingElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLHeadingElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -39,7 +39,7 @@ impl HTMLHeadingElementDerived for EventTarget {
|
||||||
impl HTMLHeadingElement {
|
impl HTMLHeadingElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>,
|
document: &Document,
|
||||||
level: HeadingLevel) -> HTMLHeadingElement {
|
level: HeadingLevel) -> HTMLHeadingElement {
|
||||||
HTMLHeadingElement {
|
HTMLHeadingElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
|
@ -51,8 +51,8 @@ impl HTMLHeadingElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>,
|
document: &Document,
|
||||||
level: HeadingLevel) -> Temporary<HTMLHeadingElement> {
|
level: HeadingLevel) -> Root<HTMLHeadingElement> {
|
||||||
let element = HTMLHeadingElement::new_inherited(localName, prefix, document, level);
|
let element = HTMLHeadingElement::new_inherited(localName, prefix, document, level);
|
||||||
Node::reflect_node(box element, document, HTMLHeadingElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLHeadingElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLHRElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLHRElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLHRElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLHRElement {
|
impl HTMLHRElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLHRElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLHRElement {
|
||||||
HTMLHRElement {
|
HTMLHRElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHRElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHRElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLHRElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLHRElement> {
|
document: &Document) -> Root<HTMLHRElement> {
|
||||||
let element = HTMLHRElement::new_inherited(localName, prefix, document);
|
let element = HTMLHRElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLHRElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLHRElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLHtmlElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLHtmlElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLHtmlElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLHtmlElement {
|
impl HTMLHtmlElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLHtmlElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLHtmlElement {
|
||||||
HTMLHtmlElement {
|
HTMLHtmlElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHtmlElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHtmlElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLHtmlElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLHtmlElement> {
|
document: &Document) -> Root<HTMLHtmlElement> {
|
||||||
let element = HTMLHtmlElement::new_inherited(localName, prefix, document);
|
let element = HTMLHtmlElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLHtmlElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLHtmlElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@ use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::error::{ErrorResult, Fallible};
|
use dom::bindings::error::{ErrorResult, Fallible};
|
||||||
use dom::bindings::error::Error::NotSupported;
|
use dom::bindings::error::Error::NotSupported;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary};
|
use dom::bindings::js::{Root};
|
||||||
use dom::customevent::CustomEvent;
|
use dom::customevent::CustomEvent;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{self, AttributeHandlers, Element};
|
use dom::element::{self, AttributeHandlers};
|
||||||
use dom::event::{Event, EventHelpers};
|
use dom::event::EventHelpers;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
||||||
|
@ -39,6 +39,8 @@ use std::borrow::ToOwned;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
use util::str::{self, LengthOrPercentageOrAuto};
|
use util::str::{self, LengthOrPercentageOrAuto};
|
||||||
|
use js::jsapi::RootedValue;
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
|
||||||
enum SandboxAllowance {
|
enum SandboxAllowance {
|
||||||
AllowNothing = 0x00,
|
AllowNothing = 0x00,
|
||||||
|
@ -82,19 +84,19 @@ pub trait RawHTMLIFrameElementHelpers {
|
||||||
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
fn get_height(&self) -> LengthOrPercentageOrAuto;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
|
impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
|
||||||
fn is_sandboxed(self) -> bool {
|
fn is_sandboxed(self) -> bool {
|
||||||
self.sandbox.get().is_some()
|
self.sandbox.get().is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_url(self) -> Option<Url> {
|
fn get_url(self) -> Option<Url> {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.get_attribute(&ns!(""), &atom!("src")).root().and_then(|src| {
|
element.get_attribute(&ns!(""), &atom!("src")).and_then(|src| {
|
||||||
let url = src.r().value();
|
let url = src.r().value();
|
||||||
if url.is_empty() {
|
if url.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
UrlParser::new().base_url(&window.r().get_url())
|
UrlParser::new().base_url(&window.r().get_url())
|
||||||
.parse(&url).ok()
|
.parse(&url).ok()
|
||||||
}
|
}
|
||||||
|
@ -103,7 +105,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
|
||||||
|
|
||||||
fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>) {
|
fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>) {
|
||||||
let old_subpage_id = self.subpage_id.get();
|
let old_subpage_id = self.subpage_id.get();
|
||||||
let win = window_from_node(self).root();
|
let win = window_from_node(self);
|
||||||
let subpage_id = win.r().get_next_subpage_id();
|
let subpage_id = win.r().get_next_subpage_id();
|
||||||
self.subpage_id.set(Some(subpage_id));
|
self.subpage_id.set(Some(subpage_id));
|
||||||
(subpage_id, old_subpage_id)
|
(subpage_id, old_subpage_id)
|
||||||
|
@ -116,7 +118,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
|
||||||
IFrameUnsandboxed
|
IFrameUnsandboxed
|
||||||
};
|
};
|
||||||
|
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id();
|
let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id();
|
||||||
|
|
||||||
|
@ -151,15 +153,17 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
|
||||||
assert!(opts::experimental_enabled());
|
assert!(opts::experimental_enabled());
|
||||||
|
|
||||||
if self.Mozbrowser() {
|
if self.Mozbrowser() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let cx = window.r().get_cx();
|
let cx = window.r().get_cx();
|
||||||
|
let mut detail = RootedValue::new(cx, UndefinedValue());
|
||||||
|
event.detail().to_jsval(cx, detail.handle_mut());
|
||||||
let custom_event = CustomEvent::new(GlobalRef::Window(window.r()),
|
let custom_event = CustomEvent::new(GlobalRef::Window(window.r()),
|
||||||
event.name().to_owned(),
|
event.name().to_owned(),
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
event.detail().to_jsval(cx)).root();
|
detail.handle());
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
let event: JSRef<Event> = EventCast::from_ref(custom_event.r());
|
let event = EventCast::from_ref(custom_event.r());
|
||||||
event.fire(target);
|
event.fire(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +180,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
|
||||||
element::get_attr_for_layout(ElementCast::from_actual(&*self),
|
element::get_attr_for_layout(ElementCast::from_actual(&*self),
|
||||||
&ns!(""),
|
&ns!(""),
|
||||||
&atom!("width")).map(|attribute| {
|
&atom!("width")).map(|attribute| {
|
||||||
str::parse_length(&**(*attribute.unsafe_get()).value())
|
str::parse_length(&**(*attribute.unsafe_get()).value_for_layout())
|
||||||
}).unwrap_or(LengthOrPercentageOrAuto::Auto)
|
}).unwrap_or(LengthOrPercentageOrAuto::Auto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +191,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
|
||||||
element::get_attr_for_layout(ElementCast::from_actual(&*self),
|
element::get_attr_for_layout(ElementCast::from_actual(&*self),
|
||||||
&ns!(""),
|
&ns!(""),
|
||||||
&atom!("height")).map(|attribute| {
|
&atom!("height")).map(|attribute| {
|
||||||
str::parse_length(&**(*attribute.unsafe_get()).value())
|
str::parse_length(&**(*attribute.unsafe_get()).value_for_layout())
|
||||||
}).unwrap_or(LengthOrPercentageOrAuto::Auto)
|
}).unwrap_or(LengthOrPercentageOrAuto::Auto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +200,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
|
||||||
impl HTMLIFrameElement {
|
impl HTMLIFrameElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLIFrameElement {
|
document: &Document) -> HTMLIFrameElement {
|
||||||
HTMLIFrameElement {
|
HTMLIFrameElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLIFrameElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLIFrameElement, localName, prefix, document),
|
||||||
|
@ -209,7 +213,7 @@ impl HTMLIFrameElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLIFrameElement> {
|
document: &Document) -> Root<HTMLIFrameElement> {
|
||||||
let element = HTMLIFrameElement::new_inherited(localName, prefix, document);
|
let element = HTMLIFrameElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLIFrameElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLIFrameElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -225,46 +229,46 @@ impl HTMLIFrameElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
|
||||||
fn Src(self) -> DOMString {
|
fn Src(self) -> DOMString {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.get_string_attribute(&atom!("src"))
|
element.get_string_attribute(&atom!("src"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetSrc(self, src: DOMString) {
|
fn SetSrc(self, src: DOMString) {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.set_url_attribute(&atom!("src"), src)
|
element.set_url_attribute(&atom!("src"), src)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Sandbox(self) -> DOMString {
|
fn Sandbox(self) -> DOMString {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.get_string_attribute(&atom!("sandbox"))
|
element.get_string_attribute(&atom!("sandbox"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetSandbox(self, sandbox: DOMString) {
|
fn SetSandbox(self, sandbox: DOMString) {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.set_tokenlist_attribute(&atom!("sandbox"), sandbox);
|
element.set_tokenlist_attribute(&atom!("sandbox"), sandbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetContentWindow(self) -> Option<Temporary<Window>> {
|
fn GetContentWindow(self) -> Option<Root<Window>> {
|
||||||
self.subpage_id.get().and_then(|subpage_id| {
|
self.subpage_id.get().and_then(|subpage_id| {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let children = window.page().children.borrow();
|
let children = window.page().children.borrow();
|
||||||
children.iter().find(|page| {
|
children.iter().find(|page| {
|
||||||
let window = page.window().root();
|
let window = page.window();
|
||||||
window.r().subpage() == Some(subpage_id)
|
window.r().subpage() == Some(subpage_id)
|
||||||
}).map(|page| page.window())
|
}).map(|page| page.window())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetContentDocument(self) -> Option<Temporary<Document>> {
|
fn GetContentDocument(self) -> Option<Root<Document>> {
|
||||||
self.GetContentWindow().root().and_then(|window| {
|
self.GetContentWindow().and_then(|window| {
|
||||||
let self_url = match self.get_url() {
|
let self_url = match self.get_url() {
|
||||||
Some(self_url) => self_url,
|
Some(self_url) => self_url,
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
let win_url = window_from_node(self).root().r().get_url();
|
let win_url = window_from_node(self).r().get_url();
|
||||||
|
|
||||||
if UrlHelper::SameOrigin(&self_url, &win_url) {
|
if UrlHelper::SameOrigin(&self_url, &win_url) {
|
||||||
Some(window.r().Document())
|
Some(window.r().Document())
|
||||||
|
@ -284,7 +288,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser
|
||||||
fn Mozbrowser(self) -> bool {
|
fn Mozbrowser(self) -> bool {
|
||||||
if opts::experimental_enabled() {
|
if opts::experimental_enabled() {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.has_attribute(&Atom::from_slice("mozbrowser"))
|
element.has_attribute(&Atom::from_slice("mozbrowser"))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -293,7 +297,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
|
|
||||||
fn SetMozbrowser(self, value: bool) -> ErrorResult {
|
fn SetMozbrowser(self, value: bool) -> ErrorResult {
|
||||||
if opts::experimental_enabled() {
|
if opts::experimental_enabled() {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.set_bool_attribute(&Atom::from_slice("mozbrowser"), value);
|
element.set_bool_attribute(&Atom::from_slice("mozbrowser"), value);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -302,9 +306,9 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
|
||||||
fn GoBack(self) -> Fallible<()> {
|
fn GoBack(self) -> Fallible<()> {
|
||||||
if self.Mozbrowser() {
|
if self.Mozbrowser() {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
|
|
||||||
let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(),
|
let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(),
|
||||||
|
@ -324,9 +328,9 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goForward
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goForward
|
||||||
fn GoForward(self) -> Fallible<()> {
|
fn GoForward(self) -> Fallible<()> {
|
||||||
if self.Mozbrowser() {
|
if self.Mozbrowser() {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
|
|
||||||
let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(),
|
let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(),
|
||||||
|
@ -362,13 +366,13 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
make_setter!(SetHeight, "height");
|
make_setter!(SetHeight, "height");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
|
impl<'a> VirtualMethods for &'a HTMLIFrameElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -392,7 +396,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
self.sandbox.set(Some(modes));
|
self.sandbox.set(Some(modes));
|
||||||
}
|
}
|
||||||
&atom!("src") => {
|
&atom!("src") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
self.process_the_iframe_attributes()
|
self.process_the_iframe_attributes()
|
||||||
}
|
}
|
||||||
|
@ -408,7 +412,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
@ -437,7 +441,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
|
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
|
||||||
match (self.containing_page_pipeline_id(), self.subpage_id()) {
|
match (self.containing_page_pipeline_id(), self.subpage_id()) {
|
||||||
(Some(containing_pipeline_id), Some(subpage_id)) => {
|
(Some(containing_pipeline_id), Some(subpage_id)) => {
|
||||||
let window = window_from_node(*self).root();
|
let window = window_from_node(*self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = window.constellation_chan();
|
let ConstellationChan(ref chan) = window.constellation_chan();
|
||||||
|
|
|
@ -10,10 +10,9 @@ use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementM
|
||||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, EventTargetCast, HTMLElementCast,
|
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, EventTargetCast, HTMLElementCast,
|
||||||
HTMLImageElementDerived};
|
HTMLImageElementDerived};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, LayoutJS, Rootable, Temporary};
|
use dom::bindings::js::{LayoutJS, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::Element;
|
|
||||||
use dom::element::AttributeHandlers;
|
use dom::element::AttributeHandlers;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -51,7 +50,7 @@ pub trait HTMLImageElementHelpers {
|
||||||
fn get_url(&self) -> Option<Url>;
|
fn get_url(&self) -> Option<Url>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
impl<'a> HTMLImageElementHelpers for &'a HTMLImageElement {
|
||||||
fn get_url(&self) -> Option<Url>{
|
fn get_url(&self) -> Option<Url>{
|
||||||
self.url.borrow().clone()
|
self.url.borrow().clone()
|
||||||
}
|
}
|
||||||
|
@ -79,7 +78,7 @@ impl Responder {
|
||||||
impl ImageResponder for Responder {
|
impl ImageResponder for Responder {
|
||||||
fn respond(&self, image: ImageResponse) {
|
fn respond(&self, image: ImageResponse) {
|
||||||
// Update the image field
|
// Update the image field
|
||||||
let element = self.element.to_temporary().root();
|
let element = self.element.root();
|
||||||
let element_ref = element.r();
|
let element_ref = element.r();
|
||||||
*element_ref.image.borrow_mut() = match image {
|
*element_ref.image.borrow_mut() = match image {
|
||||||
ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => {
|
ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => {
|
||||||
|
@ -90,17 +89,17 @@ impl ImageResponder for Responder {
|
||||||
|
|
||||||
// Mark the node dirty
|
// Mark the node dirty
|
||||||
let node = NodeCast::from_ref(element.r());
|
let node = NodeCast::from_ref(element.r());
|
||||||
let document = document_from_node(node).root();
|
let document = document_from_node(node);
|
||||||
document.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
document.r().content_changed(node, NodeDamage::OtherNodeDamage);
|
||||||
|
|
||||||
// Fire image.onload
|
// Fire image.onload
|
||||||
let window = window_from_node(document.r()).root();
|
let window = window_from_node(document.r());
|
||||||
let event = Event::new(GlobalRef::Window(window.r()),
|
let event = Event::new(GlobalRef::Window(window.r()),
|
||||||
"load".to_owned(),
|
"load".to_owned(),
|
||||||
EventBubbles::DoesNotBubble,
|
EventBubbles::DoesNotBubble,
|
||||||
EventCancelable::NotCancelable).root();
|
EventCancelable::NotCancelable);
|
||||||
let event = event.r();
|
let event = event.r();
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(node);
|
let target = EventTargetCast::from_ref(node);
|
||||||
event.fire(target);
|
event.fire(target);
|
||||||
|
|
||||||
// Trigger reflow
|
// Trigger reflow
|
||||||
|
@ -108,13 +107,13 @@ impl ImageResponder for Responder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
impl<'a> PrivateHTMLImageElementHelpers for &'a HTMLImageElement {
|
||||||
/// Makes the local `image` member match the status of the `src` attribute and starts
|
/// Makes the local `image` member match the status of the `src` attribute and starts
|
||||||
/// prefetching the image. This method must be called after `src` is changed.
|
/// prefetching the image. This method must be called after `src` is changed.
|
||||||
fn update_image(self, value: Option<(DOMString, &Url)>) {
|
fn update_image(self, value: Option<(DOMString, &Url)>) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let document = node.owner_doc().root();
|
let document = node.owner_doc();
|
||||||
let window = document.r().window().root();
|
let window = document.r().window();
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let image_cache = window.image_cache_task();
|
let image_cache = window.image_cache_task();
|
||||||
match value {
|
match value {
|
||||||
|
@ -137,7 +136,7 @@ impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLImageElement {
|
impl HTMLImageElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLImageElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLImageElement {
|
||||||
HTMLImageElement {
|
HTMLImageElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLImageElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLImageElement, localName, prefix, document),
|
||||||
url: DOMRefCell::new(None),
|
url: DOMRefCell::new(None),
|
||||||
|
@ -148,7 +147,7 @@ impl HTMLImageElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLImageElement> {
|
document: &Document) -> Root<HTMLImageElement> {
|
||||||
let element = HTMLImageElement::new_inherited(localName, prefix, document);
|
let element = HTMLImageElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -174,7 +173,7 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
|
impl<'a> HTMLImageElementMethods for &'a HTMLImageElement {
|
||||||
make_getter!(Alt);
|
make_getter!(Alt);
|
||||||
|
|
||||||
make_setter!(SetAlt, "alt");
|
make_setter!(SetAlt, "alt");
|
||||||
|
@ -190,29 +189,29 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
|
||||||
make_bool_getter!(IsMap);
|
make_bool_getter!(IsMap);
|
||||||
|
|
||||||
fn SetIsMap(self, is_map: bool) {
|
fn SetIsMap(self, is_map: bool) {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
element.set_string_attribute(&atom!("ismap"), is_map.to_string())
|
element.set_string_attribute(&atom!("ismap"), is_map.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Width(self) -> u32 {
|
fn Width(self) -> u32 {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let rect = node.get_bounding_content_box();
|
let rect = node.get_bounding_content_box();
|
||||||
rect.size.width.to_px() as u32
|
rect.size.width.to_px() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetWidth(self, width: u32) {
|
fn SetWidth(self, width: u32) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.set_uint_attribute(&atom!("width"), width)
|
elem.set_uint_attribute(&atom!("width"), width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Height(self) -> u32 {
|
fn Height(self) -> u32 {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let rect = node.get_bounding_content_box();
|
let rect = node.get_bounding_content_box();
|
||||||
rect.size.height.to_px() as u32
|
rect.size.height.to_px() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn SetHeight(self, height: u32) {
|
fn SetHeight(self, height: u32) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.set_uint_attribute(&atom!("height"), height)
|
elem.set_uint_attribute(&atom!("height"), height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,20 +263,20 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
|
||||||
make_setter!(SetBorder, "border");
|
make_setter!(SetBorder, "border");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
|
impl<'a> VirtualMethods for &'a HTMLImageElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("src") => {
|
&atom!("src") => {
|
||||||
let window = window_from_node(*self).root();
|
let window = window_from_node(*self);
|
||||||
let url = window.r().get_url();
|
let url = window.r().get_url();
|
||||||
self.update_image(Some(((**attr.value()).to_owned(), &url)));
|
self.update_image(Some(((**attr.value()).to_owned(), &url)));
|
||||||
},
|
},
|
||||||
|
@ -285,7 +284,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,9 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInp
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
||||||
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::js::{OptionalRootable, ResultRootable, Root, Rootable};
|
use dom::bindings::js::{Root};
|
||||||
use dom::bindings::js::{RootedReference, Temporary};
|
use dom::bindings::js::RootedReference;
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::{AttributeHandlers, Element};
|
use dom::element::{AttributeHandlers, Element};
|
||||||
use dom::element::{RawLayoutElementHelpers, ActivationElementHelpers};
|
use dom::element::{RawLayoutElementHelpers, ActivationElementHelpers};
|
||||||
|
@ -77,6 +77,12 @@ pub struct HTMLInputElement {
|
||||||
activation_state: DOMRefCell<InputActivationState>,
|
activation_state: DOMRefCell<InputActivationState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for HTMLInputElement {
|
||||||
|
fn eq(&self, other: &HTMLInputElement) -> bool {
|
||||||
|
self as *const HTMLInputElement == &*other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
struct InputActivationState {
|
struct InputActivationState {
|
||||||
|
@ -114,8 +120,8 @@ impl HTMLInputElementDerived for EventTarget {
|
||||||
static DEFAULT_INPUT_SIZE: u32 = 20;
|
static DEFAULT_INPUT_SIZE: u32 = 20;
|
||||||
|
|
||||||
impl HTMLInputElement {
|
impl HTMLInputElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLInputElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement {
|
||||||
let chan = document.window().root().r().constellation_chan();
|
let chan = document.window().r().constellation_chan();
|
||||||
HTMLInputElement {
|
HTMLInputElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLInputElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLInputElement, localName, prefix, document),
|
||||||
input_type: Cell::new(InputType::InputText),
|
input_type: Cell::new(InputType::InputText),
|
||||||
|
@ -133,7 +139,7 @@ impl HTMLInputElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLInputElement> {
|
document: &Document) -> Root<HTMLInputElement> {
|
||||||
let element = HTMLInputElement::new_inherited(localName, prefix, document);
|
let element = HTMLInputElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLInputElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLInputElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -217,7 +223,7 @@ impl RawLayoutHTMLInputElementHelpers for HTMLInputElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
|
||||||
// https://www.whatwg.org/html/#dom-fe-disabled
|
// https://www.whatwg.org/html/#dom-fe-disabled
|
||||||
make_bool_getter!(Disabled);
|
make_bool_getter!(Disabled);
|
||||||
|
|
||||||
|
@ -335,27 +341,26 @@ pub trait HTMLInputElementHelpers {
|
||||||
fn radio_group_updated(self, group: Option<&str>);
|
fn radio_group_updated(self, group: Option<&str>);
|
||||||
fn get_radio_group_name(self) -> Option<String>;
|
fn get_radio_group_name(self) -> Option<String>;
|
||||||
fn update_checked_state(self, checked: bool, dirty: bool);
|
fn update_checked_state(self, checked: bool, dirty: bool);
|
||||||
fn get_size(&self) -> u32;
|
fn get_size(self) -> u32;
|
||||||
fn get_indeterminate_state(self) -> bool;
|
fn get_indeterminate_state(self) -> bool;
|
||||||
fn mutable(self) -> bool;
|
fn mutable(self) -> bool;
|
||||||
fn reset(self);
|
fn reset(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) {
|
fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&str>) {
|
||||||
//TODO: if not in document, use root ancestor instead of document
|
//TODO: if not in document, use root ancestor instead of document
|
||||||
let owner = broadcaster.form_owner().root();
|
let owner = broadcaster.form_owner();
|
||||||
let doc = document_from_node(broadcaster).root();
|
let doc = document_from_node(broadcaster);
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
let doc_node = NodeCast::from_ref(doc.r());
|
||||||
|
|
||||||
// This function is a workaround for lifetime constraint difficulties.
|
// This function is a workaround for lifetime constraint difficulties.
|
||||||
fn do_broadcast<'a>(doc_node: JSRef<'a, Node>, broadcaster: JSRef<'a, HTMLInputElement>,
|
fn do_broadcast(doc_node: &Node, broadcaster: &HTMLInputElement,
|
||||||
owner: Option<JSRef<'a, HTMLFormElement>>, group: Option<&str>) {
|
owner: Option<&HTMLFormElement>, group: Option<&str>) {
|
||||||
// There is no DOM tree manipulation here, so this is safe
|
// There is no DOM tree manipulation here, so this is safe
|
||||||
let iter = unsafe {
|
let iter = unsafe {
|
||||||
doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
||||||
.filter_map(HTMLInputElementCast::to_temporary)
|
.filter_map(HTMLInputElementCast::to_root)
|
||||||
.map(|t| t.root())
|
|
||||||
.filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r())
|
.filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r())
|
||||||
};
|
};
|
||||||
for ref r in iter {
|
for ref r in iter {
|
||||||
|
@ -368,10 +373,10 @@ fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&
|
||||||
do_broadcast(doc_node, broadcaster, owner.r(), group)
|
do_broadcast(doc_node, broadcaster, owner.r(), group)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>,
|
fn in_same_group<'a,'b>(other: &'a HTMLInputElement,
|
||||||
owner: Option<JSRef<'b, HTMLFormElement>>,
|
owner: Option<&'b HTMLFormElement>,
|
||||||
group: Option<&str>) -> bool {
|
group: Option<&str>) -> bool {
|
||||||
let other_owner = other.form_owner().root();
|
let other_owner = other.form_owner();
|
||||||
let other_owner = other_owner.r();
|
let other_owner = other_owner.r();
|
||||||
other.input_type.get() == InputType::InputRadio &&
|
other.input_type.get() == InputType::InputRadio &&
|
||||||
// TODO Both a and b are in the same home subtree.
|
// TODO Both a and b are in the same home subtree.
|
||||||
|
@ -384,10 +389,10 @@ fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement {
|
||||||
fn force_relayout(self) {
|
fn force_relayout(self) {
|
||||||
let doc = document_from_node(self).root();
|
let doc = document_from_node(self);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
doc.r().content_changed(node, NodeDamage::OtherNodeDamage)
|
doc.r().content_changed(node, NodeDamage::OtherNodeDamage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,9 +404,8 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
|
|
||||||
fn get_radio_group_name(self) -> Option<String> {
|
fn get_radio_group_name(self) -> Option<String> {
|
||||||
//TODO: determine form owner
|
//TODO: determine form owner
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.get_attribute(&ns!(""), &atom!("name"))
|
elem.get_attribute(&ns!(""), &atom!("name"))
|
||||||
.root()
|
|
||||||
.map(|name| name.r().Value())
|
.map(|name| name.r().Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +427,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
//TODO: dispatch change event
|
//TODO: dispatch change event
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self) -> u32 {
|
fn get_size(self) -> u32 {
|
||||||
self.size.get()
|
self.size.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +439,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
fn mutable(self) -> bool {
|
fn mutable(self) -> bool {
|
||||||
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
|
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
|
||||||
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
|
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
!(node.get_disabled_state() || self.ReadOnly())
|
!(node.get_disabled_state() || self.ReadOnly())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,20 +460,20 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
impl<'a> VirtualMethods for &'a HTMLInputElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(true);
|
node.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
node.set_enabled_state(false);
|
||||||
}
|
}
|
||||||
|
@ -525,14 +529,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(false);
|
node.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
node.set_enabled_state(true);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
|
@ -584,7 +588,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,15 +597,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||||
s.unbind_from_tree(tree_in_doc);
|
s.unbind_from_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) {
|
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
node.check_ancestors_disabled_state_for_form_control();
|
||||||
} else {
|
} else {
|
||||||
node.check_disabled_attribute();
|
node.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_event(&self, event: JSRef<Event>) {
|
fn handle_event(&self, event: &Event) {
|
||||||
if let Some(s) = self.super_type() {
|
if let Some(s) = self.super_type() {
|
||||||
s.handle_event(event);
|
s.handle_event(event);
|
||||||
}
|
}
|
||||||
|
@ -617,12 +621,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||||
|
|
||||||
//TODO: set the editing position for text inputs
|
//TODO: set the editing position for text inputs
|
||||||
|
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
doc.r().request_focus(ElementCast::from_ref(*self));
|
doc.r().request_focus(ElementCast::from_ref(*self));
|
||||||
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() &&
|
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() &&
|
||||||
(self.input_type.get() == InputType::InputText ||
|
(self.input_type.get() == InputType::InputText ||
|
||||||
self.input_type.get() == InputType::InputPassword) {
|
self.input_type.get() == InputType::InputPassword) {
|
||||||
let keyevent: Option<JSRef<KeyboardEvent>> = KeyboardEventCast::to_ref(event);
|
let keyevent: Option<&KeyboardEvent> = KeyboardEventCast::to_ref(event);
|
||||||
keyevent.map(|keyevent| {
|
keyevent.map(|keyevent| {
|
||||||
// This can't be inlined, as holding on to textinput.borrow_mut()
|
// This can't be inlined, as holding on to textinput.borrow_mut()
|
||||||
// during self.implicit_submission will cause a panic.
|
// during self.implicit_submission will cause a panic.
|
||||||
|
@ -646,15 +650,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FormControl<'a> for JSRef<'a, HTMLInputElement> {
|
impl<'a> FormControl<'a> for &'a HTMLInputElement {
|
||||||
fn to_element(self) -> JSRef<'a, Element> {
|
fn to_element(self) -> &'a Element {
|
||||||
ElementCast::from_ref(self)
|
ElementCast::from_ref(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
impl<'a> Activatable for &'a HTMLInputElement {
|
||||||
fn as_element(&self) -> Temporary<Element> {
|
fn as_element<'b>(&'b self) -> &'b Element {
|
||||||
Temporary::from_rooted(ElementCast::from_ref(*self))
|
ElementCast::from_ref(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_instance_activatable(&self) -> bool {
|
fn is_instance_activatable(&self) -> bool {
|
||||||
|
@ -697,22 +701,21 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):pre-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):pre-click-activation-steps
|
||||||
InputType::InputRadio => {
|
InputType::InputRadio => {
|
||||||
//TODO: if not in document, use root ancestor instead of document
|
//TODO: if not in document, use root ancestor instead of document
|
||||||
let owner = self.form_owner().root();
|
let owner = self.form_owner();
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
let doc_node = NodeCast::from_ref(doc.r());
|
||||||
let group = self.get_radio_group_name();;
|
let group = self.get_radio_group_name();;
|
||||||
|
|
||||||
// Safe since we only manipulate the DOM tree after finding an element
|
// Safe since we only manipulate the DOM tree after finding an element
|
||||||
let checked_member = unsafe {
|
let checked_member = unsafe {
|
||||||
doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
||||||
.filter_map(HTMLInputElementCast::to_temporary)
|
.filter_map(HTMLInputElementCast::to_root)
|
||||||
.map(|t| t.root())
|
|
||||||
.find(|r| {
|
.find(|r| {
|
||||||
in_same_group(r.r(), owner.r(), group.as_ref().map(|gr| &**gr)) &&
|
in_same_group(r.r(), owner.r(), group.as_ref().map(|gr| &**gr)) &&
|
||||||
r.r().Checked()
|
r.r().Checked()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
cache.checked_radio.set(checked_member.r().map(JS::from_rooted));
|
cache.checked_radio.set(checked_member.r().map(JS::from_ref));
|
||||||
cache.checked_changed = self.checked_changed.get();
|
cache.checked_changed = self.checked_changed.get();
|
||||||
self.SetChecked(true);
|
self.SetChecked(true);
|
||||||
}
|
}
|
||||||
|
@ -748,7 +751,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
InputType::InputRadio => {
|
InputType::InputRadio => {
|
||||||
// We want to restore state only if the element had been changed in the first place
|
// We want to restore state only if the element had been changed in the first place
|
||||||
if cache.was_mutable {
|
if cache.was_mutable {
|
||||||
let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.get().root();
|
let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.get().map(|t| t.root());
|
||||||
let name = self.get_radio_group_name();
|
let name = self.get_radio_group_name();
|
||||||
match old_checked {
|
match old_checked {
|
||||||
Some(ref o) => {
|
Some(ref o) => {
|
||||||
|
@ -773,7 +776,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
|
||||||
fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) {
|
fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
|
||||||
let ty = self.input_type.get();
|
let ty = self.input_type.get();
|
||||||
if self.activation_state.borrow().old_type != ty {
|
if self.activation_state.borrow().old_type != ty {
|
||||||
// Type changed, abandon ship
|
// Type changed, abandon ship
|
||||||
|
@ -786,8 +789,8 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
||||||
if self.mutable() /* and document owner is fully active */ {
|
if self.mutable() /* and document owner is fully active */ {
|
||||||
self.form_owner().map(|o| {
|
self.form_owner().map(|o| {
|
||||||
o.root().r().submit(SubmittedFrom::NotFromFormSubmitMethod,
|
o.r().submit(SubmittedFrom::NotFromFormSubmitMethod,
|
||||||
FormSubmitter::InputElement(self.clone()))
|
FormSubmitter::InputElement(self.clone()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -796,7 +799,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
||||||
if self.mutable() /* and document owner is fully active */ {
|
if self.mutable() /* and document owner is fully active */ {
|
||||||
self.form_owner().map(|o| {
|
self.form_owner().map(|o| {
|
||||||
o.root().r().reset(ResetFrom::NotFromFormResetMethod)
|
o.r().reset(ResetFrom::NotFromFormResetMethod)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -804,19 +807,19 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
|
||||||
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
|
||||||
if self.mutable() {
|
if self.mutable() {
|
||||||
let win = window_from_node(*self).root();
|
let win = window_from_node(*self);
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = Event::new(GlobalRef::Window(win.r()),
|
||||||
"input".to_owned(),
|
"input".to_owned(),
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::NotCancelable).root();
|
EventCancelable::NotCancelable);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
let target = EventTargetCast::from_ref(*self);
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
|
|
||||||
let event = Event::new(GlobalRef::Window(win.r()),
|
let event = Event::new(GlobalRef::Window(win.r()),
|
||||||
"change".to_owned(),
|
"change".to_owned(),
|
||||||
EventBubbles::Bubbles,
|
EventBubbles::Bubbles,
|
||||||
EventCancelable::NotCancelable).root();
|
EventCancelable::NotCancelable);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
let target = EventTargetCast::from_ref(*self);
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -827,15 +830,15 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
// https://html.spec.whatwg.org/multipage/#implicit-submission
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self);
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(doc.r());
|
let node = NodeCast::from_ref(doc.r());
|
||||||
let owner = self.form_owner();
|
let owner = self.form_owner();
|
||||||
let form = match owner {
|
let form = match owner {
|
||||||
None => return,
|
None => return,
|
||||||
Some(ref f) => f.root()
|
Some(ref f) => f
|
||||||
};
|
};
|
||||||
|
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(*self);
|
let elem = ElementCast::from_ref(*self);
|
||||||
if elem.click_in_progress() {
|
if elem.click_in_progress() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -844,8 +847,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
let submit_button;
|
let submit_button;
|
||||||
unsafe {
|
unsafe {
|
||||||
submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap()
|
submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap()
|
||||||
.filter_map(HTMLInputElementCast::to_temporary)
|
.filter_map(HTMLInputElementCast::to_root)
|
||||||
.map(|t| t.root())
|
|
||||||
.find(|r| r.r().form_owner() == owner);
|
.find(|r| r.r().form_owner() == owner);
|
||||||
}
|
}
|
||||||
match submit_button {
|
match submit_button {
|
||||||
|
@ -859,9 +861,8 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// Safe because we don't perform any DOM modification
|
// Safe because we don't perform any DOM modification
|
||||||
// until we're done with the iterator.
|
// until we're done with the iterator.
|
||||||
let inputs = node.query_selector_iter("input".to_owned()).unwrap()
|
let inputs = node.query_selector_iter("input".to_owned()).unwrap()
|
||||||
.filter_map(HTMLInputElementCast::to_temporary)
|
.filter_map(HTMLInputElementCast::to_root)
|
||||||
.filter(|input| {
|
.filter(|input| {
|
||||||
let input = input.root();
|
|
||||||
input.r().form_owner() == owner && match &*input.r().Type() {
|
input.r().form_owner() == owner && match &*input.r().Type() {
|
||||||
"text" | "search" | "url" | "tel" |
|
"text" | "search" | "url" | "tel" |
|
||||||
"email" | "password" | "datetime" |
|
"email" | "password" | "datetime" |
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLLabelElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLLabelElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLLabelElementDerived for EventTarget {
|
||||||
impl HTMLLabelElement {
|
impl HTMLLabelElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLLabelElement {
|
document: &Document) -> HTMLLabelElement {
|
||||||
HTMLLabelElement {
|
HTMLLabelElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLLabelElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLLabelElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLLabelElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLLabelElement> {
|
document: &Document) -> Root<HTMLLabelElement> {
|
||||||
let element = HTMLLabelElement::new_inherited(localName, prefix, document);
|
let element = HTMLLabelElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLLabelElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLLabelElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLLegendElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLLegendElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLLegendElementDerived for EventTarget {
|
||||||
impl HTMLLegendElement {
|
impl HTMLLegendElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLLegendElement {
|
document: &Document) -> HTMLLegendElement {
|
||||||
HTMLLegendElement {
|
HTMLLegendElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLLegendElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLLegendElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLLegendElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLLegendElement> {
|
document: &Document) -> Root<HTMLLegendElement> {
|
||||||
let element = HTMLLegendElement::new_inherited(localName, prefix, document);
|
let element = HTMLLegendElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLLegendElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLLegendElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLLIElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLLIElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -26,7 +26,7 @@ impl HTMLLIElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLLIElement {
|
impl HTMLLIElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLLIElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLLIElement {
|
||||||
HTMLLIElement {
|
HTMLLIElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLIElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLIElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLLIElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLLIElement> {
|
document: &Document) -> Root<HTMLLIElement> {
|
||||||
let element = HTMLLIElement::new_inherited(localName, prefix, document);
|
let element = HTMLLIElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLLIElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLLIElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLLinkElementDerived};
|
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLLinkElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary};
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
use dom::bindings::js::{RootedReference};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
|
@ -53,7 +53,7 @@ impl HTMLLinkElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLLinkElement {
|
impl HTMLLinkElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLLinkElement {
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLLinkElement {
|
||||||
HTMLLinkElement {
|
HTMLLinkElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLinkElement, localName, prefix, document),
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLinkElement, localName, prefix, document),
|
||||||
rel_list: Default::default(),
|
rel_list: Default::default(),
|
||||||
|
@ -63,14 +63,14 @@ impl HTMLLinkElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLLinkElement> {
|
document: &Document) -> Root<HTMLLinkElement> {
|
||||||
let element = HTMLLinkElement::new_inherited(localName, prefix, document);
|
let element = HTMLLinkElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLLinkElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLLinkElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_attr(element: JSRef<Element>, local_name: &Atom) -> Option<String> {
|
fn get_attr(element: &Element, local_name: &Atom) -> Option<String> {
|
||||||
let elem = element.get_attribute(&ns!(""), local_name).root();
|
let elem = element.get_attribute(&ns!(""), local_name);
|
||||||
elem.r().map(|e| {
|
elem.r().map(|e| {
|
||||||
let value = e.value();
|
let value = e.value();
|
||||||
(**value).to_owned()
|
(**value).to_owned()
|
||||||
|
@ -100,23 +100,23 @@ fn is_favicon(value: &Option<String>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
impl<'a> VirtualMethods for &'a HTMLLinkElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if !node.is_in_doc() {
|
if !node.is_in_doc() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(*self);
|
let element = ElementCast::from_ref(*self);
|
||||||
let rel = get_attr(element, &atom!("rel"));
|
let rel = get_attr(element, &atom!("rel"));
|
||||||
|
|
||||||
match (rel, attr.local_name()) {
|
match (rel, attr.local_name()) {
|
||||||
|
@ -149,7 +149,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if tree_in_doc {
|
if tree_in_doc {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(*self);
|
let element = ElementCast::from_ref(*self);
|
||||||
|
|
||||||
let rel = get_attr(element, &atom!("rel"));
|
let rel = get_attr(element, &atom!("rel"));
|
||||||
let href = get_attr(element, &atom!("href"));
|
let href = get_attr(element, &atom!("href"));
|
||||||
|
@ -172,15 +172,15 @@ trait PrivateHTMLLinkElementHelpers {
|
||||||
fn handle_favicon_url(self, href: &str);
|
fn handle_favicon_url(self, href: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
impl<'a> PrivateHTMLLinkElementHelpers for &'a HTMLLinkElement {
|
||||||
fn handle_stylesheet_url(self, href: &str) {
|
fn handle_stylesheet_url(self, href: &str) {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
match UrlParser::new().base_url(&window.get_url()).parse(href) {
|
match UrlParser::new().base_url(&window.get_url()).parse(href) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
|
|
||||||
let mq_attribute = element.get_attribute(&ns!(""), &atom!("media")).root();
|
let mq_attribute = element.get_attribute(&ns!(""), &atom!("media"));
|
||||||
let value = mq_attribute.r().map(|a| a.value());
|
let value = mq_attribute.r().map(|a| a.value());
|
||||||
let mq_str = match value {
|
let mq_str = match value {
|
||||||
Some(ref value) => &***value,
|
Some(ref value) => &***value,
|
||||||
|
@ -189,7 +189,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
||||||
let mut css_parser = CssParser::new(&mq_str);
|
let mut css_parser = CssParser::new(&mq_str);
|
||||||
let media = parse_media_query_list(&mut css_parser);
|
let media = parse_media_query_list(&mut css_parser);
|
||||||
|
|
||||||
let doc = window.Document().root();
|
let doc = window.Document();
|
||||||
let link_element = Trusted::new(window.get_cx(), self, window.script_chan().clone());
|
let link_element = Trusted::new(window.get_cx(), self, window.script_chan().clone());
|
||||||
let load_dispatcher = StylesheetLoadDispatcher::new(link_element);
|
let load_dispatcher = StylesheetLoadDispatcher::new(link_element);
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_favicon_url(self, href: &str) {
|
fn handle_favicon_url(self, href: &str) {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
match UrlParser::new().base_url(&window.get_url()).parse(href) {
|
match UrlParser::new().base_url(&window.get_url()).parse(href) {
|
||||||
Ok(url) => {
|
Ok(url) => {
|
||||||
|
@ -215,7 +215,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> {
|
impl<'a> HTMLLinkElementMethods for &'a HTMLLinkElement {
|
||||||
make_url_getter!(Href);
|
make_url_getter!(Href);
|
||||||
make_setter!(SetHref, "href");
|
make_setter!(SetHref, "href");
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> {
|
||||||
make_getter!(Type);
|
make_getter!(Type);
|
||||||
make_setter!(SetType, "type");
|
make_setter!(SetType, "type");
|
||||||
|
|
||||||
fn RelList(self) -> Temporary<DOMTokenList> {
|
fn RelList(self) -> Root<DOMTokenList> {
|
||||||
self.rel_list.or_init(|| {
|
self.rel_list.or_init(|| {
|
||||||
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
|
||||||
})
|
})
|
||||||
|
@ -252,11 +252,11 @@ impl StylesheetLoadDispatcher {
|
||||||
|
|
||||||
impl StylesheetLoadResponder for StylesheetLoadDispatcher {
|
impl StylesheetLoadResponder for StylesheetLoadDispatcher {
|
||||||
fn respond(self: Box<StylesheetLoadDispatcher>) {
|
fn respond(self: Box<StylesheetLoadDispatcher>) {
|
||||||
let elem = self.elem.to_temporary().root();
|
let elem = self.elem.root();
|
||||||
let window = window_from_node(elem.r()).root();
|
let window = window_from_node(elem.r());
|
||||||
let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(),
|
let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(),
|
||||||
EventBubbles::DoesNotBubble,
|
EventBubbles::DoesNotBubble,
|
||||||
EventCancelable::NotCancelable).root();
|
EventCancelable::NotCancelable);
|
||||||
let target = EventTargetCast::from_ref(elem.r());
|
let target = EventTargetCast::from_ref(elem.r());
|
||||||
event.r().fire(target);
|
event.r().fire(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLMapElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLMapElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLMapElementDerived for EventTarget {
|
||||||
impl HTMLMapElement {
|
impl HTMLMapElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLMapElement {
|
document: &Document) -> HTMLMapElement {
|
||||||
HTMLMapElement {
|
HTMLMapElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMapElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMapElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLMapElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLMapElement> {
|
document: &Document) -> Root<HTMLMapElement> {
|
||||||
let element = HTMLMapElement::new_inherited(localName, prefix, document);
|
let element = HTMLMapElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLMapElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLMapElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::js::{JSRef};
|
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLMediaElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLMediaElementDerived;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -28,7 +27,7 @@ impl HTMLMediaElementDerived for EventTarget {
|
||||||
|
|
||||||
impl HTMLMediaElement {
|
impl HTMLMediaElement {
|
||||||
pub fn new_inherited(type_id: HTMLMediaElementTypeId, tag_name: DOMString,
|
pub fn new_inherited(type_id: HTMLMediaElementTypeId, tag_name: DOMString,
|
||||||
prefix: Option<DOMString>, document: JSRef<Document>)
|
prefix: Option<DOMString>, document: &Document)
|
||||||
-> HTMLMediaElement {
|
-> HTMLMediaElement {
|
||||||
HTMLMediaElement {
|
HTMLMediaElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -29,7 +29,7 @@ impl HTMLMetaElementDerived for EventTarget {
|
||||||
impl HTMLMetaElement {
|
impl HTMLMetaElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLMetaElement {
|
document: &Document) -> HTMLMetaElement {
|
||||||
HTMLMetaElement {
|
HTMLMetaElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMetaElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMetaElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ impl HTMLMetaElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLMetaElement> {
|
document: &Document) -> Root<HTMLMetaElement> {
|
||||||
let element = HTMLMetaElement::new_inherited(localName, prefix, document);
|
let element = HTMLMetaElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLMetaElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLMetaElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLMetaElementMethods for JSRef<'a, HTMLMetaElement> {
|
impl<'a> HTMLMetaElementMethods for &'a HTMLMetaElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-meta-name
|
// https://html.spec.whatwg.org/multipage/#dom-meta-name
|
||||||
make_getter!(Name, "name");
|
make_getter!(Name, "name");
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLMeterElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLMeterElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLMeterElementDerived for EventTarget {
|
||||||
impl HTMLMeterElement {
|
impl HTMLMeterElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLMeterElement {
|
document: &Document) -> HTMLMeterElement {
|
||||||
HTMLMeterElement {
|
HTMLMeterElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMeterElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMeterElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLMeterElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLMeterElement> {
|
document: &Document) -> Root<HTMLMeterElement> {
|
||||||
let element = HTMLMeterElement::new_inherited(localName, prefix, document);
|
let element = HTMLMeterElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLMeterElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLMeterElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLModElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLModElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLModElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLModElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLModElementDerived for EventTarget {
|
||||||
impl HTMLModElement {
|
impl HTMLModElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLModElement {
|
document: &Document) -> HTMLModElement {
|
||||||
HTMLModElement {
|
HTMLModElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLModElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLModElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLModElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLModElement> {
|
document: &Document) -> Root<HTMLModElement> {
|
||||||
let element = HTMLModElement::new_inherited(localName, prefix, document);
|
let element = HTMLModElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLModElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLModElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,8 @@ use dom::bindings::codegen::Bindings::HTMLObjectElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
|
||||||
use dom::element::AttributeHandlers;
|
use dom::element::AttributeHandlers;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -42,7 +41,7 @@ impl HTMLObjectElementDerived for EventTarget {
|
||||||
impl HTMLObjectElement {
|
impl HTMLObjectElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLObjectElement {
|
document: &Document) -> HTMLObjectElement {
|
||||||
HTMLObjectElement {
|
HTMLObjectElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLObjectElement, localName, prefix, document),
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLObjectElement, localName, prefix, document),
|
||||||
|
@ -53,7 +52,7 @@ impl HTMLObjectElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLObjectElement> {
|
document: &Document) -> Root<HTMLObjectElement> {
|
||||||
let element = HTMLObjectElement::new_inherited(localName, prefix, document);
|
let element = HTMLObjectElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLObjectElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLObjectElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -63,15 +62,15 @@ trait ProcessDataURL {
|
||||||
fn process_data_url(&self);
|
fn process_data_url(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
|
impl<'a> ProcessDataURL for &'a HTMLObjectElement {
|
||||||
// Makes the local `data` member match the status of the `data` attribute and starts
|
// Makes the local `data` member match the status of the `data` attribute and starts
|
||||||
/// prefetching the image. This method must be called after `data` is changed.
|
/// prefetching the image. This method must be called after `data` is changed.
|
||||||
fn process_data_url(&self) {
|
fn process_data_url(&self) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(*self);
|
let elem = ElementCast::from_ref(*self);
|
||||||
|
|
||||||
// TODO: support other values
|
// TODO: support other values
|
||||||
match (elem.get_attribute(&ns!(""), &atom!("type")).map(|x| x.root().r().Value()),
|
match (elem.get_attribute(&ns!(""), &atom!("type")).map(|x| x.r().Value()),
|
||||||
elem.get_attribute(&ns!(""), &atom!("data")).map(|x| x.root().r().Value())) {
|
elem.get_attribute(&ns!(""), &atom!("data")).map(|x| x.r().Value())) {
|
||||||
(None, Some(_uri)) => {
|
(None, Some(_uri)) => {
|
||||||
// TODO(gw): Prefetch the image here.
|
// TODO(gw): Prefetch the image here.
|
||||||
}
|
}
|
||||||
|
@ -85,9 +84,9 @@ pub fn is_image_data(uri: &str) -> bool {
|
||||||
TYPES.iter().any(|&type_| uri.starts_with(type_))
|
TYPES.iter().any(|&type_| uri.starts_with(type_))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
|
impl<'a> HTMLObjectElementMethods for &'a HTMLObjectElement {
|
||||||
fn Validity(self) -> Temporary<ValidityState> {
|
fn Validity(self) -> Root<ValidityState> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
ValidityState::new(window.r())
|
ValidityState::new(window.r())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,13 +97,13 @@ impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
|
||||||
make_setter!(SetType, "type");
|
make_setter!(SetType, "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
|
impl<'a> VirtualMethods for &'a HTMLObjectElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLOListElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLOListElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLOListElementDerived for EventTarget {
|
||||||
impl HTMLOListElement {
|
impl HTMLOListElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLOListElement {
|
document: &Document) -> HTMLOListElement {
|
||||||
HTMLOListElement {
|
HTMLOListElement {
|
||||||
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOListElement, localName, prefix, document)
|
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOListElement, localName, prefix, document)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl HTMLOListElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLOListElement> {
|
document: &Document) -> Root<HTMLOListElement> {
|
||||||
let element = HTMLOListElement::new_inherited(localName, prefix, document);
|
let element = HTMLOListElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLOListElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLOListElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, HTMLOptionElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, HTMLOptionElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::AttributeHandlers;
|
use dom::element::AttributeHandlers;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
|
@ -35,7 +35,7 @@ impl HTMLOptGroupElementDerived for EventTarget {
|
||||||
impl HTMLOptGroupElement {
|
impl HTMLOptGroupElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLOptGroupElement {
|
document: &Document) -> HTMLOptGroupElement {
|
||||||
HTMLOptGroupElement {
|
HTMLOptGroupElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptGroupElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptGroupElement, localName, prefix, document)
|
||||||
|
@ -45,13 +45,13 @@ impl HTMLOptGroupElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLOptGroupElement> {
|
document: &Document) -> Root<HTMLOptGroupElement> {
|
||||||
let element = HTMLOptGroupElement::new_inherited(localName, prefix, document);
|
let element = HTMLOptGroupElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLOptGroupElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLOptGroupElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> {
|
impl<'a> HTMLOptGroupElementMethods for &'a HTMLOptGroupElement {
|
||||||
// https://www.whatwg.org/html#dom-optgroup-disabled
|
// https://www.whatwg.org/html#dom-optgroup-disabled
|
||||||
make_bool_getter!(Disabled);
|
make_bool_getter!(Disabled);
|
||||||
|
|
||||||
|
@ -59,24 +59,23 @@ impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> {
|
||||||
make_bool_setter!(SetDisabled, "disabled");
|
make_bool_setter!(SetDisabled, "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLOptGroupElement> {
|
impl<'a> VirtualMethods for &'a HTMLOptGroupElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(true);
|
node.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
node.set_enabled_state(false);
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
let child = child.root();
|
|
||||||
if child.r().is_htmloptionelement() {
|
if child.r().is_htmloptionelement() {
|
||||||
child.r().set_disabled_state(true);
|
child.r().set_disabled_state(true);
|
||||||
child.r().set_enabled_state(false);
|
child.r().set_enabled_state(false);
|
||||||
|
@ -87,18 +86,17 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptGroupElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(false);
|
node.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
node.set_enabled_state(true);
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
let child = child.root();
|
|
||||||
if child.r().is_htmloptionelement() {
|
if child.r().is_htmloptionelement() {
|
||||||
child.r().check_disabled_attribute();
|
child.r().check_disabled_attribute();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,13 @@ use dom::attr::AttrHelpers;
|
||||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast, HTMLElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast, HTMLElementCast, NodeCast, TextDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLOptionElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLOptionElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived};
|
||||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::characterdata::CharacterData;
|
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, Element, ElementHelpers};
|
use dom::element::{AttributeHandlers, ElementHelpers};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
||||||
|
@ -39,7 +38,7 @@ impl HTMLOptionElementDerived for EventTarget {
|
||||||
impl HTMLOptionElement {
|
impl HTMLOptionElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLOptionElement {
|
document: &Document) -> HTMLOptionElement {
|
||||||
HTMLOptionElement {
|
HTMLOptionElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptionElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptionElement, localName, prefix, document)
|
||||||
|
@ -49,23 +48,22 @@ impl HTMLOptionElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLOptionElement> {
|
document: &Document) -> Root<HTMLOptionElement> {
|
||||||
let element = HTMLOptionElement::new_inherited(localName, prefix, document);
|
let element = HTMLOptionElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLOptionElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLOptionElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_text(node: &JSRef<Node>, value: &mut DOMString) {
|
fn collect_text(node: &&Node, value: &mut DOMString) {
|
||||||
let elem: JSRef<Element> = ElementCast::to_ref(*node).unwrap();
|
let elem = ElementCast::to_ref(*node).unwrap();
|
||||||
let svg_script = *elem.namespace() == ns!(SVG) && elem.local_name() == &atom!("script");
|
let svg_script = *elem.namespace() == ns!(SVG) && elem.local_name() == &atom!("script");
|
||||||
let html_script = node.is_htmlscriptelement();
|
let html_script = node.is_htmlscriptelement();
|
||||||
if svg_script || html_script {
|
if svg_script || html_script {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
for child in node.children() {
|
for child in node.children() {
|
||||||
let child = child.root();
|
|
||||||
if child.r().is_text() {
|
if child.r().is_text() {
|
||||||
let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(child.r()).unwrap();
|
let characterdata = CharacterDataCast::to_ref(child.r()).unwrap();
|
||||||
value.push_str(&characterdata.Data());
|
value.push_str(&characterdata.Data());
|
||||||
} else {
|
} else {
|
||||||
collect_text(&child.r(), value);
|
collect_text(&child.r(), value);
|
||||||
|
@ -74,19 +72,19 @@ fn collect_text(node: &JSRef<Node>, value: &mut DOMString) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> {
|
impl<'a> HTMLOptionElementMethods for &'a HTMLOptionElement {
|
||||||
// https://www.whatwg.org/html/#dom-option-disabled
|
// https://www.whatwg.org/html/#dom-option-disabled
|
||||||
make_bool_getter!(Disabled);
|
make_bool_getter!(Disabled);
|
||||||
|
|
||||||
// https://www.whatwg.org/html/#dom-option-disabled
|
// https://www.whatwg.org/html/#dom-option-disabled
|
||||||
fn SetDisabled(self, disabled: bool) {
|
fn SetDisabled(self, disabled: bool) {
|
||||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
let elem = ElementCast::from_ref(self);
|
||||||
elem.set_bool_attribute(&atom!("disabled"), disabled)
|
elem.set_bool_attribute(&atom!("disabled"), disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.whatwg.org/html/#dom-option-text
|
// https://www.whatwg.org/html/#dom-option-text
|
||||||
fn Text(self) -> DOMString {
|
fn Text(self) -> DOMString {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
let mut content = String::new();
|
let mut content = String::new();
|
||||||
collect_text(&node, &mut content);
|
collect_text(&node, &mut content);
|
||||||
let v: Vec<&str> = split_html_space_chars(&content).collect();
|
let v: Vec<&str> = split_html_space_chars(&content).collect();
|
||||||
|
@ -95,13 +93,13 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
|
|
||||||
// https://www.whatwg.org/html/#dom-option-text
|
// https://www.whatwg.org/html/#dom-option-text
|
||||||
fn SetText(self, value: DOMString) {
|
fn SetText(self, value: DOMString) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.SetTextContent(Some(value))
|
node.SetTextContent(Some(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#attr-option-value
|
// https://html.spec.whatwg.org/multipage/#attr-option-value
|
||||||
fn Value(self) -> DOMString {
|
fn Value(self) -> DOMString {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
let attr = &atom!("value");
|
let attr = &atom!("value");
|
||||||
if element.has_attribute(attr) {
|
if element.has_attribute(attr) {
|
||||||
element.get_string_attribute(attr)
|
element.get_string_attribute(attr)
|
||||||
|
@ -115,7 +113,7 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#attr-option-label
|
// https://html.spec.whatwg.org/multipage/#attr-option-label
|
||||||
fn Label(self) -> DOMString {
|
fn Label(self) -> DOMString {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
let attr = &atom!("label");
|
let attr = &atom!("label");
|
||||||
if element.has_attribute(attr) {
|
if element.has_attribute(attr) {
|
||||||
element.get_string_attribute(attr)
|
element.get_string_attribute(attr)
|
||||||
|
@ -129,20 +127,20 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> {
|
impl<'a> VirtualMethods for &'a HTMLOptionElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(true);
|
node.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
node.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
|
@ -150,14 +148,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_remove_attr(&self, attr: JSRef<Attr>) {
|
fn before_remove_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.before_remove_attr(attr);
|
s.before_remove_attr(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!("disabled") => {
|
&atom!("disabled") => {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.set_disabled_state(false);
|
node.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
node.set_enabled_state(true);
|
||||||
node.check_parent_disabled_state_for_option();
|
node.check_parent_disabled_state_for_option();
|
||||||
|
@ -171,7 +169,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
node.check_parent_disabled_state_for_option();
|
node.check_parent_disabled_state_for_option();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +178,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> {
|
||||||
s.unbind_from_tree(tree_in_doc);
|
s.unbind_from_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if node.GetParentNode().is_some() {
|
if node.GetParentNode().is_some() {
|
||||||
node.check_parent_disabled_state_for_option();
|
node.check_parent_disabled_state_for_option();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding::HTMLOutputElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLOutputElementBinding::HTMLOutputElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Rootable, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -30,7 +30,7 @@ impl HTMLOutputElementDerived for EventTarget {
|
||||||
impl HTMLOutputElement {
|
impl HTMLOutputElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLOutputElement {
|
document: &Document) -> HTMLOutputElement {
|
||||||
HTMLOutputElement {
|
HTMLOutputElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOutputElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLOutputElement, localName, prefix, document)
|
||||||
|
@ -40,15 +40,15 @@ impl HTMLOutputElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLOutputElement> {
|
document: &Document) -> Root<HTMLOutputElement> {
|
||||||
let element = HTMLOutputElement::new_inherited(localName, prefix, document);
|
let element = HTMLOutputElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLOutputElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLOutputElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLOutputElementMethods for JSRef<'a, HTMLOutputElement> {
|
impl<'a> HTMLOutputElementMethods for &'a HTMLOutputElement {
|
||||||
fn Validity(self) -> Temporary<ValidityState> {
|
fn Validity(self) -> Root<ValidityState> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
ValidityState::new(window.r())
|
ValidityState::new(window.r())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLParagraphElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLParagraphElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLParagraphElementDerived for EventTarget {
|
||||||
impl HTMLParagraphElement {
|
impl HTMLParagraphElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLParagraphElement {
|
document: &Document) -> HTMLParagraphElement {
|
||||||
HTMLParagraphElement {
|
HTMLParagraphElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLParagraphElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLParagraphElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLParagraphElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLParagraphElement> {
|
document: &Document) -> Root<HTMLParagraphElement> {
|
||||||
let element = HTMLParagraphElement::new_inherited(localName, prefix, document);
|
let element = HTMLParagraphElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLParagraphElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLParagraphElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLParamElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLParamElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLParamElementDerived for EventTarget {
|
||||||
impl HTMLParamElement {
|
impl HTMLParamElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLParamElement {
|
document: &Document) -> HTMLParamElement {
|
||||||
HTMLParamElement {
|
HTMLParamElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLParamElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLParamElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLParamElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLParamElement> {
|
document: &Document) -> Root<HTMLParamElement> {
|
||||||
let element = HTMLParamElement::new_inherited(localName, prefix, document);
|
let element = HTMLParamElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLParamElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLParamElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLPreElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLPreElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLPreElementDerived for EventTarget {
|
||||||
impl HTMLPreElement {
|
impl HTMLPreElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLPreElement {
|
document: &Document) -> HTMLPreElement {
|
||||||
HTMLPreElement {
|
HTMLPreElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLPreElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLPreElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLPreElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLPreElement> {
|
document: &Document) -> Root<HTMLPreElement> {
|
||||||
let element = HTMLPreElement::new_inherited(localName, prefix, document);
|
let element = HTMLPreElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLPreElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLPreElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLProgressElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLProgressElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLProgressElementDerived for EventTarget {
|
||||||
impl HTMLProgressElement {
|
impl HTMLProgressElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLProgressElement {
|
document: &Document) -> HTMLProgressElement {
|
||||||
HTMLProgressElement {
|
HTMLProgressElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLProgressElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLProgressElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLProgressElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLProgressElement> {
|
document: &Document) -> Root<HTMLProgressElement> {
|
||||||
let element = HTMLProgressElement::new_inherited(localName, prefix, document);
|
let element = HTMLProgressElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLProgressElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLProgressElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLQuoteElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLQuoteElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived;
|
use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -28,7 +28,7 @@ impl HTMLQuoteElementDerived for EventTarget {
|
||||||
impl HTMLQuoteElement {
|
impl HTMLQuoteElement {
|
||||||
fn new_inherited(localName: DOMString,
|
fn new_inherited(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> HTMLQuoteElement {
|
document: &Document) -> HTMLQuoteElement {
|
||||||
HTMLQuoteElement {
|
HTMLQuoteElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited(HTMLElementTypeId::HTMLQuoteElement, localName, prefix, document)
|
HTMLElement::new_inherited(HTMLElementTypeId::HTMLQuoteElement, localName, prefix, document)
|
||||||
|
@ -38,7 +38,7 @@ impl HTMLQuoteElement {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString,
|
pub fn new(localName: DOMString,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
document: JSRef<Document>) -> Temporary<HTMLQuoteElement> {
|
document: &Document) -> Root<HTMLQuoteElement> {
|
||||||
let element = HTMLQuoteElement::new_inherited(localName, prefix, document);
|
let element = HTMLQuoteElement::new_inherited(localName, prefix, document);
|
||||||
Node::reflect_node(box element, document, HTMLQuoteElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLQuoteElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, HTMLScriptE
|
||||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
||||||
use dom::bindings::codegen::InheritTypes::EventTargetCast;
|
use dom::bindings::codegen::InheritTypes::EventTargetCast;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Rootable};
|
use dom::bindings::js::{JS, Root};
|
||||||
use dom::bindings::js::RootedReference;
|
use dom::bindings::js::RootedReference;
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::trace::JSTraceable;
|
use dom::bindings::trace::JSTraceable;
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::{Element, AttributeHandlers, ElementCreator};
|
use dom::element::{AttributeHandlers, ElementCreator};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
||||||
use dom::element::ElementTypeId;
|
use dom::element::ElementTypeId;
|
||||||
|
@ -33,6 +33,8 @@ use dom::virtualmethods::VirtualMethods;
|
||||||
use dom::window::{WindowHelpers, ScriptHelpers};
|
use dom::window::{WindowHelpers, ScriptHelpers};
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
use script_task::{ScriptChan, ScriptMsg, Runnable};
|
use script_task::{ScriptChan, ScriptMsg, Runnable};
|
||||||
|
use js::jsapi::RootedValue;
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
|
||||||
use encoding::all::UTF_8;
|
use encoding::all::UTF_8;
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
|
@ -82,7 +84,7 @@ impl HTMLScriptElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLScriptElement {
|
impl HTMLScriptElement {
|
||||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>,
|
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document,
|
||||||
creator: ElementCreator) -> HTMLScriptElement {
|
creator: ElementCreator) -> HTMLScriptElement {
|
||||||
HTMLScriptElement {
|
HTMLScriptElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
|
@ -91,14 +93,14 @@ impl HTMLScriptElement {
|
||||||
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
||||||
non_blocking: Cell::new(creator != ElementCreator::ParserCreated),
|
non_blocking: Cell::new(creator != ElementCreator::ParserCreated),
|
||||||
ready_to_be_parser_executed: Cell::new(false),
|
ready_to_be_parser_executed: Cell::new(false),
|
||||||
parser_document: JS::from_rooted(document),
|
parser_document: JS::from_ref(document),
|
||||||
block_character_encoding: DOMRefCell::new(UTF_8 as EncodingRef),
|
block_character_encoding: DOMRefCell::new(UTF_8 as EncodingRef),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>,
|
pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document,
|
||||||
creator: ElementCreator) -> Temporary<HTMLScriptElement> {
|
creator: ElementCreator) -> Root<HTMLScriptElement> {
|
||||||
let element = HTMLScriptElement::new_inherited(localName, prefix, document, creator);
|
let element = HTMLScriptElement::new_inherited(localName, prefix, document, creator);
|
||||||
Node::reflect_node(box element, document, HTMLScriptElementBinding::Wrap)
|
Node::reflect_node(box element, document, HTMLScriptElementBinding::Wrap)
|
||||||
}
|
}
|
||||||
|
@ -190,22 +192,22 @@ impl AsyncResponseListener for ScriptContext {
|
||||||
let metadata = self.metadata.borrow_mut().take().unwrap();
|
let metadata = self.metadata.borrow_mut().take().unwrap();
|
||||||
(metadata, data)
|
(metadata, data)
|
||||||
});
|
});
|
||||||
let elem = self.elem.to_temporary().root();
|
let elem = self.elem.root();
|
||||||
|
|
||||||
elem.r().execute(ScriptOrigin::External(load));
|
elem.r().execute(ScriptOrigin::External(load));
|
||||||
|
|
||||||
let document = document_from_node(elem.r()).root();
|
let document = document_from_node(elem.r());
|
||||||
document.r().finish_load(LoadType::Script(self.url.clone()));
|
document.r().finish_load(LoadType::Script(self.url.clone()));
|
||||||
|
|
||||||
if self.resume_on_completion {
|
if self.resume_on_completion {
|
||||||
document.r().get_current_parser().unwrap().root().r().resume();
|
document.r().get_current_parser().unwrap().r().resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PreInvoke for ScriptContext {}
|
impl PreInvoke for ScriptContext {}
|
||||||
|
|
||||||
impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement {
|
||||||
fn prepare(self) -> NextParserState {
|
fn prepare(self) -> NextParserState {
|
||||||
// https://html.spec.whatwg.org/multipage/#prepare-a-script
|
// https://html.spec.whatwg.org/multipage/#prepare-a-script
|
||||||
// Step 1.
|
// Step 1.
|
||||||
|
@ -217,7 +219,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
self.parser_inserted.set(false);
|
self.parser_inserted.set(false);
|
||||||
|
|
||||||
// Step 3.
|
// Step 3.
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
if was_parser_inserted && element.has_attribute(&atom!("async")) {
|
if was_parser_inserted && element.has_attribute(&atom!("async")) {
|
||||||
self.non_blocking.set(true);
|
self.non_blocking.set(true);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +229,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
return NextParserState::Continue;
|
return NextParserState::Continue;
|
||||||
}
|
}
|
||||||
// Step 5.
|
// Step 5.
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
if !node.is_in_doc() {
|
if !node.is_in_doc() {
|
||||||
return NextParserState::Continue;
|
return NextParserState::Continue;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +246,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
self.already_started.set(true);
|
self.already_started.set(true);
|
||||||
|
|
||||||
// Step 10.
|
// Step 10.
|
||||||
let document_from_node_ref = document_from_node(self).root();
|
let document_from_node_ref = document_from_node(self);
|
||||||
let document_from_node_ref = document_from_node_ref.r();
|
let document_from_node_ref = document_from_node_ref.r();
|
||||||
if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref {
|
if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref {
|
||||||
return NextParserState::Continue;
|
return NextParserState::Continue;
|
||||||
|
@ -256,8 +258,8 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 12.
|
// Step 12.
|
||||||
let for_attribute = element.get_attribute(&ns!(""), &atom!("for")).root();
|
let for_attribute = element.get_attribute(&ns!(""), &atom!("for"));
|
||||||
let event_attribute = element.get_attribute(&ns!(""), &Atom::from_slice("event")).root();
|
let event_attribute = element.get_attribute(&ns!(""), &Atom::from_slice("event"));
|
||||||
match (for_attribute.r(), event_attribute.r()) {
|
match (for_attribute.r(), event_attribute.r()) {
|
||||||
(Some(for_attribute), Some(event_attribute)) => {
|
(Some(for_attribute), Some(event_attribute)) => {
|
||||||
let for_value = for_attribute.Value()
|
let for_value = for_attribute.Value()
|
||||||
|
@ -277,18 +279,18 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 13.
|
// Step 13.
|
||||||
if let Some(ref charset) = element.get_attribute(&ns!(""), &Atom::from_slice("charset")).root() {
|
if let Some(ref charset) = element.get_attribute(&ns!(""), &Atom::from_slice("charset")) {
|
||||||
if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) {
|
if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) {
|
||||||
*self.block_character_encoding.borrow_mut() = encodingRef;
|
*self.block_character_encoding.borrow_mut() = encodingRef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 14.
|
// Step 14.
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let base_url = window.get_url();
|
let base_url = window.get_url();
|
||||||
|
|
||||||
let load = match element.get_attribute(&ns!(""), &atom!("src")).root() {
|
let load = match element.get_attribute(&ns!(""), &atom!("src")) {
|
||||||
// Step 14.
|
// Step 14.
|
||||||
Some(ref src) => {
|
Some(ref src) => {
|
||||||
// Step 14.1
|
// Step 14.1
|
||||||
|
@ -314,7 +316,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
// state of the element's `crossorigin` content attribute, the origin being
|
// state of the element's `crossorigin` content attribute, the origin being
|
||||||
// the origin of the script element's node document, and the default origin
|
// the origin of the script element's node document, and the default origin
|
||||||
// behaviour set to taint.
|
// behaviour set to taint.
|
||||||
let doc = document_from_node(self).root();
|
let doc = document_from_node(self);
|
||||||
|
|
||||||
let script_chan = window.script_chan();
|
let script_chan = window.script_chan();
|
||||||
let elem = Trusted::new(window.get_cx(), self, script_chan.clone());
|
let elem = Trusted::new(window.get_cx(), self, script_chan.clone());
|
||||||
|
@ -335,7 +337,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
doc.r().load_async(LoadType::Script(url), listener);
|
doc.r().load_async(LoadType::Script(url), listener);
|
||||||
|
|
||||||
if self.parser_inserted.get() {
|
if self.parser_inserted.get() {
|
||||||
doc.r().get_current_parser().unwrap().root().r().suspend();
|
doc.r().get_current_parser().unwrap().r().suspend();
|
||||||
}
|
}
|
||||||
return NextParserState::Suspend;
|
return NextParserState::Suspend;
|
||||||
}
|
}
|
||||||
|
@ -409,18 +411,20 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
// document. Let neutralised doc be that Document.
|
// document. Let neutralised doc be that Document.
|
||||||
|
|
||||||
// Step 2.b.4.
|
// Step 2.b.4.
|
||||||
let document = document_from_node(self).root();
|
let document = document_from_node(self);
|
||||||
let document = document.r();
|
let document = document.r();
|
||||||
let old_script = document.GetCurrentScript().root();
|
let old_script = document.GetCurrentScript();
|
||||||
|
|
||||||
// Step 2.b.5.
|
// Step 2.b.5.
|
||||||
document.set_current_script(Some(self));
|
document.set_current_script(Some(self));
|
||||||
|
|
||||||
// Step 2.b.6.
|
// Step 2.b.6.
|
||||||
// TODO: Create a script...
|
// TODO: Create a script...
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
|
let mut rval = RootedValue::new(window.r().get_cx(), UndefinedValue());
|
||||||
window.r().evaluate_script_on_global_with_result(&*source,
|
window.r().evaluate_script_on_global_with_result(&*source,
|
||||||
&*url.serialize());
|
&*url.serialize(),
|
||||||
|
rval.handle_mut());
|
||||||
|
|
||||||
// Step 2.b.7.
|
// Step 2.b.7.
|
||||||
document.set_current_script(old_script.r());
|
document.set_current_script(old_script.r());
|
||||||
|
@ -447,7 +451,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queue_error_event(self) {
|
fn queue_error_event(self) {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let chan = window.script_chan();
|
let chan = window.script_chan();
|
||||||
let handler = Trusted::new(window.get_cx(), self, chan.clone());
|
let handler = Trusted::new(window.get_cx(), self, chan.clone());
|
||||||
|
@ -483,8 +487,8 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_javascript(self) -> bool {
|
fn is_javascript(self) -> bool {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
let element = ElementCast::from_ref(self);
|
||||||
match element.get_attribute(&ns!(""), &atom!("type")).root().map(|s| s.r().Value()) {
|
match element.get_attribute(&ns!(""), &atom!("type")).map(|s| s.r().Value()) {
|
||||||
Some(ref s) if s.is_empty() => {
|
Some(ref s) if s.is_empty() => {
|
||||||
// type attr exists, but empty means js
|
// type attr exists, but empty means js
|
||||||
debug!("script type empty, inferring js");
|
debug!("script type empty, inferring js");
|
||||||
|
@ -497,7 +501,6 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
||||||
None => {
|
None => {
|
||||||
debug!("no script type");
|
debug!("no script type");
|
||||||
match element.get_attribute(&ns!(""), &atom!("language"))
|
match element.get_attribute(&ns!(""), &atom!("language"))
|
||||||
.root()
|
|
||||||
.map(|s| s.r().Value()) {
|
.map(|s| s.r().Value()) {
|
||||||
Some(ref s) if s.is_empty() => {
|
Some(ref s) if s.is_empty() => {
|
||||||
debug!("script language empty, inferring js");
|
debug!("script language empty, inferring js");
|
||||||
|
@ -528,44 +531,44 @@ trait PrivateHTMLScriptElementHelpers {
|
||||||
cancelable: EventCancelable) -> bool;
|
cancelable: EventCancelable) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateHTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> {
|
impl<'a> PrivateHTMLScriptElementHelpers for &'a HTMLScriptElement {
|
||||||
fn dispatch_event(self,
|
fn dispatch_event(self,
|
||||||
type_: DOMString,
|
type_: DOMString,
|
||||||
bubbles: EventBubbles,
|
bubbles: EventBubbles,
|
||||||
cancelable: EventCancelable) -> bool {
|
cancelable: EventCancelable) -> bool {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self);
|
||||||
let window = window.r();
|
let window = window.r();
|
||||||
let event = Event::new(GlobalRef::Window(window),
|
let event = Event::new(GlobalRef::Window(window),
|
||||||
type_,
|
type_,
|
||||||
bubbles,
|
bubbles,
|
||||||
cancelable).root();
|
cancelable);
|
||||||
let event = event.r();
|
let event = event.r();
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
let target = EventTargetCast::from_ref(self);
|
||||||
event.fire(target)
|
event.fire(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> {
|
impl<'a> VirtualMethods for &'a HTMLScriptElement {
|
||||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||||
let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
|
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
|
||||||
Some(htmlelement as &VirtualMethods)
|
Some(htmlelement as &VirtualMethods)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_set_attr(&self, attr: JSRef<Attr>) {
|
fn after_set_attr(&self, attr: &Attr) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.after_set_attr(attr);
|
s.after_set_attr(attr);
|
||||||
}
|
}
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if attr.local_name() == &atom!("src") && !self.parser_inserted.get() && node.is_in_doc() {
|
if attr.local_name() == &atom!("src") && !self.parser_inserted.get() && node.is_in_doc() {
|
||||||
self.prepare();
|
self.prepare();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_inserted(&self, child: JSRef<Node>) {
|
fn child_inserted(&self, child: &Node) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.child_inserted(child);
|
s.child_inserted(child);
|
||||||
}
|
}
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(*self);
|
let node = NodeCast::from_ref(*self);
|
||||||
if !self.parser_inserted.get() && node.is_in_doc() {
|
if !self.parser_inserted.get() && node.is_in_doc() {
|
||||||
self.prepare();
|
self.prepare();
|
||||||
}
|
}
|
||||||
|
@ -581,7 +584,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cloning_steps(&self, copy: JSRef<Node>, maybe_doc: Option<JSRef<Document>>,
|
fn cloning_steps(&self, copy: &Node, maybe_doc: Option<&Document>,
|
||||||
clone_children: CloneChildrenFlag) {
|
clone_children: CloneChildrenFlag) {
|
||||||
if let Some(ref s) = self.super_type() {
|
if let Some(ref s) = self.super_type() {
|
||||||
s.cloning_steps(copy, maybe_doc, clone_children);
|
s.cloning_steps(copy, maybe_doc, clone_children);
|
||||||
|
@ -589,13 +592,13 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> {
|
||||||
|
|
||||||
// https://whatwg.org/html/#already-started
|
// https://whatwg.org/html/#already-started
|
||||||
if self.already_started.get() {
|
if self.already_started.get() {
|
||||||
let copy_elem: JSRef<HTMLScriptElement> = HTMLScriptElementCast::to_ref(copy).unwrap();
|
let copy_elem = HTMLScriptElementCast::to_ref(copy).unwrap();
|
||||||
copy_elem.mark_already_started();
|
copy_elem.mark_already_started();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> {
|
impl<'a> HTMLScriptElementMethods for &'a HTMLScriptElement {
|
||||||
make_url_getter!(Src);
|
make_url_getter!(Src);
|
||||||
|
|
||||||
make_setter!(SetSrc, "src");
|
make_setter!(SetSrc, "src");
|
||||||
|
@ -607,7 +610,7 @@ impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> {
|
||||||
|
|
||||||
// https://www.whatwg.org/html/#dom-script-text
|
// https://www.whatwg.org/html/#dom-script-text
|
||||||
fn SetText(self, value: DOMString) {
|
fn SetText(self, value: DOMString) {
|
||||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.SetTextContent(Some(value))
|
node.SetTextContent(Some(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,7 +622,7 @@ struct EventDispatcher {
|
||||||
|
|
||||||
impl Runnable for EventDispatcher {
|
impl Runnable for EventDispatcher {
|
||||||
fn handler(self: Box<EventDispatcher>) {
|
fn handler(self: Box<EventDispatcher>) {
|
||||||
let target = self.element.to_temporary().root();
|
let target = self.element.root();
|
||||||
if self.is_error {
|
if self.is_error {
|
||||||
target.r().dispatch_error_event();
|
target.r().dispatch_error_event();
|
||||||
} else {
|
} else {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue