Merge branch 'master' into calc

This commit is contained in:
Simon Sapin 2015-09-01 18:39:16 +02:00
commit 80d471d5cf
400 changed files with 8129 additions and 11782 deletions

View file

@ -112,14 +112,12 @@ impl WebGLPaintTask {
gl::enable_vertex_attrib_array(attrib_id),
CanvasWebGLMsg::GetAttribLocation(program_id, name, chan) =>
self.get_attrib_location(program_id, name, chan),
CanvasWebGLMsg::GetShaderInfoLog(shader_id, chan) =>
self.get_shader_info_log(shader_id, chan),
CanvasWebGLMsg::GetShaderParameter(shader_id, param_id, chan) =>
self.get_shader_parameter(shader_id, param_id, chan),
CanvasWebGLMsg::GetUniformLocation(program_id, name, chan) =>
self.get_uniform_location(program_id, name, chan),
CanvasWebGLMsg::CompileShader(shader_id) =>
self.compile_shader(shader_id),
CanvasWebGLMsg::CompileShader(shader_id, source) =>
self.compile_shader(shader_id, source),
CanvasWebGLMsg::CreateBuffer(chan) =>
self.create_buffer(chan),
CanvasWebGLMsg::CreateFramebuffer(chan) =>
@ -154,8 +152,6 @@ impl WebGLPaintTask {
gl::bind_texture(target, id),
CanvasWebGLMsg::LinkProgram(program_id) =>
gl::link_program(program_id),
CanvasWebGLMsg::ShaderSource(shader_id, source) =>
gl::shader_source(shader_id, &[source.as_bytes()]),
CanvasWebGLMsg::Uniform4fv(uniform_id, data) =>
gl::uniform_4f(uniform_id, data[0], data[1], data[2], data[3]),
CanvasWebGLMsg::UseProgram(program_id) =>
@ -303,11 +299,9 @@ impl WebGLPaintTask {
gl::bind_framebuffer(target, id);
}
// TODO(ecoal95): This is not spec-compliant, we must check
// the version of GLSL used. This functionality should probably
// be in the WebGLShader object
#[inline]
fn compile_shader(&self, shader_id: u32) {
fn compile_shader(&self, shader_id: u32, source: String) {
gl::shader_source(shader_id, &[source.as_bytes()]);
gl::compile_shader(shader_id);
}
@ -323,13 +317,6 @@ impl WebGLPaintTask {
chan.send(attrib_location).unwrap();
}
fn get_shader_info_log(&self, shader_id: u32, chan: IpcSender<Option<String>>) {
// TODO(ecoal95): Right now we always return a value, we should
// check for gl errors and return None there
let info = gl::get_shader_info_log(shader_id);
chan.send(Some(info)).unwrap();
}
fn get_shader_parameter(&self,
shader_id: u32,
param_id: u32,

View file

@ -138,7 +138,7 @@ pub enum CanvasWebGLMsg {
DepthRange(f64, f64),
Enable(u32),
Disable(u32),
CompileShader(u32),
CompileShader(u32, String),
CreateBuffer(IpcSender<Option<NonZero<u32>>>),
CreateFramebuffer(IpcSender<Option<NonZero<u32>>>),
CreateRenderbuffer(IpcSender<Option<NonZero<u32>>>),
@ -157,7 +157,6 @@ pub enum CanvasWebGLMsg {
BindTexture(u32, u32),
DrawArrays(u32, i32, i32),
EnableVertexAttribArray(u32),
GetShaderInfoLog(u32, IpcSender<Option<String>>),
GetShaderParameter(u32, u32, IpcSender<WebGLShaderParameter>),
GetAttribLocation(u32, String, IpcSender<Option<i32>>),
GetUniformLocation(u32, String, IpcSender<Option<i32>>),
@ -166,7 +165,6 @@ pub enum CanvasWebGLMsg {
LineWidth(f32),
PixelStorei(u32, i32),
LinkProgram(u32),
ShaderSource(u32, String),
Uniform4fv(i32, Vec<f32>),
UseProgram(u32),
VertexAttribPointer2f(u32, i32, bool, i32, u32),

View file

@ -54,8 +54,8 @@ use style::viewport::ViewportConstraints;
use url::Url;
use util::cursor::Cursor;
use util::geometry::PagePx;
use util::opts;
use util::task::spawn_named;
use util::{opts, prefs};
/// Maintains the pipelines and navigation context and grants permission to composite.
///
@ -891,7 +891,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
containing_pipeline_id: PipelineId,
subpage_id: SubpageId,
event: MozBrowserEvent) {
assert!(opts::experimental_enabled());
assert!(prefs::get_pref("dom.mozbrowser.enabled", false));
// Find the script channel for the given parent pipeline,
// and pass the event to that script task.
@ -1373,7 +1373,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserlocationchange
fn trigger_mozbrowserlocationchange(&self, pipeline_id: PipelineId) {
if opts::experimental_enabled() {
if prefs::get_pref("dom.mozbrowser.enabled", false) {
// Work around borrow checker
let event_info = {
let pipeline = self.pipeline(pipeline_id);

View file

@ -7,6 +7,7 @@ use windowing::WindowEvent;
use euclid::scale_factor::ScaleFactor;
use euclid::size::Size2D;
use msg::constellation_msg::AnimationState;
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{ConstellationChan, WindowSizeData};
use profile_traits::mem;
@ -88,6 +89,18 @@ impl CompositorEventListener for NullCompositor {
response_chan.send(()).unwrap();
}
Msg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
match animation_state {
AnimationState::AnimationsPresent |
AnimationState::NoAnimationsPresent |
AnimationState::NoAnimationCallbacksPresent => {}
AnimationState::AnimationCallbacksPresent => {
let msg = ConstellationMsg::TickAnimation(pipeline_id);
self.constellation_chan.0.send(msg).unwrap()
}
}
}
// Explicitly list ignored messages so that when we add a new one,
// we'll notice and think about whether it needs a response, like
// SetFrameTree.
@ -95,7 +108,6 @@ impl CompositorEventListener for NullCompositor {
Msg::InitializeLayersForPipeline(..) |
Msg::SetLayerRect(..) |
Msg::AssignPaintedBuffers(..) |
Msg::ChangeRunningAnimationsState(..) |
Msg::ScrollFragmentPoint(..) |
Msg::Status(..) |
Msg::LoadStart(..) |

View file

@ -31,7 +31,7 @@ use url::Url;
use util;
use util::geometry::{PagePx, ViewportPx};
use util::ipc::OptionalIpcSender;
use util::opts;
use util::prefs;
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
pub struct Pipeline {
@ -269,7 +269,7 @@ impl Pipeline {
pub fn trigger_mozbrowser_event(&self,
subpage_id: SubpageId,
event: MozBrowserEvent) {
assert!(opts::experimental_enabled());
assert!(prefs::get_pref("dom.mozbrowser.enabled", false));
let event = ConstellationControlMsg::MozBrowserEvent(self.id,
subpage_id,

View file

@ -6,13 +6,11 @@
use devtools_traits::PreciseTime;
use rustc_serialize::json;
use std::any::{Any, TypeId};
use std::any::Any;
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::marker::Reflect;
use std::mem::{replace, transmute};
use std::mem::replace;
use std::net::TcpStream;
use std::raw::TraitObject;
use std::sync::{Arc, Mutex};
#[derive(PartialEq)]
@ -24,7 +22,7 @@ pub enum ActorMessageStatus {
/// A common trait for all devtools actors that encompasses an immutable name
/// and the ability to process messages that are directed to particular actors.
/// TODO: ensure the name is immutable
pub trait Actor: Any {
pub trait Actor: Any + ActorAsAny {
fn handle_message(&self,
registry: &ActorRegistry,
msg_type: &str,
@ -33,55 +31,14 @@ pub trait Actor: Any {
fn name(&self) -> String;
}
impl Actor + Send {
/// Returns true if the boxed type is the same as `T`
#[inline]
pub fn is<T: Reflect + 'static>(&self) -> bool {
// Get TypeId of the type this function is instantiated with
let t = TypeId::of::<T>();
// Get TypeId of the type in the trait object
let boxed = self.get_type_id();
// Compare both TypeIds on equality
t == boxed
trait ActorAsAny {
fn actor_as_any(&self) -> &Any;
fn actor_as_any_mut(&mut self) -> &mut Any;
}
/// Returns some reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[inline]
#[allow(unsafe_code)]
pub fn downcast_ref<T: Reflect + 'static>(&self) -> Option<&T> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
let to: TraitObject = transmute(self);
// Extract the data pointer
Some(transmute(to.data))
}
} else {
None
}
}
/// Returns some mutable reference to the boxed value if it is of type `T`, or
/// `None` if it isn't.
#[inline]
#[allow(unsafe_code)]
pub fn downcast_mut<T: Reflect + 'static>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
let to: TraitObject = transmute(self);
// Extract the data pointer
Some(transmute(to.data))
}
} else {
None
}
}
impl<T: Actor> ActorAsAny for T {
fn actor_as_any(&self) -> &Any { self }
fn actor_as_any_mut(&mut self) -> &mut Any { self }
}
/// A list of known, owned actors.
@ -179,15 +136,15 @@ impl ActorRegistry {
}
/// Find an actor by registered name
pub fn find<'a, T: Reflect + 'static>(&'a self, name: &str) -> &'a T {
pub fn find<'a, T: Any>(&'a self, name: &str) -> &'a T {
let actor = self.actors.get(&name.to_string()).unwrap();
actor.downcast_ref::<T>().unwrap()
actor.actor_as_any().downcast_ref::<T>().unwrap()
}
/// Find an actor by registered name
pub fn find_mut<'a, T: Reflect + 'static>(&'a mut self, name: &str) -> &'a mut T {
pub fn find_mut<'a, T: Any>(&'a mut self, name: &str) -> &'a mut T {
let actor = self.actors.get_mut(&name.to_string()).unwrap();
actor.downcast_mut::<T>().unwrap()
actor.actor_as_any_mut().downcast_mut::<T>().unwrap()
}
/// Attempt to process a message as directed by its `to` property. If the actor is not

View file

@ -17,9 +17,9 @@ use devtools_traits::EvaluateJSReply::{StringValue, BooleanValue, ActorValue};
use devtools_traits::{CachedConsoleMessageTypes, DevtoolScriptControlMsg, PAGE_ERROR, CONSOLE_API};
use msg::constellation_msg::PipelineId;
use core::cell::RefCell;
use ipc_channel::ipc::{self, IpcSender};
use rustc_serialize::json::{self, Json, ToJson};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::net::TcpStream;
use std::sync::mpsc::channel;

View file

@ -6,7 +6,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use msg::constellation_msg::PipelineId;
use rustc_serialize::{json, Encoder, Encodable};
use std::cell::RefCell;
use std::collections::{HashMap, VecDeque};
use std::net::TcpStream;
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};
@ -17,7 +16,7 @@ use actors::framerate::FramerateActor;
use actors::memory::{MemoryActor, TimelineMemoryReply};
use devtools_traits::DevtoolScriptControlMsg;
use devtools_traits::DevtoolScriptControlMsg::{SetTimelineMarkers, DropTimelineMarkers};
use devtools_traits::{PreciseTime, TimelineMarker, TracingMetadata, TimelineMarkerType};
use devtools_traits::{PreciseTime, TimelineMarker, TimelineMarkerType};
use protocol::JsonPacketStream;
use util::task;
@ -148,72 +147,15 @@ impl TimelineActor {
return;
}
/// Select root(with depth 0) TimelineMarker pair (IntervalStart + IntervalEnd)
/// from queue and add marker to emitter
/// Return true if closed (IntervalStart + IntervalEnd) pair was founded
fn group(queue: &mut VecDeque<TimelineMarker>, depth: usize,
start_payload: Option<TimelineMarker>, emitter: &Emitter,
markers: &mut Vec<TimelineMarkerReply>) -> bool {
if let Some(start_payload) = start_payload {
if start_payload.metadata != TracingMetadata::IntervalStart {
panic!("Start payload doesn't have metadata IntervalStart");
}
if let Some(end_payload) = queue.pop_front() {
match end_payload.metadata {
TracingMetadata::IntervalEnd => {
if depth == 0 {
// Emit TimelineMarkerReply, pair was found
markers.push(emitter.marker(start_payload, end_payload));
}
return true;
}
TracingMetadata::IntervalStart => {
if group(queue, depth + 1, Some(end_payload), emitter, markers) {
return group(queue, depth, Some(start_payload), emitter, markers);
} else {
queue.push_front(start_payload);
}
}
_ => panic!("Unknown tracingMetadata")
}
} else {
queue.push_front(start_payload);
}
}
false
}
task::spawn_named("PullTimelineMarkers".to_string(), move || {
let mut queues = HashMap::new();
queues.insert("Reflow".to_string(), VecDeque::new());
queues.insert("DOMEvent".to_string(), VecDeque::new());
loop {
if !*is_recording.lock().unwrap() {
break;
}
// Creating queues by marker.name
loop {
match receiver.try_recv() {
Ok(marker) => {
if let Some(list) = queues.get_mut(&marker.name) {
list.push_back(marker);
}
}
Err(_) => break
}
}
// Emit all markers
let mut markers = vec![];
for (_, queue) in &mut queues {
let start_payload = queue.pop_front();
group(queue, 0, start_payload, &emitter, &mut markers);
while let Ok(marker) = receiver.try_recv() {
markers.push(emitter.marker(marker));
}
emitter.send(markers);
@ -336,14 +278,13 @@ impl Emitter {
}
}
fn marker(&self, start_payload: TimelineMarker, end_payload: TimelineMarker)
-> TimelineMarkerReply {
fn marker(&self, payload: TimelineMarker) -> TimelineMarkerReply {
TimelineMarkerReply {
name: start_payload.name,
start: HighResolutionStamp::new(self.start_stamp, start_payload.time),
end: HighResolutionStamp::new(self.start_stamp, end_payload.time),
stack: start_payload.stack,
endStack: end_payload.stack,
name: payload.name,
start: HighResolutionStamp::new(self.start_stamp, payload.start_time),
end: HighResolutionStamp::new(self.start_stamp, payload.end_time),
stack: payload.start_stack,
endStack: payload.end_stack,
}
}

View file

@ -11,12 +11,8 @@
#![crate_type = "rlib"]
#![feature(box_syntax)]
#![feature(core)]
#![feature(custom_derive)]
#![feature(get_type_id)]
#![feature(plugin)]
#![feature(raw)]
#![feature(reflect_marker)]
#![plugin(serde_macros)]
#![allow(non_snake_case)]
@ -25,7 +21,6 @@
#[macro_use]
extern crate log;
extern crate core;
extern crate devtools_traits;
extern crate rustc_serialize;
extern crate ipc_channel;

View file

@ -124,21 +124,19 @@ pub struct NodeInfo {
pub incompleteValue: bool,
}
#[derive(PartialEq, Eq, Deserialize, Serialize)]
pub enum TracingMetadata {
Default,
IntervalStart,
IntervalEnd,
Event,
EventBacktrace,
pub struct StartedTimelineMarker {
name: String,
start_time: PreciseTime,
start_stack: Option<Vec<()>>,
}
#[derive(Deserialize, Serialize)]
pub struct TimelineMarker {
pub name: String,
pub metadata: TracingMetadata,
pub time: PreciseTime,
pub stack: Option<Vec<()>>,
pub start_time: PreciseTime,
pub start_stack: Option<Vec<()>>,
pub end_time: PreciseTime,
pub end_stack: Option<Vec<()>>,
}
#[derive(PartialEq, Eq, Hash, Clone, Deserialize, Serialize)]
@ -270,12 +268,23 @@ pub enum NetworkEvent {
}
impl TimelineMarker {
pub fn new(name: String, metadata: TracingMetadata) -> TimelineMarker {
TimelineMarker {
pub fn start(name: String) -> StartedTimelineMarker {
StartedTimelineMarker {
name: name,
metadata: metadata,
time: PreciseTime::now(),
stack: None,
start_time: PreciseTime::now(),
start_stack: None,
}
}
}
impl StartedTimelineMarker {
pub fn end(self) -> TimelineMarker {
TimelineMarker {
name: self.name,
start_time: self.start_time,
start_stack: self.start_stack,
end_time: PreciseTime::now(),
end_stack: None,
}
}
}

View file

@ -72,6 +72,19 @@ enum DashSize {
DashedBorder = 3
}
#[derive(Copy, Clone, Debug)]
struct Ellipse {
origin: Point2D<f32>,
width: f32,
height: f32,
}
#[derive(Copy, Clone, Debug)]
struct Line {
start: Point2D<f32>,
end: Point2D<f32>,
}
impl<'a> PaintContext<'a> {
pub fn draw_target(&self) -> &DrawTarget {
&self.draw_target
@ -355,6 +368,104 @@ impl<'a> PaintContext<'a> {
self.draw_target.push_clip(&path_builder.finish());
}
fn solve_quadratic(a: f32, b: f32, c: f32) -> (Option<f32>, Option<f32>) {
let discriminant = b * b - 4. * a * c;
if discriminant < 0. {
return (None, None);
}
let x1 = (-b + discriminant.sqrt())/(2. * a);
let x2 = (-b - discriminant.sqrt())/(2. * a);
if discriminant == 0. {
return (Some(x1), None);
}
return (Some(x1), Some(x2));
}
fn intersect_ellipse_line(e: Ellipse, l: Line) -> (Option<Point2D<f32>>, Option<Point2D<f32>>) {
debug_assert!(l.end.x - l.start.x > f32::EPSILON, "Error line segment end.x > start.x!!");
// shift the origin to center of the ellipse.
let line = Line { start: l.start - e.origin,
end: l.end - e.origin };
let a = (line.end.y - line.start.y)/(line.end.x - line.start.x);
let b = line.start.y - (a * line.start.x);
// given the equation of a line,
// y = a * x + b,
// and the equation of an ellipse,
// x^2/w^2 + y^2/h^2 = 1,
// substitute y = a * x + b, giving
// x^2/w^2 + (a^2x^2 + 2abx + b^2)/h^2 = 1
// then simplify to
// (h^2 + w^2a^2)x^2 + 2abw^2x + (b^2w^2 - w^2h^2) = 0
// finally solve for w using the quadratic equation.
let w = e.width;
let h = e.height;
let quad_a = h * h + w * w * a * a;
let quad_b = 2. * a * b * w * w;
let quad_c = b * b * w * w - w * w * h * h;
let intersections = PaintContext::solve_quadratic(quad_a, quad_b, quad_c);
match intersections {
(Some(x0), Some(x1)) => {
let mut p0 = Point2D::new(x0, a * x0 + b) + e.origin;
let mut p1 = Point2D::new(x1, a * x1 + b) + e.origin;
if x0 > x1 {
mem::swap(&mut p0, &mut p1);
}
(Some(p0), Some(p1))
},
(Some(x0), None) => {
let p = Point2D::new(x0, a * x0 + b) + e.origin;
(Some(p), None)
},
(None, Some(x1)) => {
let p = Point2D::new(x1, a * x1 + b) + e.origin;
(Some(p), None)
},
(None, None) => (None, None),
}
}
// Given an ellipse and line segment, the line segment may intersect the
// ellipse at 0, 1, or 2 points. We compute those intersection points.
// For each intersection point the angle of the point on the ellipse relative to
// the top|bottom of the ellipse is computed.
// Examples:
// - intersection at ellipse.center + (0, ellipse.height), the angle is 0 rad.
// - intersection at ellipse.center + (0, -ellipse.height), the angle is 0 rad.
// - intersection at ellipse.center + (+-ellipse.width, 0), the angle is pi/2.
fn ellipse_line_intersection_angles(e: Ellipse, l: Line)
-> (Option<(Point2D<f32>, f32)>, Option<(Point2D<f32>, f32)>) {
fn point_angle(e: Ellipse, intersect_point: Point2D<f32>) -> f32 {
((intersect_point.y - e.origin.y).abs() / e.height).asin()
}
let intersection = PaintContext::intersect_ellipse_line(e, l);
match intersection {
(Some(p0), Some(p1)) => (Some((p0, point_angle(e, p0))), Some((p1, point_angle(e, p1)))),
(Some(p0), None) => (Some((p0, point_angle(e, p0))), None),
(None, Some(p1)) => (None, Some((p1, point_angle(e, p1)))),
(None, None) => (None, None),
}
}
fn ellipse_rightmost_line_intersection_angle(e: Ellipse, l: Line) -> Option<f32> {
match PaintContext::ellipse_line_intersection_angles(e, l) {
(Some((p0, angle0)), Some((p1, _))) if p0.x > p1.x => Some(angle0),
(_, Some((_, angle1))) => Some(angle1),
(Some((_, angle0)), None) => Some(angle0),
(None, None) => None,
}
}
fn ellipse_leftmost_line_intersection_angle(e: Ellipse, l: Line) -> Option<f32> {
match PaintContext::ellipse_line_intersection_angles(e, l) {
(Some((p0, angle0)), Some((p1, _))) if p0.x < p1.x => Some(angle0),
(_, Some((_, angle1))) => Some(angle1),
(Some((_, angle0)), None) => Some(angle0),
(None, None) => None,
}
}
// The following comment is wonderful, and stolen from
// gecko:gfx/thebes/gfxContext.cpp:RoundedRectangle for reference.
//
@ -450,6 +561,11 @@ impl<'a> PaintContext<'a> {
let box_BL = box_TL + Point2D::new(0.0, bounds.size.height);
let box_BR = box_TL + Point2D::new(bounds.size.width, bounds.size.height);
let inner_TL = box_TL + Point2D::new(border.left, border.top);
let inner_TR = box_TR + Point2D::new(-border.right, border.top);
let inner_BR = box_BR + Point2D::new(-border.right, -border.bottom);
let inner_BL = box_BL + Point2D::new(border.left, -border.bottom);
let rad_R: AzFloat = 0.;
let rad_BR = rad_R + f32::consts::FRAC_PI_4;
let rad_B = rad_BR + f32::consts::FRAC_PI_4;
@ -457,7 +573,6 @@ impl<'a> PaintContext<'a> {
let rad_L = rad_BL + f32::consts::FRAC_PI_4;
let rad_TL = rad_L + f32::consts::FRAC_PI_4;
let rad_T = rad_TL + f32::consts::FRAC_PI_4;
let rad_TR = rad_T + f32::consts::FRAC_PI_4;
fn dx(x: AzFloat) -> Point2D<AzFloat> {
Point2D::new(x, 0.)
@ -475,12 +590,41 @@ impl<'a> PaintContext<'a> {
Point2D::new(0., if cond { dy } else { 0. })
}
fn compatible_borders_corner(border1_width: f32, border2_width: f32) -> bool {
(border1_width - border2_width).abs() <= f32::EPSILON
}
let distance_to_elbow_TL =
if border.top == border.left {
(radius.top_left - border.top).max(0.)
} else {
0.
};
let distance_to_elbow_TR =
if border.top == border.right {
(radius.top_right - border.top).max(0.)
} else {
0.
};
let distance_to_elbow_BR =
if border.right == border.bottom {
(radius.bottom_right - border.bottom).max(0.)
} else {
0.
};
let distance_to_elbow_BL =
if border.left == border.bottom {
(radius.bottom_left - border.bottom).max(0.)
} else {
0.
};
match direction {
Direction::Top => {
let edge_TL = box_TL + dx(radius.top_left.max(border.left));
let edge_TR = box_TR + dx(-radius.top_right.max(border.right));
let edge_BR = edge_TR + dy(border.top);
let edge_BL = edge_TL + dy(border.top);
let edge_BR = box_TR + dx(-border.right - distance_to_elbow_TR) + dy(border.top);
let edge_BL = box_TL + dx(border.left + distance_to_elbow_TL) + dy(border.top);
let corner_TL = edge_TL + dx_if(radius.top_left == 0., -border.left);
let corner_TR = edge_TR + dx_if(radius.top_right == 0., border.right);
@ -497,11 +641,18 @@ impl<'a> PaintContext<'a> {
// the origin is the center of the arcs we're about to draw.
let origin = edge_TR + Point2D::new((border.right - radius.top_right).max(0.),
radius.top_right);
// the elbow is the inside of the border's curve.
let distance_to_elbow = (radius.top_right - border.top).max(0.);
let angle = if compatible_borders_corner(border.top, border.right) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: inner_TR, end: box_TR };
let ellipse = Ellipse { origin: origin, width: radius.top_right, height: radius.top_right };
PaintContext::ellipse_rightmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, radius.top_right, rad_T, rad_TR, false);
path_builder.arc(origin, distance_to_elbow, rad_TR, rad_T, true);
path_builder.arc(origin, radius.top_right, rad_T, rad_R - angle, false);
if distance_to_elbow_TR != 0. {
path_builder.arc(origin, distance_to_elbow_TR, rad_R - angle, rad_T, true);
}
}
match mode {
@ -515,17 +666,25 @@ impl<'a> PaintContext<'a> {
if radius.top_left != 0. {
let origin = edge_TL + Point2D::new(-(border.left - radius.top_left).max(0.),
radius.top_left);
let distance_to_elbow = (radius.top_left - border.top).max(0.);
let angle = if compatible_borders_corner(border.top, border.left) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: box_TL, end: inner_TL };
let ellipse = Ellipse { origin: origin, width: radius.top_left, height: radius.top_left };
PaintContext::ellipse_leftmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, distance_to_elbow, rad_T, rad_TL, true);
path_builder.arc(origin, radius.top_left, rad_TL, rad_T, false);
if distance_to_elbow_TL != 0. {
path_builder.arc(origin, distance_to_elbow_TL, rad_T, rad_L + angle, true);
}
path_builder.arc(origin, radius.top_left, rad_L + angle, rad_T, false);
}
}
Direction::Left => {
let edge_TL = box_TL + dy(radius.top_left.max(border.top));
let edge_BL = box_BL + dy(-radius.bottom_left.max(border.bottom));
let edge_TR = edge_TL + dx(border.left);
let edge_BR = edge_BL + dx(border.left);
let edge_TR = box_TL + dx(border.left) + dy(border.top + distance_to_elbow_TL);
let edge_BR = box_BL + dx(border.left) + dy(-border.bottom - distance_to_elbow_BL);
let corner_TL = edge_TL + dy_if(radius.top_left == 0., -border.top);
let corner_BL = edge_BL + dy_if(radius.bottom_left == 0., border.bottom);
@ -541,10 +700,19 @@ impl<'a> PaintContext<'a> {
if radius.top_left != 0. {
let origin = edge_TL + Point2D::new(radius.top_left,
-(border.top - radius.top_left).max(0.));
let distance_to_elbow = (radius.top_left - border.left).max(0.);
path_builder.arc(origin, radius.top_left, rad_L, rad_TL, false);
path_builder.arc(origin, distance_to_elbow, rad_TL, rad_L, true);
let angle = if compatible_borders_corner(border.top, border.left) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: box_TL, end: inner_TL };
let ellipse = Ellipse { origin: origin, width: radius.top_left, height: radius.top_left };
PaintContext::ellipse_leftmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, radius.top_left, rad_L, rad_L + angle, false);
if distance_to_elbow_TL != 0. {
path_builder.arc(origin, distance_to_elbow_TL, rad_L + angle, rad_L, true);
}
}
match mode {
@ -559,17 +727,27 @@ impl<'a> PaintContext<'a> {
let origin = edge_BL +
Point2D::new(radius.bottom_left,
(border.bottom - radius.bottom_left).max(0.));
let distance_to_elbow = (radius.bottom_left - border.left).max(0.);
let angle = if compatible_borders_corner(border.bottom, border.left) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: box_BL, end: inner_BL };
let ellipse = Ellipse { origin: origin,
width: radius.bottom_left,
height: radius.bottom_left };
PaintContext::ellipse_leftmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, distance_to_elbow, rad_L, rad_BL, true);
path_builder.arc(origin, radius.bottom_left, rad_BL, rad_L, false);
if distance_to_elbow_BL != 0. {
path_builder.arc(origin, distance_to_elbow_BL, rad_L, rad_L - angle, true);
}
path_builder.arc(origin, radius.bottom_left, rad_L - angle, rad_L, false);
}
}
Direction::Right => {
let edge_TR = box_TR + dy(radius.top_right.max(border.top));
let edge_BR = box_BR + dy(-radius.bottom_right.max(border.bottom));
let edge_TL = edge_TR + dx(-border.right);
let edge_BL = edge_BR + dx(-border.right);
let edge_TL = box_TR + dx(-border.right) + dy(border.top + distance_to_elbow_TR);
let edge_BL = box_BR + dx(-border.right) + dy(-border.bottom - distance_to_elbow_BR);
let corner_TR = edge_TR + dy_if(radius.top_right == 0., -border.top);
let corner_BR = edge_BR + dy_if(radius.bottom_right == 0., border.bottom);
@ -585,10 +763,18 @@ impl<'a> PaintContext<'a> {
if radius.top_right != 0. {
let origin = edge_TR + Point2D::new(-radius.top_right,
-(border.top - radius.top_right).max(0.));
let distance_to_elbow = (radius.top_right - border.right).max(0.);
let angle = if compatible_borders_corner(border.top, border.right) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: inner_TR, end: box_TR };
let ellipse = Ellipse { origin: origin, width: radius.top_right, height: radius.top_right };
PaintContext::ellipse_rightmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, distance_to_elbow, rad_R, rad_TR, true);
path_builder.arc(origin, radius.top_right, rad_TR, rad_R, false);
if distance_to_elbow_TR != 0. {
path_builder.arc(origin, distance_to_elbow_TR, rad_R, rad_R - angle, true);
}
path_builder.arc(origin, radius.top_right, rad_R - angle, rad_R, false);
}
match mode {
@ -603,17 +789,27 @@ impl<'a> PaintContext<'a> {
let origin = edge_BR +
Point2D::new(-radius.bottom_right,
(border.bottom - radius.bottom_right).max(0.));
let distance_to_elbow = (radius.bottom_right - border.right).max(0.);
let angle = if compatible_borders_corner(border.bottom, border.right) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: inner_BR, end: box_BR };
let ellipse = Ellipse { origin: origin,
width: radius.bottom_right,
height: radius.bottom_right };
PaintContext::ellipse_rightmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, radius.bottom_right, rad_R, rad_BR, false);
path_builder.arc(origin, distance_to_elbow, rad_BR, rad_R, true);
path_builder.arc(origin, radius.bottom_right, rad_R, rad_R + angle, false);
if distance_to_elbow_BR != 0. {
path_builder.arc(origin, distance_to_elbow_BR, rad_R + angle, rad_R, true);
}
}
}
Direction::Bottom => {
let edge_BL = box_BL + dx(radius.bottom_left.max(border.left));
let edge_BR = box_BR + dx(-radius.bottom_right.max(border.right));
let edge_TL = edge_BL + dy(-border.bottom);
let edge_TR = edge_BR + dy(-border.bottom);
let edge_TL = box_BL + dy(-border.bottom) + dx(border.left + distance_to_elbow_BL);
let edge_TR = box_BR + dy(-border.bottom) + dx(-border.right - distance_to_elbow_BR);
let corner_BR = edge_BR + dx_if(radius.bottom_right == 0., border.right);
let corner_BL = edge_BL + dx_if(radius.bottom_left == 0., -border.left);
@ -629,10 +825,20 @@ impl<'a> PaintContext<'a> {
if radius.bottom_right != 0. {
let origin = edge_BR + Point2D::new((border.right - radius.bottom_right).max(0.),
-radius.bottom_right);
let distance_to_elbow = (radius.bottom_right - border.bottom).max(0.);
let angle = if compatible_borders_corner(border.bottom, border.right) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: inner_BR, end: box_BR };
let ellipse = Ellipse { origin: origin,
width: radius.bottom_right,
height: radius.bottom_right };
PaintContext::ellipse_rightmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, distance_to_elbow, rad_B, rad_BR, true);
path_builder.arc(origin, radius.bottom_right, rad_BR, rad_B, false);
if distance_to_elbow_BR != 0. {
path_builder.arc(origin, distance_to_elbow_BR, rad_B, rad_R + angle, true);
}
path_builder.arc(origin, radius.bottom_right, rad_R + angle, rad_B, false);
}
match mode {
@ -646,10 +852,20 @@ impl<'a> PaintContext<'a> {
if radius.bottom_left != 0. {
let origin = edge_BL - Point2D::new((border.left - radius.bottom_left).max(0.),
radius.bottom_left);
let distance_to_elbow = (radius.bottom_left - border.bottom).max(0.);
let angle = if compatible_borders_corner(border.bottom, border.left) {
f32::consts::FRAC_PI_4
} else {
let line = Line { start: box_BL, end: inner_BL };
let ellipse = Ellipse { origin: origin,
width: radius.bottom_left,
height: radius.bottom_left };
PaintContext::ellipse_leftmost_line_intersection_angle(ellipse, line).unwrap()
};
path_builder.arc(origin, radius.bottom_left, rad_B, rad_BL, false);
path_builder.arc(origin, distance_to_elbow, rad_BL, rad_B, true);
path_builder.arc(origin, radius.bottom_left, rad_B, rad_L - angle, false);
if distance_to_elbow_BL != 0. {
path_builder.arc(origin, distance_to_elbow_BL, rad_L - angle, rad_B, true);
}
}
}
}

View file

@ -33,11 +33,6 @@ pub struct FontTable {
data: CFData,
}
// Noncopyable.
impl Drop for FontTable {
fn drop(&mut self) {}
}
impl FontTable {
pub fn wrap(data: CFData) -> FontTable {
FontTable { data: data }

View file

@ -58,17 +58,7 @@ impl GlyphEntry {
starts_ligature,
glyph_count);
let mut val = FLAG_NOT_MISSING;
if !starts_cluster {
val |= FLAG_NOT_CLUSTER_START;
}
if !starts_ligature {
val |= FLAG_NOT_LIGATURE_GROUP_START;
}
val |= (glyph_count as u32) << GLYPH_COUNT_SHIFT;
GlyphEntry::new(val)
GlyphEntry::new(glyph_count as u32)
}
/// Create a GlyphEntry for the case where glyphs couldn't be found for the specified
@ -76,55 +66,22 @@ impl GlyphEntry {
fn missing(glyph_count: usize) -> GlyphEntry {
assert!(glyph_count <= u16::MAX as usize);
GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT)
GlyphEntry::new(glyph_count as u32)
}
}
/// The id of a particular glyph within a font
pub type GlyphId = u32;
// TODO: unify with bit flags?
#[derive(PartialEq, Copy, Clone)]
pub enum BreakType {
None,
Normal,
Hyphen,
}
static BREAK_TYPE_NONE: u8 = 0x0;
static BREAK_TYPE_NORMAL: u8 = 0x1;
static BREAK_TYPE_HYPHEN: u8 = 0x2;
fn break_flag_to_enum(flag: u8) -> BreakType {
if (flag & BREAK_TYPE_NORMAL) != 0 {
BreakType::Normal
} else if (flag & BREAK_TYPE_HYPHEN) != 0 {
BreakType::Hyphen
} else {
BreakType::None
}
}
fn break_enum_to_flag(e: BreakType) -> u8 {
match e {
BreakType::None => BREAK_TYPE_NONE,
BreakType::Normal => BREAK_TYPE_NORMAL,
BreakType::Hyphen => BREAK_TYPE_HYPHEN,
}
}
// TODO: make this more type-safe.
static FLAG_CHAR_IS_SPACE: u32 = 0x10000000;
// These two bits store some BREAK_TYPE_* flags
static FLAG_CAN_BREAK_MASK: u32 = 0x60000000;
static FLAG_CAN_BREAK_SHIFT: u32 = 29;
static FLAG_IS_SIMPLE_GLYPH: u32 = 0x80000000;
const FLAG_CHAR_IS_SPACE: u32 = 0x40000000;
const FLAG_IS_SIMPLE_GLYPH: u32 = 0x80000000;
// glyph advance; in Au's.
static GLYPH_ADVANCE_MASK: u32 = 0x0FFF0000;
static GLYPH_ADVANCE_SHIFT: u32 = 16;
static GLYPH_ID_MASK: u32 = 0x0000FFFF;
const GLYPH_ADVANCE_MASK: u32 = 0x3FFF0000;
const GLYPH_ADVANCE_SHIFT: u32 = 16;
const GLYPH_ID_MASK: u32 = 0x0000FFFF;
// Non-simple glyphs (more than one glyph per char; missing glyph,
// newline, tab, large advance, or nonzero x/y offsets) may have one
@ -132,21 +89,8 @@ static GLYPH_ID_MASK: u32 = 0x0000FFFF;
// side array so that there is a 1:1 mapping of GlyphEntry to
// unicode char.
// The number of detailed glyphs for this char. If the char couldn't
// be mapped to a glyph (!FLAG_NOT_MISSING), then this actually holds
// the UTF8 code point instead.
static GLYPH_COUNT_MASK: u32 = 0x00FFFF00;
static GLYPH_COUNT_SHIFT: u32 = 8;
// N.B. following Gecko, these are all inverted so that a lot of
// missing chars can be memset with zeros in one fell swoop.
static FLAG_NOT_MISSING: u32 = 0x00000001;
static FLAG_NOT_CLUSTER_START: u32 = 0x00000002;
static FLAG_NOT_LIGATURE_GROUP_START: u32 = 0x00000004;
static FLAG_CHAR_IS_TAB: u32 = 0x00000008;
static FLAG_CHAR_IS_NEWLINE: u32 = 0x00000010;
//static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020;
//static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038;
// The number of detailed glyphs for this char.
const GLYPH_COUNT_MASK: u32 = 0x0000FFFF;
fn is_simple_glyph_id(id: GlyphId) -> bool {
((id as u32) & GLYPH_ID_MASK) == id
@ -164,7 +108,6 @@ type DetailedGlyphCount = u16;
// Getters and setters for GlyphEntry. Setter methods are functional,
// because GlyphEntry is immutable and only a u32 in size.
impl GlyphEntry {
// getter methods
#[inline(always)]
fn advance(&self) -> Au {
Au(((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT) as i32)
@ -174,62 +117,20 @@ impl GlyphEntry {
self.value & GLYPH_ID_MASK
}
fn is_ligature_start(&self) -> bool {
self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START)
}
fn is_cluster_start(&self) -> bool {
self.has_flag(!FLAG_NOT_CLUSTER_START)
}
// True if original char was normal (U+0020) space. Other chars may
// map to space glyph, but this does not account for them.
/// True if original char was normal (U+0020) space. Other chars may
/// map to space glyph, but this does not account for them.
fn char_is_space(&self) -> bool {
self.has_flag(FLAG_CHAR_IS_SPACE)
}
fn char_is_tab(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_TAB)
}
fn char_is_newline(&self) -> bool {
!self.is_simple() && self.has_flag(FLAG_CHAR_IS_NEWLINE)
}
fn can_break_before(&self) -> BreakType {
let flag = ((self.value & FLAG_CAN_BREAK_MASK) >> FLAG_CAN_BREAK_SHIFT) as u8;
break_flag_to_enum(flag)
}
// setter methods
#[inline(always)]
fn set_char_is_space(&self) -> GlyphEntry {
GlyphEntry::new(self.value | FLAG_CHAR_IS_SPACE)
}
#[inline(always)]
fn set_char_is_tab(&self) -> GlyphEntry {
assert!(!self.is_simple());
GlyphEntry::new(self.value | FLAG_CHAR_IS_TAB)
}
#[inline(always)]
fn set_char_is_newline(&self) -> GlyphEntry {
assert!(!self.is_simple());
GlyphEntry::new(self.value | FLAG_CHAR_IS_NEWLINE)
}
#[inline(always)]
fn set_can_break_before(&self, e: BreakType) -> GlyphEntry {
let flag = (break_enum_to_flag(e) as u32) << FLAG_CAN_BREAK_SHIFT;
GlyphEntry::new(self.value | flag)
}
// helper methods
fn glyph_count(&self) -> u16 {
assert!(!self.is_simple());
((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16
(self.value & GLYPH_COUNT_MASK) as u16
}
#[inline(always)]
@ -576,9 +477,6 @@ impl<'a> GlyphStore {
}
};
// FIXME(pcwalton): Is this necessary? I think it's a no-op.
entry = entry.adapt_character_flags_of_entry(self.entry_buffer[i.to_usize()]);
if character == Some(' ') {
entry = entry.set_char_is_space()
}
@ -647,62 +545,11 @@ impl<'a> GlyphStore {
.fold(Au(0), |advance, (_, glyph)| advance + glyph.advance())
}
// getter methods
pub fn char_is_space(&self, i: CharIndex) -> bool {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].char_is_space()
}
pub fn char_is_tab(&self, i: CharIndex) -> bool {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].char_is_tab()
}
pub fn char_is_newline(&self, i: CharIndex) -> bool {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].char_is_newline()
}
pub fn is_ligature_start(&self, i: CharIndex) -> bool {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].is_ligature_start()
}
pub fn is_cluster_start(&self, i: CharIndex) -> bool {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].is_cluster_start()
}
pub fn can_break_before(&self, i: CharIndex) -> BreakType {
assert!(i < self.char_len());
self.entry_buffer[i.to_usize()].can_break_before()
}
// setter methods
pub fn set_char_is_space(&mut self, i: CharIndex) {
assert!(i < self.char_len());
let entry = self.entry_buffer[i.to_usize()];
self.entry_buffer[i.to_usize()] = entry.set_char_is_space();
}
pub fn set_char_is_tab(&mut self, i: CharIndex) {
assert!(i < self.char_len());
let entry = self.entry_buffer[i.to_usize()];
self.entry_buffer[i.to_usize()] = entry.set_char_is_tab();
}
pub fn set_char_is_newline(&mut self, i: CharIndex) {
assert!(i < self.char_len());
let entry = self.entry_buffer[i.to_usize()];
self.entry_buffer[i.to_usize()] = entry.set_char_is_newline();
}
pub fn set_can_break_before(&mut self, i: CharIndex, t: BreakType) {
assert!(i < self.char_len());
let entry = self.entry_buffer[i.to_usize()];
self.entry_buffer[i.to_usize()] = entry.set_can_break_before(t);
}
pub fn space_count_in_range(&self, range: &Range<CharIndex>) -> u32 {
let mut spaces = 0;
for index in range.each_index() {

View file

@ -313,6 +313,10 @@ impl Flow for FlexFlow {
&mut self.block_flow
}
fn mark_as_root(&mut self) {
self.block_flow.mark_as_root();
}
fn bubble_inline_sizes(&mut self) {
let _scope = layout_debug_scope!("flex::bubble_inline_sizes {:x}",
self.block_flow.base.debug_id());

View file

@ -13,12 +13,12 @@
#![deny(unsafe_code)]
use block::{BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
use block::{BlockFlow, FloatNonReplaced, AbsoluteNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
use context::LayoutContext;
use floats::FloatKind;
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, OpaqueFlow};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator};
use model::MaybeAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
@ -242,6 +242,26 @@ impl TableWrapperFlow {
return
}
if !self.block_flow.base.flags.contains(INLINE_POSITION_IS_STATIC) {
let inline_size_computer = AbsoluteTable {
minimum_width_of_all_columns: minimum_width_of_all_columns,
preferred_width_of_all_columns: preferred_width_of_all_columns,
border_collapse: border_collapse,
};
let input =
inline_size_computer.compute_inline_size_constraint_inputs(&mut self.block_flow,
parent_flow_inline_size,
layout_context);
let solution = inline_size_computer.solve_inline_size_constraints(&mut self.block_flow,
&input);
inline_size_computer.set_inline_size_constraint_solutions(&mut self.block_flow,
solution);
inline_size_computer.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
solution);
return
}
let inline_size_computer = Table {
minimum_width_of_all_columns: minimum_width_of_all_columns,
preferred_width_of_all_columns: preferred_width_of_all_columns,
@ -791,3 +811,54 @@ impl ISizeAndMarginsComputer for FloatedTable {
FloatNonReplaced.solve_inline_size_constraints(block, input)
}
}
struct AbsoluteTable {
minimum_width_of_all_columns: Au,
preferred_width_of_all_columns: Au,
border_collapse: border_collapse::T,
}
impl ISizeAndMarginsComputer for AbsoluteTable {
fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
block.fragment.compute_border_and_padding(containing_block_inline_size,
self.border_collapse)
}
fn initial_computed_inline_size(&self,
block: &mut BlockFlow,
parent_flow_inline_size: Au,
layout_context: &LayoutContext)
-> MaybeAuto {
let containing_block_inline_size =
self.containing_block_inline_size(block,
parent_flow_inline_size,
layout_context);
initial_computed_inline_size(block,
containing_block_inline_size,
self.minimum_width_of_all_columns,
self.preferred_width_of_all_columns)
}
fn containing_block_inline_size(&self,
block: &mut BlockFlow,
parent_flow_inline_size: Au,
layout_context: &LayoutContext)
-> Au {
AbsoluteNonReplaced.containing_block_inline_size(block, parent_flow_inline_size, layout_context)
}
fn solve_inline_size_constraints(&self,
block: &mut BlockFlow,
input: &ISizeConstraintInput)
-> ISizeConstraintSolution {
AbsoluteNonReplaced.solve_inline_size_constraints(block, input)
}
fn set_inline_position_of_flow_if_necessary(&self,
block: &mut BlockFlow,
solution: ISizeConstraintSolution) {
AbsoluteNonReplaced.set_inline_position_of_flow_if_necessary(block, solution);
}
}

View file

@ -2,49 +2,47 @@
* 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/. */
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
use hsts::{HSTSList, secure_url};
use file_loader;
use flate2::read::{DeflateDecoder, GzDecoder};
use hsts::secure_url;
use hyper::Error as HttpError;
use hyper::client::{Request, Response};
use hyper::header::{AcceptEncoding, Accept, ContentLength, ContentType, Host};
use hyper::header::{Location, qitem, StrictTransportSecurity};
use hyper::header::{Quality, QualityItem, Headers, ContentEncoding, Encoding};
use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::net::{Fresh, HttpsConnector, Openssl};
use hyper::status::{StatusCode, StatusClass};
use ipc_channel::ipc::{self, IpcSender};
use log;
use mime_classifier::MIMEClassifier;
use net_traits::ProgressMsg::{Payload, Done};
use net_traits::hosts::replace_hosts;
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer, IncludeSubdomains};
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
use file_loader;
use flate2::read::{DeflateDecoder, GzDecoder};
use hyper::Error as HttpError;
use hyper::client::Request;
use hyper::header::StrictTransportSecurity;
use hyper::header::{AcceptEncoding, Accept, ContentLength, ContentType, Host, Location, qitem, Quality, QualityItem};
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::net::{HttpConnector, HttpsConnector, Openssl};
use hyper::status::{StatusCode, StatusClass};
use ipc_channel::ipc::{self, IpcSender};
use log;
use openssl::ssl::{SslContext, SslMethod, SSL_VERIFY_PEER};
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::collections::HashSet;
use std::error::Error;
use std::io::{self, Read, Write};
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::mpsc::{Sender, channel};
use url::{Url, UrlParser};
use util::opts;
use util::resource_files::resources_dir_path;
use util::task::spawn_named;
use std::borrow::ToOwned;
use std::boxed::FnBox;
use uuid;
pub fn factory(resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>)
devtools_chan: Option<Sender<DevtoolsControlMsg>>)
-> Box<FnBox(LoadData, LoadConsumer, Arc<MIMEClassifier>) + Send> {
box move |load_data, senders, classifier| {
spawn_named("http_loader".to_owned(),
move || load(load_data, senders, classifier, resource_mgr_chan, devtools_chan, hsts_list))
box move |load_data: LoadData, senders, classifier| {
spawn_named(format!("http_loader for {}", load_data.url.serialize()),
move || load_for_consumer(load_data, senders, classifier, resource_mgr_chan, devtools_chan))
}
}
@ -76,239 +74,260 @@ fn read_block<R: Read>(reader: &mut R) -> Result<ReadResult, ()> {
}
}
fn request_must_be_secured(hsts_list: &HSTSList, url: &Url) -> bool {
match url.domain() {
Some(ref h) => {
hsts_list.is_host_secure(h)
},
_ => false
}
fn inner_url(url: &Url) -> Url {
let inner_url = url.non_relative_scheme_data().unwrap();
Url::parse(inner_url).unwrap()
}
fn load(mut load_data: LoadData,
fn load_for_consumer(load_data: LoadData,
start_chan: LoadConsumer,
classifier: Arc<MIMEClassifier>,
resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>) {
// FIXME: At the time of writing this FIXME, servo didn't have any central
// location for configuration. If you're reading this and such a
// repository DOES exist, please update this constant to use it.
let max_redirects = 50;
let mut iters = 0;
// URL of the document being loaded, as seen by all the higher-level code.
let mut doc_url = load_data.url.clone();
// URL that we actually fetch from the network, after applying the replacements
// specified in the hosts file.
let mut url = replace_hosts(&load_data.url);
let mut redirected_to = HashSet::new();
devtools_chan: Option<Sender<DevtoolsControlMsg>>) {
// If the URL is a view-source scheme then the scheme data contains the
// real URL that should be used for which the source is to be viewed.
// Change our existing URL to that and keep note that we are viewing
// the source rather than rendering the contents of the URL.
let viewing_source = url.scheme == "view-source";
if viewing_source {
let inner_url = load_data.url.non_relative_scheme_data().unwrap();
doc_url = Url::parse(inner_url).unwrap();
url = replace_hosts(&doc_url);
match &*url.scheme {
"http" | "https" => {}
_ => {
let s = format!("The {} scheme with view-source is not supported", url.scheme);
send_error(url, s, start_chan);
return;
match load::<WrappedHttpRequest>(load_data, resource_mgr_chan, devtools_chan, &NetworkHttpRequestFactory) {
Err(LoadError::UnsupportedScheme(url)) => {
let s = format!("{} request, but we don't support that scheme", &*url.scheme);
send_error(url, s, start_chan)
}
};
Err(LoadError::Connection(url, e)) => {
send_error(url, e, start_chan)
}
// Loop to handle redirects.
loop {
iters = iters + 1;
if &*url.scheme != "https" && request_must_be_secured(&hsts_list.lock().unwrap(), &url) {
info!("{} is in the strict transport security list, requesting secure host", url);
url = secure_url(&url);
Err(LoadError::MaxRedirects(url)) => {
send_error(url, "too many redirects".to_string(), start_chan)
}
if iters > max_redirects {
send_error(url, "too many redirects".to_string(), start_chan);
return;
Err(LoadError::Cors(url, msg)) |
Err(LoadError::InvalidRedirect(url, msg)) |
Err(LoadError::Decoding(url, msg)) => {
send_error(url, msg, start_chan)
}
Err(LoadError::Ssl(url, msg)) => {
info!("ssl validation error {}, '{}'", url.serialize(), msg);
match &*url.scheme {
"http" | "https" => {}
_ => {
let s = format!("{} request, but we don't support that scheme", url.scheme);
send_error(url, s, start_chan);
return;
let mut image = resources_dir_path();
image.push("badcert.html");
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap(), None);
file_loader::factory(load_data, start_chan, classifier)
}
Ok(mut load_response) => {
let metadata = load_response.metadata.clone();
send_data(&mut load_response, start_chan, metadata, classifier)
}
}
}
info!("requesting {}", url.serialize());
pub trait HttpResponse: Read {
fn headers(&self) -> &Headers;
fn status(&self) -> StatusCode;
fn status_raw(&self) -> &RawStatus;
fn content_encoding(&self) -> Option<Encoding> {
self.headers().get::<ContentEncoding>().and_then(|h| {
match h {
&ContentEncoding(ref encodings) => {
if encodings.contains(&Encoding::Gzip) {
Some(Encoding::Gzip)
} else if encodings.contains(&Encoding::Deflate) {
Some(Encoding::Deflate)
} else {
// TODO: Is this the correct behaviour?
None
}
}
}
})
}
}
struct WrappedHttpResponse {
response: Response
}
impl Read for WrappedHttpResponse {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.response.read(buf)
}
}
impl HttpResponse for WrappedHttpResponse {
fn headers(&self) -> &Headers {
&self.response.headers
}
fn status(&self) -> StatusCode {
self.response.status
}
fn status_raw(&self) -> &RawStatus {
self.response.status_raw()
}
}
pub trait HttpRequestFactory {
type R: HttpRequest;
fn create(&self, url: Url, method: Method) -> Result<Self::R, LoadError>;
}
struct NetworkHttpRequestFactory;
impl HttpRequestFactory for NetworkHttpRequestFactory {
type R = WrappedHttpRequest;
fn create(&self, url: Url, method: Method) -> Result<WrappedHttpRequest, LoadError> {
let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
context.set_verify(SSL_VERIFY_PEER, None);
context.set_CA_file(&resources_dir_path().join("certs")).unwrap();
let connector = HttpsConnector::new(Openssl { context: Arc::new(context) });
let connection = Request::with_connector(method, url.clone(), &connector);
let ssl_err_string = "Some(OpenSslErrors([UnknownError { library: \"SSL routines\", \
function: \"SSL3_GET_SERVER_CERTIFICATE\", \
reason: \"certificate verify failed\" }]))";
let req = if opts::get().nossl {
Request::with_connector(load_data.method.clone(), url.clone(), &HttpConnector)
} else {
let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
context.set_verify(SSL_VERIFY_PEER, None);
context.set_CA_file(&resources_dir_path().join("certs")).unwrap();
Request::with_connector(load_data.method.clone(), url.clone(),
&HttpsConnector::new(Openssl { context: Arc::new(context) }))
};
let mut req = match req {
let request = match connection {
Ok(req) => req,
Err(HttpError::Io(ref io_error)) if (
io_error.kind() == io::ErrorKind::Other &&
io_error.description() == "Error in OpenSSL" &&
// FIXME: This incredibly hacky. Make it more robust, and at least test it.
format!("{:?}", io_error.cause()) == ssl_err_string
) => {
let mut image = resources_dir_path();
image.push("badcert.html");
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap(), None);
file_loader::factory(load_data, start_chan, classifier);
return;
return Err(
LoadError::Ssl(
url,
format!("ssl error {:?}: {:?} {:?}",
io_error.kind(),
io_error.description(),
io_error.cause())
)
)
},
Err(e) => {
println!("{:?}", e);
send_error(url, e.description().to_string(), start_chan);
return;
return Err(LoadError::Connection(url, e.description().to_string()))
}
};
//Ensure that the host header is set from the original url
let host = Host {
hostname: doc_url.serialize_host().unwrap(),
port: doc_url.port_or_default()
};
// Avoid automatically preserving request headers when redirects occur.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=401564 and
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828 .
// Only preserve ones which have been explicitly marked as such.
if iters == 1 {
let mut combined_headers = load_data.headers.clone();
combined_headers.extend(load_data.preserved_headers.iter());
*req.headers_mut() = combined_headers;
} else {
*req.headers_mut() = load_data.preserved_headers.clone();
Ok(WrappedHttpRequest { request: request })
}
}
req.headers_mut().set(host);
pub trait HttpRequest {
type R: HttpResponse + 'static;
if !req.headers().has::<Accept>() {
fn headers_mut(&mut self) -> &mut Headers;
fn send(self, body: &Option<Vec<u8>>) -> Result<Self::R, LoadError>;
}
struct WrappedHttpRequest {
request: Request<Fresh>
}
impl HttpRequest for WrappedHttpRequest {
type R = WrappedHttpResponse;
fn headers_mut(&mut self) -> &mut Headers {
self.request.headers_mut()
}
fn send(self, body: &Option<Vec<u8>>) -> Result<WrappedHttpResponse, LoadError> {
let url = self.request.url.clone();
let mut request_writer = match self.request.start() {
Ok(streaming) => streaming,
Err(e) => return Err(LoadError::Connection(url, e.description().to_string()))
};
if let Some(ref data) = *body {
match request_writer.write_all(&data) {
Err(e) => {
return Err(LoadError::Connection(url, e.description().to_string()))
}
_ => {}
}
}
let response = match request_writer.send() {
Ok(w) => w,
Err(e) => return Err(LoadError::Connection(url, e.description().to_string()))
};
Ok(WrappedHttpResponse { response: response })
}
}
#[derive(Debug)]
pub enum LoadError {
UnsupportedScheme(Url),
Connection(Url, String),
Cors(Url, String),
Ssl(Url, String),
InvalidRedirect(Url, String),
Decoding(Url, String),
MaxRedirects(Url)
}
fn set_default_accept_encoding(headers: &mut Headers) {
if headers.has::<AcceptEncoding>() {
return
}
headers.set_raw("Accept-Encoding".to_owned(), vec![b"gzip, deflate".to_vec()]);
}
fn set_default_accept(headers: &mut Headers) {
if !headers.has::<Accept>() {
let accept = Accept(vec![
qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])),
qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_string()), vec![])),
QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)),
QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)),
]);
req.headers_mut().set(accept);
headers.set(accept);
}
}
fn set_request_cookies(url: Url, headers: &mut Headers, resource_mgr_chan: &IpcSender<ControlMsg>) {
let (tx, rx) = ipc::channel().unwrap();
resource_mgr_chan.send(ControlMsg::GetCookiesForUrl(doc_url.clone(),
tx,
CookieSource::HTTP)).unwrap();
resource_mgr_chan.send(ControlMsg::GetCookiesForUrl(url, tx, CookieSource::HTTP)).unwrap();
if let Some(cookie_list) = rx.recv().unwrap() {
let mut v = Vec::new();
v.push(cookie_list.into_bytes());
req.headers_mut().set_raw("Cookie".to_owned(), v);
}
if !req.headers().has::<AcceptEncoding>() {
req.headers_mut().set_raw("Accept-Encoding".to_owned(), vec![b"gzip, deflate".to_vec()]);
}
if log_enabled!(log::LogLevel::Info) {
info!("{}", load_data.method);
for header in req.headers().iter() {
info!(" - {}", header);
}
info!("{:?}", load_data.data);
}
// Avoid automatically sending request body if a redirect has occurred.
let writer = match load_data.data {
Some(ref data) if iters == 1 => {
req.headers_mut().set(ContentLength(data.len() as u64));
let mut writer = match req.start() {
Ok(w) => w,
Err(e) => {
send_error(url, e.description().to_string(), start_chan);
return;
}
};
match writer.write_all(&*data) {
Err(e) => {
send_error(url, e.description().to_string(), start_chan);
return;
}
_ => {}
};
writer
},
_ => {
match load_data.method {
Method::Get | Method::Head => (),
_ => req.headers_mut().set(ContentLength(0))
}
match req.start() {
Ok(w) => w,
Err(e) => {
send_error(url, e.description().to_string(), start_chan);
return;
}
}
}
};
// Send an HttpRequest message to devtools with a unique request_id
// TODO: Do this only if load_data has some pipeline_id, and send the pipeline_id in the message
let request_id = uuid::Uuid::new_v4().to_simple_string();
if let Some(ref chan) = devtools_chan {
let net_event = NetworkEvent::HttpRequest(load_data.url.clone(),
load_data.method.clone(),
load_data.headers.clone(),
load_data.data.clone());
chan.send(DevtoolsControlMsg::FromChrome(
ChromeToDevtoolsControlMsg::NetworkEvent(request_id.clone(),
net_event))).unwrap();
}
let mut response = match writer.send() {
Ok(r) => r,
Err(e) => {
send_error(url, e.description().to_string(), start_chan);
return;
}
};
// Dump headers, but only do the iteration if info!() is enabled.
info!("got HTTP response {}, headers:", response.status);
if log_enabled!(log::LogLevel::Info) {
for header in response.headers.iter() {
info!(" - {}", header);
headers.set_raw("Cookie".to_owned(), v);
}
}
if let Some(cookies) = response.headers.get_raw("set-cookie") {
for cookie in cookies {
fn set_cookies_from_response(url: Url, response: &HttpResponse, resource_mgr_chan: &IpcSender<ControlMsg>) {
if let Some(cookies) = response.headers().get_raw("set-cookie") {
for cookie in cookies.iter() {
if let Ok(cookies) = String::from_utf8(cookie.clone()) {
resource_mgr_chan.send(ControlMsg::SetCookiesForUrl(doc_url.clone(),
resource_mgr_chan.send(ControlMsg::SetCookiesForUrl(url.clone(),
cookies,
CookieSource::HTTP)).unwrap();
}
}
}
}
if url.scheme == "https" {
if let Some(header) = response.headers.get::<StrictTransportSecurity>() {
fn request_must_be_secured(url: &Url, resource_mgr_chan: &IpcSender<ControlMsg>) -> bool {
let (tx, rx) = ipc::channel().unwrap();
resource_mgr_chan.send(
ControlMsg::GetHostMustBeSecured(url.domain().unwrap().to_string(), tx)
).unwrap();
rx.recv().unwrap()
}
fn update_sts_list_from_response(url: &Url, response: &HttpResponse, resource_mgr_chan: &IpcSender<ControlMsg>) {
if url.scheme != "https" {
return;
}
if let Some(header) = response.headers().get::<StrictTransportSecurity>() {
if let Some(host) = url.domain() {
info!("adding host {} to the strict transport security list", host);
info!("- max-age {}", header.max_age);
@ -320,28 +339,236 @@ reason: \"certificate verify failed\" }]))";
IncludeSubdomains::NotIncluded
};
resource_mgr_chan.send(
ControlMsg::SetHSTSEntryForHost(
host.to_string(), include_subdomains, header.max_age
)
).unwrap();
let msg = ControlMsg::SetHSTSEntryForHost(
host.to_string(),
include_subdomains,
header.max_age
);
resource_mgr_chan.send(msg).unwrap();
}
}
}
pub struct StreamedResponse<R: HttpResponse> {
decoder: Decoder<R>,
pub metadata: Metadata
}
if response.status.class() == StatusClass::Redirection {
match response.headers.get::<Location>() {
impl<R: HttpResponse> Read for StreamedResponse<R> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.decoder {
Decoder::Gzip(ref mut d) => d.read(buf),
Decoder::Deflate(ref mut d) => d.read(buf),
Decoder::Plain(ref mut d) => d.read(buf)
}
}
}
impl<R: HttpResponse> StreamedResponse<R> {
fn new(m: Metadata, d: Decoder<R>) -> StreamedResponse<R> {
StreamedResponse { metadata: m, decoder: d }
}
fn from_http_response(response: R, m: Metadata) -> Result<StreamedResponse<R>, LoadError> {
match response.content_encoding() {
Some(Encoding::Gzip) => {
let result = GzDecoder::new(response);
match result {
Ok(response_decoding) => {
return Ok(StreamedResponse::new(m, Decoder::Gzip(response_decoding)));
}
Err(err) => {
return Err(LoadError::Decoding(m.final_url, err.to_string()));
}
}
}
Some(Encoding::Deflate) => {
let response_decoding = DeflateDecoder::new(response);
return Ok(StreamedResponse::new(m, Decoder::Deflate(response_decoding)));
}
_ => {
return Ok(StreamedResponse::new(m, Decoder::Plain(response)));
}
}
}
}
enum Decoder<R: Read> {
Gzip(GzDecoder<R>),
Deflate(DeflateDecoder<R>),
Plain(R)
}
fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
request_id: String,
url: Url,
method: Method,
headers: Headers,
body: Option<Vec<u8>>) {
if let Some(ref chan) = devtools_chan {
let net_event = NetworkEvent::HttpRequest(url, method, headers, body);
let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event);
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
}
}
fn send_response_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
request_id: String,
headers: Option<Headers>,
status: Option<RawStatus>) {
if let Some(ref chan) = devtools_chan {
let net_event_response = NetworkEvent::HttpResponse(headers, status, None);
let msg = ChromeToDevtoolsControlMsg::NetworkEvent(request_id, net_event_response);
chan.send(DevtoolsControlMsg::FromChrome(msg)).unwrap();
}
}
pub fn load<A>(load_data: LoadData,
resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
request_factory: &HttpRequestFactory<R=A>)
-> Result<StreamedResponse<A::R>, LoadError> where A: HttpRequest + 'static {
// FIXME: At the time of writing this FIXME, servo didn't have any central
// location for configuration. If you're reading this and such a
// repository DOES exist, please update this constant to use it.
let max_redirects = 50;
let mut iters = 0;
// URL of the document being loaded, as seen by all the higher-level code.
let mut doc_url = load_data.url.clone();
// URL that we actually fetch from the network, after applying the replacements
// specified in the hosts file.
let mut url = replace_hosts(&load_data.url);
let mut redirected_to = HashSet::new();
let mut method = load_data.method.clone();
// If the URL is a view-source scheme then the scheme data contains the
// real URL that should be used for which the source is to be viewed.
// Change our existing URL to that and keep note that we are viewing
// the source rather than rendering the contents of the URL.
let viewing_source = url.scheme == "view-source";
if viewing_source {
url = inner_url(&load_data.url);
doc_url = url.clone();
}
// Loop to handle redirects.
loop {
iters = iters + 1;
if &*url.scheme == "http" && request_must_be_secured(&url, &resource_mgr_chan) {
info!("{} is in the strict transport security list, requesting secure host", url);
url = secure_url(&url);
}
if iters > max_redirects {
return Err(LoadError::MaxRedirects(url));
}
if &*url.scheme != "http" && &*url.scheme != "https" {
return Err(LoadError::UnsupportedScheme(url));
}
info!("requesting {}", url.serialize());
// Ensure that the host header is set from the original url
let host = Host {
hostname: doc_url.serialize_host().unwrap(),
port: doc_url.port_or_default()
};
// Avoid automatically preserving request headers when redirects occur.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=401564 and
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828 .
// Only preserve ones which have been explicitly marked as such.
let mut request_headers = if iters == 1 {
let mut combined_headers = load_data.headers.clone();
combined_headers.extend(load_data.preserved_headers.iter());
combined_headers
} else {
load_data.preserved_headers.clone()
};
request_headers.set(host);
set_default_accept(&mut request_headers);
set_default_accept_encoding(&mut request_headers);
set_request_cookies(doc_url.clone(), &mut request_headers, &resource_mgr_chan);
let mut req = try!(request_factory.create(url.clone(), method.clone()));
*req.headers_mut() = request_headers;
if log_enabled!(log::LogLevel::Info) {
info!("{}", method);
for header in req.headers_mut().iter() {
info!(" - {}", header);
}
info!("{:?}", load_data.data);
}
// Avoid automatically sending request body if a redirect has occurred.
//
// TODO - This is the wrong behaviour according to the RFC. However, I'm not
// sure how much "correctness" vs. real-world is important in this case.
//
// https://tools.ietf.org/html/rfc7231#section-6.4
let is_redirected_request = iters != 1;
let request_id = uuid::Uuid::new_v4().to_simple_string();
let response = match load_data.data {
Some(ref data) if !is_redirected_request => {
req.headers_mut().set(ContentLength(data.len() as u64));
// TODO: Do this only if load_data has some pipeline_id, and send the pipeline_id
// in the message
send_request_to_devtools(
devtools_chan.clone(), request_id.clone(), url.clone(),
method.clone(), load_data.headers.clone(),
load_data.data.clone()
);
try!(req.send(&load_data.data))
}
_ => {
if load_data.method != Method::Get && load_data.method != Method::Head {
req.headers_mut().set(ContentLength(0))
}
send_request_to_devtools(
devtools_chan.clone(), request_id.clone(), url.clone(),
method.clone(), load_data.headers.clone(),
None
);
try!(req.send(&None))
}
};
info!("got HTTP response {}, headers:", response.status());
if log_enabled!(log::LogLevel::Info) {
for header in response.headers().iter() {
info!(" - {}", header);
}
}
set_cookies_from_response(doc_url.clone(), &response, &resource_mgr_chan);
update_sts_list_from_response(&url, &response, &resource_mgr_chan);
// --- Loop if there's a redirect
if response.status().class() == StatusClass::Redirection {
match response.headers().get::<Location>() {
Some(&Location(ref new_url)) => {
// CORS (https://fetch.spec.whatwg.org/#http-fetch, status section, point 9, 10)
match load_data.cors {
Some(ref c) => {
if c.preflight {
// The preflight lied
send_error(url,
"Preflight fetch inconsistent with main fetch".to_string(),
start_chan);
return;
return Err(
LoadError::Cors(
url,
"Preflight fetch inconsistent with main fetch".to_string()));
} else {
// XXXManishearth There are some CORS-related steps here,
// but they don't seem necessary until credentials are implemented
@ -349,28 +576,28 @@ reason: \"certificate verify failed\" }]))";
}
_ => {}
}
let new_doc_url = match UrlParser::new().base_url(&doc_url).parse(&new_url) {
Ok(u) => u,
Err(e) => {
send_error(doc_url, e.to_string(), start_chan);
return;
return Err(LoadError::InvalidRedirect(doc_url, e.to_string()));
}
};
info!("redirecting to {}", new_doc_url);
url = replace_hosts(&new_doc_url);
doc_url = new_doc_url;
// According to https://tools.ietf.org/html/rfc7231#section-6.4.2,
// historically UAs have rewritten POST->GET on 301 and 302 responses.
if load_data.method == Method::Post &&
(response.status == StatusCode::MovedPermanently ||
response.status == StatusCode::Found) {
load_data.method = Method::Get;
if method == Method::Post &&
(response.status() == StatusCode::MovedPermanently ||
response.status() == StatusCode::Found) {
method = Method::Get;
}
if redirected_to.contains(&doc_url) {
send_error(doc_url, "redirect loop".to_string(), start_chan);
return;
if redirected_to.contains(&url) {
return Err(LoadError::InvalidRedirect(doc_url, "redirect loop".to_string()));
}
redirected_to.insert(doc_url.clone());
@ -380,11 +607,13 @@ reason: \"certificate verify failed\" }]))";
}
}
let mut adjusted_headers = response.headers.clone();
let mut adjusted_headers = response.headers().clone();
if viewing_source {
adjusted_headers.set(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![])));
}
let mut metadata: Metadata = Metadata::default(doc_url);
let mut metadata: Metadata = Metadata::default(doc_url.clone());
metadata.set_content_type(match adjusted_headers.get() {
Some(&ContentType(ref mime)) => Some(mime),
None => None
@ -392,56 +621,16 @@ reason: \"certificate verify failed\" }]))";
metadata.headers = Some(adjusted_headers);
metadata.status = Some(response.status_raw().clone());
let mut encoding_str: Option<String> = None;
//FIXME: Implement Content-Encoding Header https://github.com/hyperium/hyper/issues/391
if let Some(encodings) = response.headers.get_raw("content-encoding") {
for encoding in encodings {
if let Ok(encodings) = String::from_utf8(encoding.clone()) {
if encodings == "gzip" || encodings == "deflate" {
encoding_str = Some(encodings);
break;
}
}
}
}
// --- Tell devtools that we got a response
// Send an HttpResponse message to devtools with the corresponding request_id
// TODO: Send this message only if load_data has a pipeline_id that is not None
if let Some(ref chan) = devtools_chan {
let net_event_response =
NetworkEvent::HttpResponse(metadata.headers.clone(),
metadata.status.clone(),
None);
chan.send(DevtoolsControlMsg::FromChrome(
ChromeToDevtoolsControlMsg::NetworkEvent(request_id,
net_event_response))).unwrap();
}
// TODO: Send this message even when the load fails?
send_response_to_devtools(
devtools_chan, request_id,
metadata.headers.clone(), metadata.status.clone()
);
match encoding_str {
Some(encoding) => {
if encoding == "gzip" {
let result = GzDecoder::new(response);
match result {
Ok(mut response_decoding) => {
send_data(&mut response_decoding, start_chan, metadata, classifier);
}
Err(err) => {
send_error(metadata.final_url, err.to_string(), start_chan);
return;
}
}
} else if encoding == "deflate" {
let mut response_decoding = DeflateDecoder::new(response);
send_data(&mut response_decoding, start_chan, metadata, classifier);
}
},
None => {
send_data(&mut response, start_chan, metadata, classifier);
}
}
// We didn't get redirected.
break;
return StreamedResponse::from_http_response(response, metadata)
}
}

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::borrow::ToOwned;
use std::cmp::max;
pub struct MIMEClassifier {
image_classifier: GroupedClassifier,
@ -24,51 +23,34 @@ impl MIMEClassifier {
data: &[u8]) -> Option<(String, String)> {
match *supplied_type {
None => {
return self.sniff_unknown_type(!no_sniff, data);
}
None => self.sniff_unknown_type(!no_sniff, data),
Some((ref media_type, ref media_subtype)) => {
match (&**media_type, &**media_subtype) {
("unknown", "unknown") | ("application", "unknown") | ("*", "*") => {
return self.sniff_unknown_type(!no_sniff, data);
}
("unknown", "unknown") |
("application", "unknown") |
("*", "*") => self.sniff_unknown_type(!no_sniff, data),
_ => {
if no_sniff {
return supplied_type.clone();
}
if check_for_apache_bug {
return self.sniff_text_or_data(data);
}
if MIMEClassifier::is_xml(media_type, media_subtype) {
return supplied_type.clone();
}
//Inplied in section 7.3, but flow is not clear
if MIMEClassifier::is_html(media_type, media_subtype) {
return self.feeds_classifier
.classify(data)
.or(supplied_type.clone());
}
if &**media_type == "image" {
if let Some(tp) = self.image_classifier.classify(data) {
return Some(tp);
}
}
supplied_type.clone()
} else if check_for_apache_bug {
self.sniff_text_or_data(data)
} else if MIMEClassifier::is_xml(media_type, media_subtype) {
supplied_type.clone()
} else if MIMEClassifier::is_html(media_type, media_subtype) {
//Implied in section 7.3, but flow is not clear
self.feeds_classifier.classify(data).or(supplied_type.clone())
} else {
match (&**media_type, &**media_subtype) {
("audio", _) | ("video", _) | ("application", "ogg") => {
if let Some(tp) = self.audio_video_classifer.classify(data) {
return Some(tp);
}
}
_ => {}
("image", _) => self.image_classifier.classify(data),
("audio", _) | ("video", _) | ("application", "ogg") =>
self.audio_video_classifer.classify(data),
_ => None
}.or(supplied_type.clone())
}
}
}
}
}
return supplied_type.clone();
}
pub fn new() -> MIMEClassifier {
@ -99,13 +81,15 @@ impl MIMEClassifier {
fn sniff_text_or_data(&self, data: &[u8]) -> Option<(String, String)> {
self.binary_or_plaintext.classify(data)
}
fn is_xml(tp: &str, sub_tp: &str) -> bool {
let suffix = &sub_tp[(max(sub_tp.len() as isize - "+xml".len() as isize, 0) as usize)..];
match (tp, sub_tp, suffix) {
(_, _, "+xml") | ("application", "xml",_) | ("text", "xml",_) => {true}
_ => {false}
sub_tp.ends_with("+xml") ||
match (tp, sub_tp) {
("application", "xml") | ("text", "xml") => true,
_ => false
}
}
fn is_html(tp: &str, sub_tp: &str) -> bool {
tp == "text" && sub_tp == "html"
}
@ -141,13 +125,11 @@ impl <'a, T: Iterator<Item=&'a u8> + Clone> Matches for T {
// Side effects
// moves the iterator when match is found
fn matches(&mut self, matches: &[u8]) -> bool {
for (byte_a, byte_b) in self.clone().take(matches.len()).zip(matches) {
if byte_a != byte_b {
return false;
}
}
let result = self.clone().zip(matches).all(|(s, m)| *s == *m);
if result {
self.nth(matches.len());
true
}
result
}
}
@ -160,31 +142,22 @@ struct ByteMatcher {
impl ByteMatcher {
fn matches(&self, data: &[u8]) -> Option<usize> {
if data.len() < self.pattern.len() {
return None;
None
} else if data == self.pattern {
Some(self.pattern.len())
} else {
data[..data.len() - self.pattern.len()].iter()
.position(|x| !self.leading_ignore.contains(x))
.and_then(|start|
if data[start..].iter()
.zip(self.pattern.iter()).zip(self.mask.iter())
.all(|((&data, &pattern), &mask)| (data & mask) == (pattern & mask)) {
Some(start + self.pattern.len())
} else {
None
})
}
//TODO replace with iterators if I ever figure them out...
let mut i: usize = 0;
let max_i = data.len()-self.pattern.len();
loop {
if !self.leading_ignore.iter().any(|x| *x == data[i]) {
break;
}
i = i + 1;
if i > max_i {
return None;
}
}
for j in 0..self.pattern.len() {
if (data[i] & self.mask[j]) != (self.pattern[j] & self.mask[j]) {
return None;
}
i = i + 1;
}
Some(i)
}
}
@ -202,14 +175,13 @@ struct TagTerminatedByteMatcher {
impl MIMEChecker for TagTerminatedByteMatcher {
fn classify(&self, data: &[u8]) -> Option<(String, String)> {
let pattern = self.matcher.matches(data);
let pattern_matches = pattern.map(|j| j < data.len() && (data[j] == b' ' || data[j] == b'>'));
if pattern_matches.unwrap_or(false) {
self.matcher.matches(data).and_then(|j|
if j < data.len() && (data[j] == b' ' || data[j] == b'>') {
Some((self.matcher.content_type.0.to_owned(),
self.matcher.content_type.1.to_owned()))
} else {
None
}
})
}
}
pub struct Mp4Matcher;
@ -219,48 +191,21 @@ impl Mp4Matcher {
if data.len() < 12 {
return false;
}
let box_size = ((data[0] as u32) << 3 | (data[1] as u32) << 2 |
(data[2] as u32) << 1 | (data[3] as u32)) as usize;
if (data.len() < box_size) || (box_size % 4 != 0) {
return false;
}
//TODO replace with iterators
let ftyp = [0x66, 0x74, 0x79, 0x70];
let mp4 = [0x6D, 0x70, 0x34];
for i in 4..8 {
if data[i] != ftyp[i - 4] {
let ftyp = [0x66, 0x74, 0x79, 0x70];
if !data[4..].starts_with(&ftyp) {
return false;
}
}
let mut all_match = true;
for i in 8..11 {
if data[i] != mp4[i - 8] {
all_match = false;
break;
}
}
if all_match {
return true;
}
let mut bytes_read: usize = 16;
while bytes_read < box_size {
all_match = true;
for i in 0..3 {
if mp4[i] != data[i + bytes_read] {
all_match = false;
break;
}
}
if all_match {
return true;
}
bytes_read = bytes_read + 4;
}
false
let mp4 = [0x6D, 0x70, 0x34];
data[8..].starts_with(&mp4) ||
data[16..box_size].chunks(4).any(|chunk| chunk.starts_with(&mp4))
}
}
@ -278,27 +223,24 @@ struct BinaryOrPlaintextClassifier;
impl BinaryOrPlaintextClassifier {
fn classify_impl(&self, data: &[u8]) -> (&'static str, &'static str) {
if (data.len() >= 2 &&
((data[0] == 0xFFu8 && data[1] == 0xFEu8) ||
(data[0] == 0xFEu8 && data[1] == 0xFFu8))) ||
(data.len() >= 3 && data[0] == 0xEFu8 && data[1] == 0xBBu8 && data[2] == 0xBFu8)
if data == &[0xFFu8, 0xFEu8] ||
data == &[0xFEu8, 0xFFu8] ||
data.starts_with(&[0xEFu8, 0xBBu8, 0xBFu8])
{
("text", "plain")
}
else if data.len() >= 1 && data.iter().any(|&x| x <= 0x08u8 ||
} else if data.iter().any(|&x| x <= 0x08u8 ||
x == 0x0Bu8 ||
(x >= 0x0Eu8 && x <= 0x1Au8) ||
(x >= 0x1Cu8 && x <= 0x1Fu8)) {
("application", "octet-stream")
}
else {
} else {
("text", "plain")
}
}
}
impl MIMEChecker for BinaryOrPlaintextClassifier {
fn classify(&self, data: &[u8]) -> Option<(String, String)> {
return as_string_option(Some(self.classify_impl(data)));
as_string_option(Some(self.classify_impl(data)))
}
}
struct GroupedClassifier {
@ -358,7 +300,6 @@ impl GroupedClassifier {
box ByteMatcher::application_pdf()
]
}
}
fn plaintext_classifier() -> GroupedClassifier {
GroupedClassifier {
@ -403,70 +344,97 @@ impl MIMEChecker for GroupedClassifier {
}
}
enum Match {
Start,
DidNotMatch,
StartAndEnd
}
impl Match {
fn chain<F: FnOnce() -> Match>(self, f: F) -> Match {
if let Match::DidNotMatch = self {
return f();
}
self
}
}
fn eats_until<'a, T>(matcher: &mut T, start: &[u8], end: &[u8]) -> Match
where T: Iterator<Item=&'a u8> + Clone {
if !matcher.matches(start) {
Match::DidNotMatch
} else if end.len() == 1 {
if matcher.any(|&x| x == end[0]) {
Match::StartAndEnd
} else {
Match::Start
}
} else {
while !matcher.matches(end) {
if matcher.next().is_none() {
return Match::Start;
}
}
Match::StartAndEnd
}
}
struct FeedsClassifier;
impl FeedsClassifier {
fn classify_impl(&self, data: &[u8]) -> Option<(&'static str, &'static str)> {
let length = data.len();
let mut data_iterator = data.iter();
// acceptable byte sequences
let utf8_bom = &[0xEFu8, 0xBBu8, 0xBFu8];
// can not be feed unless length is > 3
if length < 3 {
if data.len() < 3 {
return None;
}
// eat the first three bytes if they are equal to UTF-8 BOM
data_iterator.matches(utf8_bom);
let mut matcher = data.iter();
// continuously search for next "<" until end of data_iterator
// eat the first three acceptable byte sequences if they are equal to UTF-8 BOM
let utf8_bom = &[0xEFu8, 0xBBu8, 0xBFu8];
matcher.matches(utf8_bom);
// continuously search for next "<" until end of matcher
// TODO: need max_bytes to prevent inadvertently examining html document
// eg. an html page with a feed example
while !data_iterator.find(|&data_iterator| *data_iterator == b'<').is_none() {
loop {
if data_iterator.matches(b"?") {
// eat until ?>
while !data_iterator.matches(b"?>") {
if data_iterator.next().is_none() {
if matcher.find(|&x| *x == b'<').is_none() {
return None;
}
match eats_until(&mut matcher, b"?", b"?>")
.chain(|| eats_until(&mut matcher, b"!--", b"-->"))
.chain(|| eats_until(&mut matcher, b"!", b">")) {
Match::StartAndEnd => continue,
Match::DidNotMatch => {},
Match::Start => return None
}
} else if data_iterator.matches(b"!--") {
// eat until -->
while !data_iterator.matches(b"-->") {
if data_iterator.next().is_none() {
return None;
}
}
} else if data_iterator.matches(b"!") {
data_iterator.find(|&data_iterator| *data_iterator == b'>');
} else if data_iterator.matches(b"rss") {
if matcher.matches(b"rss") {
return Some(("application", "rss+xml"));
} else if data_iterator.matches(b"feed") {
}
if matcher.matches(b"feed") {
return Some(("application", "atom+xml"));
} else if data_iterator.matches(b"rdf: RDF") {
while !data_iterator.next().is_none() {
if data_iterator.matches(b"http: //purl.org/rss/1.0/") {
while !data_iterator.next().is_none() {
if data_iterator.matches(b"http: //www.w3.org/1999/02/22-rdf-syntax-ns#") {
return Some(("application", "rss+xml"));
}
if matcher.matches(b"rdf: RDF") {
while matcher.next().is_some() {
match eats_until(&mut matcher,
b"http: //purl.org/rss/1.0/",
b"http: //www.w3.org/1999/02/22-rdf-syntax-ns#")
.chain(|| eats_until(&mut matcher,
b"http: //www.w3.org/1999/02/22-rdf-syntax-ns#",
b"http: //purl.org/rss/1.0/")) {
Match::StartAndEnd => return Some(("application", "rss+xml")),
Match::DidNotMatch => {},
Match::Start => return None
}
}
} else if data_iterator.matches(b"http: //www.w3.org/1999/02/22-rdf-syntax-ns#") {
while !data_iterator.next().is_none() {
if data_iterator.matches(b"http: //purl.org/rss/1.0/") {
return Some(("application", "rss+xml"));
return None;
}
}
}
}
}
}
None
}
}
impl MIMEChecker for FeedsClassifier {
fn classify(&self, data: &[u8]) -> Option<(String, String)> {

View file

@ -29,7 +29,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::mpsc::{channel, Sender};
pub enum ProgressSender {
@ -175,6 +174,9 @@ impl ResourceChannelManager {
self.resource_manager.add_hsts_entry(entry)
}
}
ControlMsg::GetHostMustBeSecured(host, consumer) => {
consumer.send(self.resource_manager.is_host_sts(&*host)).unwrap();
}
ControlMsg::Exit => {
break
}
@ -189,7 +191,7 @@ pub struct ResourceManager {
resource_task: IpcSender<ControlMsg>,
mime_classifier: Arc<MIMEClassifier>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>
hsts_list: HSTSList
}
impl ResourceManager {
@ -203,7 +205,7 @@ impl ResourceManager {
resource_task: resource_task,
mime_classifier: Arc::new(MIMEClassifier::new()),
devtools_chan: devtools_channel,
hsts_list: Arc::new(Mutex::new(hsts_list))
hsts_list: hsts_list
}
}
}
@ -221,11 +223,11 @@ impl ResourceManager {
}
pub fn add_hsts_entry(&mut self, entry: HSTSEntry) {
self.hsts_list.lock().unwrap().push(entry);
self.hsts_list.push(entry);
}
pub fn is_host_sts(&self, host: &str) -> bool {
self.hsts_list.lock().unwrap().is_host_secure(host)
self.hsts_list.is_host_secure(host)
}
fn load(&mut self, mut load_data: LoadData, consumer: LoadConsumer) {
@ -241,7 +243,7 @@ impl ResourceManager {
let loader = match &*load_data.url.scheme {
"file" => from_factory(file_loader::factory),
"http" | "https" | "view-source" =>
http_loader::factory(self.resource_task.clone(), self.devtools_chan.clone(), self.hsts_list.clone()),
http_loader::factory(self.resource_task.clone(), self.devtools_chan.clone()),
"data" => from_factory(data_loader::factory),
"about" => from_factory(about_loader::factory),
_ => {

View file

@ -161,6 +161,7 @@ pub enum ControlMsg {
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
/// Store a domain's STS information
SetHSTSEntryForHost(String, IncludeSubdomains, u64),
GetHostMustBeSecured(String, IpcSender<bool>),
Exit
}

View file

@ -17,6 +17,7 @@ pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotat
item2.attrs.push(quote_attr!(cx, #[must_root]));
item2.attrs.push(quote_attr!(cx, #[privatize]));
item2.attrs.push(quote_attr!(cx, #[derive(JSTraceable)]));
item2.attrs.push(quote_attr!(cx, #[derive(HeapSizeOf)]));
// The following attributes are only for internal usage
item2.attrs.push(quote_attr!(cx, #[_generate_reflector]));

View file

@ -55,6 +55,10 @@ features = ["query_encoding", "serde_serialization"]
[dependencies.offscreen_gl_context]
git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
[dependencies.angle]
git = "https://github.com/ecoal95/angle"
branch = "servo"
[dependencies.cssparser]
version = "0.3"
features = [ "serde-serialization" ]

View file

@ -13,9 +13,7 @@ use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::conversions::jsstring_to_str;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
use dom::document::DocumentHelpers;
use dom::node::{Node, NodeHelpers};
use dom::window::{WindowHelpers, ScriptHelpers};
use dom::node::Node;
use ipc_channel::ipc::IpcSender;
use js::jsapi::{ObjectClassName, RootedObject, RootedValue};
use js::jsval::UndefinedValue;

View file

@ -4,8 +4,8 @@
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast};
use dom::element::{Element, ActivationElementHelpers};
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
use dom::element::Element;
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
use dom::mouseevent::MouseEvent;
use dom::node::window_from_node;

View file

@ -9,7 +9,7 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutNullableHeap};
use dom::bindings::js::{Root, RootedReference, LayoutJS};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::element::Element;
use dom::virtualmethods::vtable_for;
use dom::window::Window;
@ -111,7 +111,6 @@ impl Deref for AttrValue {
// https://dom.spec.whatwg.org/#interface-attr
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Attr {
reflector_: Reflector,
local_name: Atom,
@ -163,19 +162,19 @@ impl Attr {
}
}
impl<'a> AttrMethods for &'a Attr {
impl AttrMethods for Attr {
// https://dom.spec.whatwg.org/#dom-attr-localname
fn LocalName(self) -> DOMString {
fn LocalName(&self) -> DOMString {
(**self.local_name()).to_owned()
}
// https://dom.spec.whatwg.org/#dom-attr-value
fn Value(self) -> DOMString {
fn Value(&self) -> DOMString {
(**self.value()).to_owned()
}
// https://dom.spec.whatwg.org/#dom-attr-value
fn SetValue(self, value: DOMString) {
fn SetValue(&self, value: DOMString) {
match self.owner() {
None => *self.value.borrow_mut() = AttrValue::String(value),
Some(owner) => {
@ -186,32 +185,32 @@ impl<'a> AttrMethods for &'a Attr {
}
// https://dom.spec.whatwg.org/#dom-attr-textcontent
fn TextContent(self) -> DOMString {
fn TextContent(&self) -> DOMString {
self.Value()
}
// https://dom.spec.whatwg.org/#dom-attr-textcontent
fn SetTextContent(self, value: DOMString) {
fn SetTextContent(&self, value: DOMString) {
self.SetValue(value)
}
// https://dom.spec.whatwg.org/#dom-attr-nodevalue
fn NodeValue(self) -> DOMString {
fn NodeValue(&self) -> DOMString {
self.Value()
}
// https://dom.spec.whatwg.org/#dom-attr-nodevalue
fn SetNodeValue(self, value: DOMString) {
fn SetNodeValue(&self, value: DOMString) {
self.SetValue(value)
}
// https://dom.spec.whatwg.org/#dom-attr-name
fn Name(self) -> DOMString {
fn Name(&self) -> DOMString {
(*self.name).to_owned()
}
// https://dom.spec.whatwg.org/#dom-attr-namespaceuri
fn GetNamespaceURI(self) -> Option<DOMString> {
fn GetNamespaceURI(&self) -> Option<DOMString> {
let Namespace(ref atom) = self.namespace;
match &**atom {
"" => None,
@ -220,32 +219,24 @@ impl<'a> AttrMethods for &'a Attr {
}
// https://dom.spec.whatwg.org/#dom-attr-prefix
fn GetPrefix(self) -> Option<DOMString> {
fn GetPrefix(&self) -> Option<DOMString> {
self.prefix().as_ref().map(|p| (**p).to_owned())
}
// https://dom.spec.whatwg.org/#dom-attr-ownerelement
fn GetOwnerElement(self) -> Option<Root<Element>> {
fn GetOwnerElement(&self) -> Option<Root<Element>> {
self.owner()
}
// https://dom.spec.whatwg.org/#dom-attr-specified
fn Specified(self) -> bool {
fn Specified(&self) -> bool {
true // Always returns true
}
}
pub trait AttrHelpers<'a> {
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element);
fn value(self) -> Ref<'a, AttrValue>;
fn local_name(self) -> &'a Atom;
fn set_owner(self, owner: Option<&Element>);
fn owner(self) -> Option<Root<Element>>;
fn summarize(self) -> AttrInfo;
}
impl<'a> AttrHelpers<'a> for &'a Attr {
fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element) {
impl Attr {
pub fn set_value(&self, set_type: AttrSettingType, value: AttrValue, owner: &Element) {
assert!(Some(owner) == self.owner().r());
let node = NodeCast::from_ref(owner);
@ -264,17 +255,17 @@ impl<'a> AttrHelpers<'a> for &'a Attr {
}
}
fn value(self) -> Ref<'a, AttrValue> {
pub fn value(&self) -> Ref<AttrValue> {
self.value.borrow()
}
fn local_name(self) -> &'a Atom {
pub fn local_name(&self) -> &Atom {
&self.local_name
}
/// Sets the owner element. Should be called after the attribute is added
/// or removed from its older parent.
fn set_owner(self, owner: Option<&Element>) {
pub fn set_owner(&self, owner: Option<&Element>) {
let ref ns = self.namespace;
match (self.owner().r(), owner) {
(None, Some(new)) => {
@ -290,11 +281,11 @@ impl<'a> AttrHelpers<'a> for &'a Attr {
self.owner.set(owner.map(JS::from_ref))
}
fn owner(self) -> Option<Root<Element>> {
pub fn owner(&self) -> Option<Root<Element>> {
self.owner.get().map(Root::from_rooted)
}
fn summarize(self) -> AttrInfo {
pub fn summarize(&self) -> AttrInfo {
let Namespace(ref ns) = self.namespace;
AttrInfo {
namespace: (**ns).to_owned(),

View file

@ -339,7 +339,7 @@ class CGMethodCall(CGThing):
code = (
"if argc < %d {\n"
" throw_type_error(cx, \"Not enough arguments to %s.\");\n"
" return 0;\n"
" return JSFalse;\n"
"}" % (requiredArgs, methodName))
self.cgRoot.prepend(
CGWrapper(CGGeneric(code), pre="\n", post="\n"))
@ -512,11 +512,11 @@ class CGMethodCall(CGThing):
CGSwitch("argcount",
argCountCases,
CGGeneric("throw_type_error(cx, \"Not enough arguments to %s.\");\n"
"return 0;" % methodName)))
"return JSFalse;" % methodName)))
# XXXjdm Avoid unreachable statement warnings
# overloadCGThings.append(
# CGGeneric('panic!("We have an always-returning default case");\n'
# 'return 0;'))
# 'return JSFalse;'))
self.cgRoot = CGWrapper(CGList(overloadCGThings, "\n"),
pre="\n")
@ -888,7 +888,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if invalidEnumValueFatal:
handleInvalidEnumValueCode = exceptionCode
else:
handleInvalidEnumValueCode = "return 1;"
handleInvalidEnumValueCode = "return JSTrue;"
transmute = "mem::transmute(index)"
if isMember == 'Dictionary':
transmute = 'unsafe { ' + transmute + ' }'
template = (
"match find_enum_string_index(cx, ${val}, %(values)s) {\n"
@ -896,10 +900,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
" Ok(None) => { %(handleInvalidEnumValueCode)s },\n"
" Ok(Some(index)) => {\n"
" //XXXjdm need some range checks up in here.\n"
" unsafe { mem::transmute(index) }\n"
" %(transmute)s\n"
" },\n"
"}" % {"values": enum + "Values::strings",
"exceptionCode": exceptionCode,
"transmute": transmute,
"handleInvalidEnumValueCode": handleInvalidEnumValueCode})
if defaultValue is not None:
@ -1012,7 +1017,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
declType = CGGeneric(typeName)
template = ("match %s::new(cx, ${val}) {\n"
" Ok(dictionary) => dictionary,\n"
" Err(_) => return 0,\n"
" Err(_) => return JSFalse,\n"
"}" % typeName)
return handleOptional(template, declType, handleDefaultNull("%s::empty(cx)" % typeName))
@ -1037,7 +1042,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
conversionBehavior = "()"
if failureCode is None:
failureCode = 'return 0'
failureCode = 'return JSFalse'
declType = CGGeneric(builtinNames[type.tag()])
if type.nullable():
@ -1216,7 +1221,7 @@ class CGArgumentConverter(CGThing):
return self.converter.define()
def wrapForType(jsvalRef, result='result', successCode='return 1;', pre=''):
def wrapForType(jsvalRef, result='result', successCode='return JSTrue;', pre=''):
"""
Reflect a Rust value into JS.
@ -1472,6 +1477,7 @@ class AttrDefiner(PropertyDefiner):
def __init__(self, descriptor, name, static):
PropertyDefiner.__init__(self, descriptor, name)
self.name = name
self.descriptor = descriptor
self.regular = [
m
for m in descriptor.interface.members
@ -1488,14 +1494,14 @@ class AttrDefiner(PropertyDefiner):
def getter(attr):
if self.static:
accessor = 'get_' + attr.identifier.name
accessor = 'get_' + self.descriptor.internalNameFor(attr.identifier.name)
jitinfo = "0 as *const JSJitInfo"
else:
if attr.hasLenientThis():
accessor = "generic_lenient_getter"
else:
accessor = "generic_getter"
jitinfo = "&%s_getterinfo" % attr.identifier.name
jitinfo = "&%s_getterinfo" % self.descriptor.internalNameFor(attr.identifier.name)
return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }"
% {"info": jitinfo,
@ -1506,14 +1512,14 @@ class AttrDefiner(PropertyDefiner):
return "JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }"
if self.static:
accessor = 'set_' + attr.identifier.name
accessor = 'set_' + self.descriptor.internalNameFor(attr.identifier.name)
jitinfo = "0 as *const JSJitInfo"
else:
if attr.hasLenientThis():
accessor = "generic_lenient_setter"
else:
accessor = "generic_setter"
jitinfo = "&%s_setterinfo" % attr.identifier.name
jitinfo = "&%s_setterinfo" % self.descriptor.internalNameFor(attr.identifier.name)
return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }"
% {"info": jitinfo,
@ -1620,19 +1626,11 @@ class CGImports(CGWrapper):
"""
if ignored_warnings is None:
ignored_warnings = [
# Allow unreachable_code because we use 'break' in a way that
# sometimes produces two 'break's in a row. See for example
# CallbackMember.getArgConversions.
'unreachable_code',
'non_camel_case_types',
'non_upper_case_globals',
'unused_parens',
'unused_imports',
'unused_variables',
'unused_unsafe',
'unused_mut',
'unused_assignments',
'dead_code',
]
def componentTypes(type):
@ -2049,7 +2047,7 @@ class CGAbstractMethod(CGThing):
"""
def __init__(self, descriptor, name, returnType, args, inline=False,
alwaysInline=False, extern=False, pub=False, templateArgs=None,
unsafe=True):
unsafe=False):
CGThing.__init__(self)
self.descriptor = descriptor
self.name = name
@ -2111,7 +2109,7 @@ class CGAbstractMethod(CGThing):
def CreateBindingJSObject(descriptor, parent=None):
create = "let mut raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
create = "let raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
if descriptor.proxy:
assert not descriptor.isGlobal()
create += """
@ -2160,12 +2158,13 @@ class CGWrapMethod(CGAbstractMethod):
assert not descriptor.interface.isCallback()
if not descriptor.isGlobal():
args = [Argument('*mut JSContext', 'cx'), Argument('GlobalRef', 'scope'),
Argument("Box<%s>" % descriptor.concreteType, 'object', mutable=True)]
Argument("Box<%s>" % descriptor.concreteType, 'object')]
else:
args = [Argument('*mut JSContext', 'cx'),
Argument("Box<%s>" % descriptor.concreteType, 'object', mutable=True)]
Argument("Box<%s>" % descriptor.concreteType, 'object')]
retval = 'Root<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, pub=True)
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
pub=True, unsafe=True)
def definition_body(self):
if not self.descriptor.isGlobal():
@ -2309,6 +2308,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
def definition_body(self):
protoChain = self.descriptor.prototypeChain
if len(protoChain) == 1:
self.unsafe = True
getParentProto = "parent_proto.ptr = JS_GetObjectPrototype(cx, global)"
else:
parentProtoName = self.descriptor.prototypeChain[-2]
@ -2382,7 +2382,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
Argument('HandleObject', 'receiver'),
Argument('MutableHandleObject', 'rval')]
CGAbstractMethod.__init__(self, descriptor, name,
'void', args, pub=pub)
'void', args, pub=pub, unsafe=True)
self.id = idPrefix + "ID::" + self.descriptor.name
def definition_body(self):
@ -2452,7 +2452,9 @@ class CGDefineProxyHandler(CGAbstractMethod):
"""
def __init__(self, descriptor):
assert descriptor.proxy
CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', '*const libc::c_void', [], pub=True)
CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler',
'*const libc::c_void', [],
pub=True, unsafe=True)
def define(self):
return CGAbstractMethod.define(self)
@ -2778,7 +2780,7 @@ class CGSetterCall(CGPerSignatureCall):
def wrap_return_value(self):
# We have no return value
return "\nreturn 1;"
return "\nreturn JSTrue;"
def getArgc(self):
return "1"
@ -2835,7 +2837,10 @@ class CGSpecializedMethod(CGAbstractExternMethod):
@staticmethod
def makeNativeName(descriptor, method):
name = method.identifier.name
return MakeNativeName(descriptor.binaryNameFor(name))
nativeName = descriptor.binaryNameFor(name)
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
return MakeNativeName(nativeName)
class CGStaticMethod(CGAbstractStaticBindingMethod):
@ -2850,7 +2855,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
def generate_code(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
self.method)
setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n")
setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method)
return CGList([setupArgs, call])
@ -2862,7 +2867,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
"""
def __init__(self, descriptor, attr):
self.attr = attr
name = 'get_' + attr.identifier.name
name = 'get_' + descriptor.internalNameFor(attr.identifier.name)
args = [Argument('*mut JSContext', 'cx'),
Argument('HandleObject', '_obj'),
Argument('*const %s' % descriptor.concreteType, 'this'),
@ -2880,7 +2885,10 @@ class CGSpecializedGetter(CGAbstractExternMethod):
@staticmethod
def makeNativeName(descriptor, attr):
name = attr.identifier.name
nativeName = MakeNativeName(descriptor.binaryNameFor(name))
nativeName = descriptor.binaryNameFor(name)
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
nativeName = MakeNativeName(nativeName)
infallible = ('infallible' in
descriptor.getExtendedAttributes(attr, getter=True))
if attr.type.nullable() or not infallible:
@ -2901,7 +2909,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod):
def generate_code(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
self.attr)
setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n")
setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
call = CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
self.attr)
return CGList([setupArgs, call])
@ -2914,7 +2922,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
"""
def __init__(self, descriptor, attr):
self.attr = attr
name = 'set_' + attr.identifier.name
name = 'set_' + descriptor.internalNameFor(attr.identifier.name)
args = [Argument('*mut JSContext', 'cx'),
Argument('HandleObject', 'obj'),
Argument('*const %s' % descriptor.concreteType, 'this'),
@ -2931,7 +2939,10 @@ class CGSpecializedSetter(CGAbstractExternMethod):
@staticmethod
def makeNativeName(descriptor, attr):
name = attr.identifier.name
return "Set" + MakeNativeName(descriptor.binaryNameFor(name))
nativeName = descriptor.binaryNameFor(name)
if nativeName == name:
nativeName = descriptor.internalNameFor(name)
return "Set" + MakeNativeName(nativeName)
class CGStaticSetter(CGAbstractStaticBindingMethod):
@ -2948,9 +2959,9 @@ class CGStaticSetter(CGAbstractStaticBindingMethod):
self.attr)
checkForArg = CGGeneric(
"let args = CallArgs::from_vp(vp, argc);\n"
"if (argc == 0) {\n"
"if argc == 0 {\n"
" throw_type_error(cx, \"Not enough arguments to %s setter.\");\n"
" return 0;\n"
" return JSFalse;\n"
"}" % self.attr.identifier.name)
call = CGSetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
self.attr)
@ -3045,8 +3056,9 @@ class CGMemberJITInfo(CGThing):
def define(self):
if self.member.isAttr():
getterinfo = ("%s_getterinfo" % self.member.identifier.name)
getter = ("get_%s" % self.member.identifier.name)
internalMemberName = self.descriptor.internalNameFor(self.member.identifier.name)
getterinfo = ("%s_getterinfo" % internalMemberName)
getter = ("get_%s" % internalMemberName)
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
movable = self.mayBeMovable() and getterinfal
@ -3070,8 +3082,8 @@ class CGMemberJITInfo(CGThing):
slotIndex,
[self.member.type], None)
if (not self.member.readonly or self.member.getExtendedAttribute("PutForwards")):
setterinfo = ("%s_setterinfo" % self.member.identifier.name)
setter = ("set_%s" % self.member.identifier.name)
setterinfo = ("%s_setterinfo" % internalMemberName)
setter = ("set_%s" % internalMemberName)
# Setters are always fallible, since they have to do a typed unwrap.
result += self.defineJitInfo(setterinfo, setter, "Setter",
False, False, "AliasEverything",
@ -3966,7 +3978,23 @@ class CGProxyIndexedSetter(CGProxySpecialOperation):
CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')
class CGProxyNamedGetter(CGProxySpecialOperation):
class CGProxyNamedOperation(CGProxySpecialOperation):
"""
Class to generate a call to a named operation.
"""
def __init__(self, descriptor, name):
CGProxySpecialOperation.__init__(self, descriptor, name)
def define(self):
# Our first argument is the id we're getting.
argName = self.arguments[0].identifier.name
return ("let %s = jsid_to_str(cx, id);\n"
"let this = UnwrapProxy(proxy);\n"
"let this = &*this;\n" % argName +
CGProxySpecialOperation.define(self))
class CGProxyNamedGetter(CGProxyNamedOperation):
"""
Class to generate a call to an named getter. If templateValues is not None
the returned value will be wrapped with wrapForType using templateValues.
@ -3976,7 +4004,16 @@ class CGProxyNamedGetter(CGProxySpecialOperation):
CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')
class CGProxyNamedSetter(CGProxySpecialOperation):
class CGProxyNamedPresenceChecker(CGProxyNamedGetter):
"""
Class to generate a call that checks whether a named property exists.
For now, we just delegate to CGProxyNamedGetter
"""
def __init__(self, descriptor):
CGProxyNamedGetter.__init__(self, descriptor)
class CGProxyNamedSetter(CGProxyNamedOperation):
"""
Class to generate a call to a named setter.
"""
@ -3984,7 +4021,7 @@ class CGProxyNamedSetter(CGProxySpecialOperation):
CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')
class CGProxyNamedDeleter(CGProxySpecialOperation):
class CGProxyNamedDeleter(CGProxyNamedOperation):
"""
Class to generate a call to a named deleter.
"""
@ -3996,7 +4033,8 @@ class CGProxyUnwrap(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('HandleObject', 'obj')]
CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy",
'*const ' + descriptor.concreteType, args, alwaysInline=True)
'*const ' + descriptor.concreteType, args,
alwaysInline=True, unsafe=True)
def definition_body(self):
return CGGeneric("""\
@ -4057,9 +4095,6 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
# properties that shadow prototype properties.
namedGet = ("\n" +
"if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
"}\n")
else:
@ -4121,9 +4156,6 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
if not self.descriptor.operations['NamedCreator'] is namedSetter:
raise TypeError("Can't handle creator that's different from the setter")
set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" +
CGIndenter(CGProxyNamedSetter(self.descriptor)).define() +
" (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" +
" return JSTrue;\n" +
@ -4132,9 +4164,6 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
"}\n")
else:
set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
" if (found) {\n"
# TODO(Issue 5876)
@ -4165,10 +4194,7 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod):
def getBody(self):
set = ""
if self.descriptor.operations['NamedDeleter']:
set += ("let name = jsid_to_str(cx, id);\n" +
"let this = UnwrapProxy(proxy);\n" +
"let this = &*this;\n" +
"%s") % (CGProxyNamedDeleter(self.descriptor).define())
set += CGProxyNamedDeleter(self.descriptor).define()
set += "return proxyhandler::delete(%s) as u8;" % ", ".join(a.name for a in self.args)
return set
@ -4205,7 +4231,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod):
for name in (*unwrapped_proxy).SupportedPropertyNames() {
let cstring = CString::new(name).unwrap();
let jsstring = JS_InternString(cx, cstring.as_ptr());
let mut rooted = RootedString::new(cx, jsstring);
let rooted = RootedString::new(cx, jsstring);
let jsid = INTERNED_STRING_TO_JSID(cx, rooted.handle().get());
let rooted_jsid = RootedId::new(cx, jsid);
AppendToAutoIdVector(props, rooted_jsid.handle().get());
@ -4253,9 +4279,6 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
namedGetter = self.descriptor.operations['NamedGetter']
if namedGetter:
named = ("if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
" *bp = found as u8;\n"
" return JSTrue;\n"
@ -4328,10 +4351,7 @@ if !expando.ptr.is_null() {
namedGetter = self.descriptor.operations['NamedGetter']
if namedGetter:
getNamed = ("if (RUST_JSID_IS_STRING(id) != 0) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
" let this = &*this;\n" +
getNamed = ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
"}\n")
else:
@ -4564,7 +4584,7 @@ class CGInterfaceTrait(CGThing):
return "".join(", %s: %s" % argument for argument in arguments)
methods = [
CGGeneric("fn %s(self%s) -> %s;\n" % (name, fmt(arguments), rettype))
CGGeneric("fn %s(&self%s) -> %s;\n" % (name, fmt(arguments), rettype))
for name, arguments, rettype in members()
]
if methods:
@ -5499,7 +5519,7 @@ class CallbackMember(CGNativeMember):
conversion = (
CGIfWrapper(CGGeneric(conversion),
"%s.is_some()" % arg.identifier.name).define() +
" else if (argc == %d) {\n"
" else if argc == %d {\n"
" // This is our current trailing argument; reduce argc\n"
" argc -= 1;\n"
"} else {\n"
@ -5532,6 +5552,8 @@ class CallbackMember(CGNativeMember):
"}\n")
def getArgcDecl(self):
if self.argCount <= 1:
return CGGeneric("let argc = %s;" % self.argCountStr)
return CGGeneric("let mut argc = %s;" % self.argCountStr)
@staticmethod
@ -5773,12 +5795,17 @@ class GlobalGenRoots():
CGGeneric("use std::mem;\n\n")]
for descriptor in descriptors:
name = descriptor.name
protos = [CGGeneric('pub trait %s : Sized {}\n' % (name + 'Base'))]
protos = [CGGeneric("""\
/// Types which are derived from `%(name)s` and can be freely converted
/// to `%(name)s`
pub trait %(name)sBase : Sized {}\n""" % {'name': name})]
for proto in descriptor.prototypeChain:
protos += [CGGeneric('impl %s for %s {}\n' % (proto + 'Base',
descriptor.concreteType))]
derived = [CGGeneric('pub trait %s : Sized { fn %s(&self) -> bool; }\n' %
(name + 'Derived', 'is_' + name.lower()))]
derived = [CGGeneric("""\
/// Types which `%(name)s` derives from
pub trait %(name)sDerived : Sized { fn %(method)s(&self) -> bool; }\n""" %
{'name': name, 'method': 'is_' + name.lower()})]
for protoName in descriptor.prototypeChain[1:-1]:
protoDescriptor = config.getDescriptor(protoName)
delegate = string.Template("""\
@ -5800,6 +5827,8 @@ impl ${selfName} for ${baseName} {
pub struct ${name}Cast;
impl ${name}Cast {
#[inline]
/// Downcast an instance of a base class of `${name}` to an instance of
/// `${name}`, if it internally is an instance of `${name}`
pub fn to_ref<'a, T: ${toBound}+Reflectable>(base: &'a T) -> Option<&'a ${name}> {
match base.${checkFn}() {
true => Some(unsafe { mem::transmute(base) }),
@ -5807,14 +5836,6 @@ impl ${name}Cast {
}
}
#[inline]
pub fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a &'b T) -> Option<&'a &'b ${name}> {
match base.${checkFn}() {
true => Some(unsafe { mem::transmute(base) }),
false => None
}
}
#[inline]
#[allow(unrooted_must_root)]
pub fn to_layout_js<T: ${toBound}+Reflectable>(base: &LayoutJS<T>) -> Option<LayoutJS<${name}>> {
@ -5835,15 +5856,11 @@ impl ${name}Cast {
}
#[inline]
/// Upcast an instance of a derived class of `${name}` to `${name}`
pub fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: &'a T) -> &'a ${name} {
unsafe { mem::transmute(derived) }
}
#[inline]
pub fn from_borrowed_ref<'a, 'b, T: ${fromBound}+Reflectable>(derived: &'a &'b T) -> &'a &'b ${name} {
unsafe { mem::transmute(derived) }
}
#[inline]
#[allow(unrooted_must_root)]
pub fn from_layout_js<T: ${fromBound}+Reflectable>(derived: &LayoutJS<T>) -> LayoutJS<${name}> {

View file

@ -263,6 +263,8 @@ class Descriptor(DescriptorProvider):
self._binaryNames.setdefault('__legacycaller', 'LegacyCall')
self._binaryNames.setdefault('__stringifier', 'Stringifier')
self._internalNames = desc.get('internalNames', {})
for member in self.interface.members:
if not member.isAttr() and not member.isMethod():
continue
@ -272,6 +274,8 @@ class Descriptor(DescriptorProvider):
assert len(binaryName) == 1
self._binaryNames.setdefault(member.identifier.name,
binaryName[0])
self._internalNames.setdefault(member.identifier.name,
member.identifier.name.replace('-', '_'))
# Build the prototype chain.
self.prototypeChain = []
@ -285,6 +289,9 @@ class Descriptor(DescriptorProvider):
def binaryNameFor(self, name):
return self._binaryNames.get(name, name)
def internalNameFor(self, name):
return self._internalNames.get(name, name)
def getExtendedAttributes(self, member, getter=False, setter=False):
def maybeAppendInfallibleToAttrs(attrs, throws):
if throws is None:

View file

@ -12,9 +12,8 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::native_from_reflector_jsmanaged;
use dom::bindings::js::{JS, Root};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::DocumentHelpers;
use dom::window::{self, WindowHelpers, ScriptHelpers};
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
use dom::window::{self, ScriptHelpers};
use dom::workerglobalscope::WorkerGlobalScope;
use script_task::{ScriptChan, ScriptPort, CommonScriptMsg, ScriptTask};
use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};

View file

@ -207,6 +207,7 @@ impl MutHeapJSVal {
/// `JS<T>`.
#[must_root]
#[derive(JSTraceable)]
#[derive(HeapSizeOf)]
pub struct MutHeap<T: HeapGCValue + Copy> {
val: Cell<T>,
}
@ -433,11 +434,6 @@ impl<T: Reflectable> Root<T> {
&**self
}
/// Don't use this. Don't make me find you.
pub fn get_unsound_ref_forever<'a, 'b>(&'a self) -> &'b T {
unsafe { &**self.ptr }
}
/// Generate a new root from a JS<T> reference
#[allow(unrooted_must_root)]
pub fn from_rooted(js: JS<T>) -> Root<T> {

View file

@ -168,15 +168,13 @@ pub mod codegen {
pub mod PrototypeList {
include!(concat!(env!("OUT_DIR"), "/PrototypeList.rs"));
}
#[allow(unreachable_code, non_camel_case_types, non_upper_case_globals, unused_parens,
unused_imports, unused_variables, unused_unsafe, unused_mut, unused_assignments,
dead_code)]
#[allow(non_camel_case_types, non_upper_case_globals,
unused_imports, unused_variables, unused_assignments)]
pub mod RegisterBindings {
include!(concat!(env!("OUT_DIR"), "/RegisterBindings.rs"));
}
#[allow(unreachable_code, non_camel_case_types, non_upper_case_globals, unused_parens,
unused_imports, unused_variables, unused_unsafe, unused_mut, unused_assignments,
dead_code)]
#[allow(non_camel_case_types, non_upper_case_globals,
unused_imports, unused_variables, unused_assignments)]
pub mod UnionTypes {
include!(concat!(env!("OUT_DIR"), "/UnionTypes.rs"));
}

View file

@ -29,7 +29,7 @@
//! The `no_jsmanaged_fields!()` macro adds an empty implementation of `JSTraceable` to
//! a datatype.
use dom::bindings::js::JS;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::Trusted;
use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
use script_task::ScriptChan;
@ -69,6 +69,7 @@ use std::collections::{HashMap, HashSet};
use std::ffi::CString;
use std::hash::{Hash, Hasher};
use std::intrinsics::return_address;
use std::iter::{FromIterator, IntoIterator};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
@ -511,6 +512,17 @@ impl<T: JSTraceable + Reflectable> DerefMut for RootedVec<T> {
}
}
impl<A: JSTraceable + Reflectable> FromIterator<Root<A>> for RootedVec<JS<A>> {
#[allow(moved_no_move)]
fn from_iter<T>(iterable: T) -> RootedVec<JS<A>> where T: IntoIterator<Item=Root<A>> {
let mut vec = RootedVec::new_with_destination_address(unsafe {
return_address() as *const libc::c_void
});
vec.extend(iterable.into_iter().map(|item| JS::from_rooted(&item)));
vec
}
}
/// SM Callback that traces the rooted traceables
pub unsafe fn trace_traceables(tracer: *mut JSTracer) {
ROOTED_TRACEABLES.with(|ref traceables| {

View file

@ -25,7 +25,6 @@ pub enum BlobTypeId {
// http://dev.w3.org/2006/webapi/FileAPI/#blob
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Blob {
reflector_: Reflector,
type_: BlobTypeId,
@ -78,21 +77,15 @@ impl Blob {
};
Ok(Blob::new(global, bytes, &typeString.to_ascii_lowercase()))
}
}
pub trait BlobHelpers {
fn read_out_buffer(self, send: Sender<Vec<u8>>);
}
impl<'a> BlobHelpers for &'a Blob {
fn read_out_buffer(self, send: Sender<Vec<u8>>) {
pub fn read_out_buffer(&self, send: Sender<Vec<u8>>) {
send.send(self.bytes.clone().unwrap_or(vec![])).unwrap();
}
}
impl<'a> BlobMethods for &'a Blob {
impl BlobMethods for Blob {
// https://dev.w3.org/2006/webapi/FileAPI/#dfn-size
fn Size(self) -> u64 {
fn Size(&self) -> u64 {
match self.bytes {
None => 0,
Some(ref bytes) => bytes.len() as u64
@ -100,12 +93,12 @@ impl<'a> BlobMethods for &'a Blob {
}
// https://dev.w3.org/2006/webapi/FileAPI/#dfn-type
fn Type(self) -> DOMString {
fn Type(&self) -> DOMString {
self.typeString.clone()
}
// https://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>) -> Root<Blob> {
let size: i64 = self.Size().to_i64().unwrap();
let relativeStart: i64 = match start {
@ -153,12 +146,12 @@ impl<'a> BlobMethods for &'a Blob {
}
// https://dev.w3.org/2006/webapi/FileAPI/#dfn-isClosed
fn IsClosed(self) -> bool {
fn IsClosed(&self) -> bool {
self.isClosed_.get()
}
// https://dev.w3.org/2006/webapi/FileAPI/#dfn-close
fn Close(self) {
fn Close(&self) {
// Step 1
if self.isClosed_.get() {
return;

View file

@ -8,10 +8,9 @@ use dom::bindings::js::{JS, Root};
use dom::bindings::proxyhandler::{get_property_descriptor, fill_property_descriptor};
use dom::bindings::utils::get_array_index_from_id;
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
use dom::document::{Document, DocumentHelpers};
use dom::document::Document;
use dom::element::Element;
use dom::window::Window;
use dom::window::WindowHelpers;
use js::glue::{GetProxyPrivate};
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};

View file

@ -16,7 +16,6 @@ use dom::canvasrenderingcontext2d::parse_color;
// https://html.spec.whatwg.org/multipage/#canvasgradient
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CanvasGradient {
reflector_: Reflector,
style: CanvasGradientStyle,
@ -44,9 +43,9 @@ impl CanvasGradient {
}
}
impl<'a> CanvasGradientMethods for &'a CanvasGradient {
impl CanvasGradientMethods for CanvasGradient {
// https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
fn AddColorStop(self, offset: Finite<f64>, color: String) -> ErrorResult {
fn AddColorStop(&self, offset: Finite<f64>, color: String) -> ErrorResult {
if *offset < 0f64 || *offset > 1f64 {
return Err(IndexSize);
}

View file

@ -12,7 +12,6 @@ use euclid::size::Size2D;
// https://html.spec.whatwg.org/multipage/#canvaspattern
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CanvasPattern {
reflector_: Reflector,
surface_data: Vec<u8>,

View file

@ -17,11 +17,11 @@ use dom::bindings::num::Finite;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
use dom::canvaspattern::CanvasPattern;
use dom::htmlcanvaselement::HTMLCanvasElement;
use dom::htmlcanvaselement::utils as canvas_utils;
use dom::htmlcanvaselement::{HTMLCanvasElement, HTMLCanvasElementHelpers};
use dom::htmlimageelement::{HTMLImageElement, HTMLImageElementHelpers};
use dom::imagedata::{ImageData, ImageDataHelpers};
use dom::node::{window_from_node, NodeHelpers, NodeDamage};
use dom::htmlimageelement::HTMLImageElement;
use dom::imagedata::ImageData;
use dom::node::{window_from_node, NodeDamage};
use msg::constellation_msg::Msg as ConstellationMsg;
use net_traits::image::base::PixelFormat;
@ -61,7 +61,6 @@ pub enum CanvasFillOrStrokeStyle {
// https://html.spec.whatwg.org/multipage/#canvasrenderingcontext2d
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CanvasRenderingContext2D {
reflector_: Reflector,
global: GlobalField,
@ -408,18 +407,11 @@ impl CanvasRenderingContext2D {
Some(Rect::new(Point2D::new(x as f32, y as f32), Size2D::new(w as f32, h as f32)))
}
}
pub trait CanvasRenderingContext2DHelpers {
fn get_renderer_id(self) -> usize;
fn get_ipc_renderer(self) -> IpcSender<CanvasMsg>;
}
impl<'a> CanvasRenderingContext2DHelpers for &'a CanvasRenderingContext2D {
fn get_renderer_id(self) -> usize {
pub fn get_renderer_id(&self) -> usize {
self.renderer_id
}
fn get_ipc_renderer(self) -> IpcSender<CanvasMsg> {
pub fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
self.ipc_renderer.clone()
}
}
@ -451,20 +443,20 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D
// 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.
impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-canvas
fn Canvas(self) -> Root<HTMLCanvasElement> {
fn Canvas(&self) -> Root<HTMLCanvasElement> {
self.canvas.root()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save
fn Save(self) {
fn Save(&self) {
self.saved_states.borrow_mut().push(self.state.borrow().clone());
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
fn Restore(self) {
fn Restore(&self) {
let mut saved_states = self.saved_states.borrow_mut();
if let Some(state) = saved_states.pop() {
self.state.borrow_mut().clone_from(&state);
@ -473,7 +465,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-scale
fn Scale(self, x: f64, y: f64) {
fn Scale(&self, x: f64, y: f64) {
if !(x.is_finite() && y.is_finite()) {
return;
}
@ -484,7 +476,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-rotate
fn Rotate(self, angle: f64) {
fn Rotate(&self, angle: f64) {
if angle == 0.0 || !angle.is_finite() {
return;
}
@ -498,7 +490,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-translate
fn Translate(self, x: f64, y: f64) {
fn Translate(&self, x: f64, y: f64) {
if !(x.is_finite() && y.is_finite()) {
return;
}
@ -509,7 +501,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-transform
fn Transform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
fn Transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
if !(a.is_finite() && b.is_finite() && c.is_finite() &&
d.is_finite() && e.is_finite() && f.is_finite()) {
return;
@ -526,7 +518,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform
fn SetTransform(self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
fn SetTransform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
if !(a.is_finite() && b.is_finite() && c.is_finite() &&
d.is_finite() && e.is_finite() && f.is_finite()) {
return;
@ -542,19 +534,19 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-resettransform
fn ResetTransform(self) {
fn ResetTransform(&self) {
self.state.borrow_mut().transform = Matrix2D::identity();
self.update_transform()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
fn GlobalAlpha(self) -> f64 {
fn GlobalAlpha(&self) -> f64 {
let state = self.state.borrow();
state.global_alpha
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
fn SetGlobalAlpha(self, alpha: f64) {
fn SetGlobalAlpha(&self, alpha: f64) {
if !alpha.is_finite() || alpha > 1.0 || alpha < 0.0 {
return;
}
@ -566,7 +558,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
fn GlobalCompositeOperation(self) -> DOMString {
fn GlobalCompositeOperation(&self) -> DOMString {
let state = self.state.borrow();
match state.global_composition {
CompositionOrBlending::Composition(op) => op.to_str().to_owned(),
@ -575,7 +567,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
fn SetGlobalCompositeOperation(self, op_str: DOMString) {
fn SetGlobalCompositeOperation(&self, op_str: DOMString) {
if let Some(op) = CompositionOrBlending::from_str(&op_str) {
self.state.borrow_mut().global_composition = op;
self.ipc_renderer
@ -585,7 +577,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fillrect
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
fn FillRect(&self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::FillRect(rect))).unwrap();
self.mark_as_dirty();
@ -593,7 +585,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clearrect
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
fn ClearRect(&self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClearRect(rect)))
@ -603,7 +595,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokerect
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
fn StrokeRect(&self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
self.ipc_renderer
.send(CanvasMsg::Canvas2d(Canvas2dMsg::StrokeRect(rect)))
@ -613,36 +605,36 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beginpath
fn BeginPath(self) {
fn BeginPath(&self) {
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::BeginPath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath
fn ClosePath(self) {
fn ClosePath(&self) {
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClosePath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
fn Fill(self, _: CanvasWindingRule) {
fn Fill(&self, _: CanvasWindingRule) {
// TODO: Process winding rule
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Fill)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-stroke
fn Stroke(self) {
fn Stroke(&self) {
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Stroke)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
fn Clip(self, _: CanvasWindingRule) {
fn Clip(&self, _: CanvasWindingRule) {
// TODO: Process winding rule
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Clip)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
fn DrawImage(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
fn DrawImage(&self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
dx: f64, dy: f64) -> Fallible<()> {
if !(dx.is_finite() && dy.is_finite()) {
return Ok(());
@ -652,7 +644,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
fn DrawImage_(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
fn DrawImage_(&self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
if !(dx.is_finite() && dy.is_finite() &&
dw.is_finite() && dh.is_finite()) {
@ -663,7 +655,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
fn DrawImage__(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
fn DrawImage__(&self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
sx: f64, sy: f64, sw: f64, sh: f64,
dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> {
if !(sx.is_finite() && sy.is_finite() && sw.is_finite() && sh.is_finite() &&
@ -675,7 +667,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-moveto
fn MoveTo(self, x: f64, y: f64) {
fn MoveTo(&self, x: f64, y: f64) {
if !(x.is_finite() && y.is_finite()) {
return;
}
@ -687,7 +679,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-lineto
fn LineTo(self, x: f64, y: f64) {
fn LineTo(&self, x: f64, y: f64) {
if !(x.is_finite() && y.is_finite()) {
return;
}
@ -699,7 +691,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-rect
fn Rect(self, x: f64, y: f64, width: f64, height: f64) {
fn Rect(&self, x: f64, y: f64, width: f64, height: f64) {
if [x, y, width, height].iter().all(|val| val.is_finite()) {
let rect = Rect::new(Point2D::new(x as f32, y as f32),
Size2D::new(width as f32, height as f32));
@ -709,7 +701,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-quadraticcurveto
fn QuadraticCurveTo(self, cpx: f64, cpy: f64, x: f64, y: f64) {
fn QuadraticCurveTo(&self, cpx: f64, cpy: f64, x: f64, y: f64) {
if !(cpx.is_finite() && cpy.is_finite() &&
x.is_finite() && y.is_finite()) {
return;
@ -723,7 +715,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beziercurveto
fn BezierCurveTo(self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
fn BezierCurveTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
if !(cp1x.is_finite() && cp1y.is_finite() && cp2x.is_finite() && cp2y.is_finite() &&
x.is_finite() && y.is_finite()) {
return;
@ -738,7 +730,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arc
fn Arc(self, x: f64, y: f64, r: f64,
fn Arc(&self, x: f64, y: f64, r: f64,
start: f64, end: f64, ccw: bool) -> Fallible<()> {
if !([x, y, r, start, end].iter().all(|x| x.is_finite())) {
return Ok(());
@ -758,7 +750,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arcto
fn ArcTo(self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, r: f64) -> Fallible<()> {
fn ArcTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, r: f64) -> Fallible<()> {
if !([cp1x, cp1y, cp2x, cp2y, r].iter().all(|x| x.is_finite())) {
return Ok(());
}
@ -776,18 +768,18 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled
fn ImageSmoothingEnabled(self) -> bool {
fn ImageSmoothingEnabled(&self) -> bool {
let state = self.state.borrow();
state.image_smoothing_enabled
}
// https://html.spec.whatwg.org/#dom-context-2d-imagesmoothingenabled
fn SetImageSmoothingEnabled(self, value: bool) -> () {
fn SetImageSmoothingEnabled(&self, value: bool) -> () {
self.state.borrow_mut().image_smoothing_enabled = value;
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
fn StrokeStyle(self) -> StringOrCanvasGradientOrCanvasPattern {
fn StrokeStyle(&self) -> StringOrCanvasGradientOrCanvasPattern {
match self.state.borrow().stroke_style {
CanvasFillOrStrokeStyle::Color(ref rgba) => {
let mut result = String::new();
@ -801,7 +793,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
fn SetStrokeStyle(self, value: StringOrCanvasGradientOrCanvasPattern) {
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
match value {
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
match parse_color(&string) {
@ -827,7 +819,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
fn FillStyle(self) -> StringOrCanvasGradientOrCanvasPattern {
fn FillStyle(&self) -> StringOrCanvasGradientOrCanvasPattern {
match self.state.borrow().fill_style {
CanvasFillOrStrokeStyle::Color(ref rgba) => {
let mut result = String::new();
@ -841,7 +833,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
fn SetFillStyle(self, value: StringOrCanvasGradientOrCanvasPattern) {
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
match value {
StringOrCanvasGradientOrCanvasPattern::eString(string) => {
if let Ok(rgba) = parse_color(&string) {
@ -867,7 +859,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
fn CreateImageData(self, sw: Finite<f64>, sh: Finite<f64>) -> Fallible<Root<ImageData>> {
fn CreateImageData(&self, sw: Finite<f64>, sh: Finite<f64>) -> Fallible<Root<ImageData>> {
if *sw == 0.0 || *sh == 0.0 {
return Err(IndexSize)
}
@ -878,12 +870,12 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
fn CreateImageData_(self, imagedata: &ImageData) -> Fallible<Root<ImageData>> {
fn CreateImageData_(&self, imagedata: &ImageData) -> Fallible<Root<ImageData>> {
Ok(ImageData::new(self.global.root().r(), imagedata.Width(), imagedata.Height(), None))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
fn GetImageData(self,
fn GetImageData(&self,
sx: Finite<f64>,
sy: Finite<f64>,
sw: Finite<f64>,
@ -933,13 +925,13 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData(self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>) {
fn PutImageData(&self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>) {
self.PutImageData_(imagedata, dx, dy, Finite::wrap(0f64), Finite::wrap(0f64),
Finite::wrap(imagedata.Width() as f64), Finite::wrap(imagedata.Height() as f64))
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
fn PutImageData_(self, imagedata: &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>) {
let data = imagedata.get_data_array(&self.global.root().r());
let offset = Point2D::new(*dx, *dy);
@ -954,14 +946,14 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// 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>) -> Root<CanvasGradient> {
CanvasGradient::new(self.global.root().r(),
CanvasGradientStyle::Linear(LinearGradientStyle::new(*x0, *y0, *x1, *y1, Vec::new())))
}
// 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>)
-> Fallible<Root<CanvasGradient>> {
if *r0 < 0. || *r1 < 0. {
@ -974,7 +966,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
fn CreatePattern(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
fn CreatePattern(&self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
repetition: DOMString) -> Fallible<Root<CanvasPattern>> {
let (image_data, image_size) = match image {
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
@ -1024,13 +1016,13 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
fn LineWidth(self) -> f64 {
fn LineWidth(&self) -> f64 {
let state = self.state.borrow();
state.line_width
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
fn SetLineWidth(self, width: f64) {
fn SetLineWidth(&self, width: f64) {
if !width.is_finite() || width <= 0.0 {
return;
}
@ -1042,7 +1034,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
fn LineCap(self) -> DOMString {
fn LineCap(&self) -> DOMString {
let state = self.state.borrow();
match state.line_cap {
LineCapStyle::Butt => "butt".to_owned(),
@ -1052,7 +1044,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
fn SetLineCap(self, cap_str: DOMString) {
fn SetLineCap(&self, cap_str: DOMString) {
if let Some(cap) = LineCapStyle::from_str(&cap_str) {
self.state.borrow_mut().line_cap = cap;
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineCap(cap))).unwrap()
@ -1060,7 +1052,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
fn LineJoin(self) -> DOMString {
fn LineJoin(&self) -> DOMString {
let state = self.state.borrow();
match state.line_join {
LineJoinStyle::Round => "round".to_owned(),
@ -1070,7 +1062,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
fn SetLineJoin(self, join_str: DOMString) {
fn SetLineJoin(&self, join_str: DOMString) {
if let Some(join) = LineJoinStyle::from_str(&join_str) {
self.state.borrow_mut().line_join = join;
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineJoin(join))).unwrap()
@ -1078,13 +1070,13 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
fn MiterLimit(self) -> f64 {
fn MiterLimit(&self) -> f64 {
let state = self.state.borrow();
state.miter_limit
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
fn SetMiterLimit(self, limit: f64) {
fn SetMiterLimit(&self, limit: f64) {
if !limit.is_finite() || limit <= 0.0 {
return;
}
@ -1096,12 +1088,12 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
fn ShadowOffsetX(self) -> f64 {
fn ShadowOffsetX(&self) -> f64 {
self.state.borrow().shadow_offset_x
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
fn SetShadowOffsetX(self, value: f64) {
fn SetShadowOffsetX(&self, value: f64) {
if !value.is_finite() || value == self.state.borrow().shadow_offset_x {
return;
}
@ -1110,12 +1102,12 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
fn ShadowOffsetY(self) -> f64 {
fn ShadowOffsetY(&self) -> f64 {
self.state.borrow().shadow_offset_y
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
fn SetShadowOffsetY(self, value: f64) {
fn SetShadowOffsetY(&self, value: f64) {
if !value.is_finite() || value == self.state.borrow().shadow_offset_y {
return;
}
@ -1124,12 +1116,12 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
fn ShadowBlur(self) -> f64 {
fn ShadowBlur(&self) -> f64 {
self.state.borrow().shadow_blur
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
fn SetShadowBlur(self, value: f64) {
fn SetShadowBlur(&self, value: f64) {
if !value.is_finite() || value < 0f64 || value == self.state.borrow().shadow_blur {
return;
}
@ -1138,14 +1130,14 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
fn ShadowColor(self) -> DOMString {
fn ShadowColor(&self) -> DOMString {
let mut result = String::new();
serialize(&self.state.borrow().shadow_color, &mut result).unwrap();
result
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
fn SetShadowColor(self, value: DOMString) {
fn SetShadowColor(&self, value: DOMString) {
if let Ok(color) = parse_color(&value) {
self.state.borrow_mut().shadow_color = color;
self.ipc_renderer

View file

@ -15,16 +15,15 @@ use dom::bindings::js::{LayoutJS, Root};
use dom::document::Document;
use dom::element::Element;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId};
use dom::node::{Node, NodeTypeId};
use util::str::{DOMString, slice_chars};
use util::str::DOMString;
use std::borrow::ToOwned;
use std::cell::Ref;
// https://dom.spec.whatwg.org/#characterdata
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CharacterData {
node: Node,
data: DOMRefCell<DOMString>,
@ -48,103 +47,111 @@ impl CharacterData {
}
}
impl<'a> CharacterDataMethods for &'a CharacterData {
impl CharacterDataMethods for CharacterData {
// https://dom.spec.whatwg.org/#dom-characterdata-data
fn Data(self) -> DOMString {
fn Data(&self) -> DOMString {
self.data.borrow().clone()
}
// https://dom.spec.whatwg.org/#dom-characterdata-data
fn SetData(self, data: DOMString) {
fn SetData(&self, data: DOMString) {
*self.data.borrow_mut() = data;
}
// https://dom.spec.whatwg.org/#dom-characterdata-length
fn Length(self) -> u32 {
self.data.borrow().chars().count() as u32
fn Length(&self) -> u32 {
self.data.borrow().chars().map(|c| c.len_utf16()).sum::<usize>() as u32
}
// https://dom.spec.whatwg.org/#dom-characterdata-substringdataoffset-count
fn SubstringData(self, offset: u32, count: u32) -> Fallible<DOMString> {
// https://dom.spec.whatwg.org/#dom-characterdata-substringdata
fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString> {
let data = self.data.borrow();
// Step 1.
let length = data.chars().count() as u32;
if offset > length {
let data_from_offset = match find_utf16_code_unit_offset(&data, offset) {
Some(offset_bytes) => &data[offset_bytes..],
// Step 2.
return Err(IndexSize);
}
// Steps 3-4.
let end = if length - offset < count { length } else { offset + count };
Ok(slice_chars(&*data, offset as usize, end as usize).to_owned())
None => return Err(IndexSize)
};
let substring = match find_utf16_code_unit_offset(data_from_offset, count) {
// Steps 3.
None => data_from_offset,
// Steps 4.
Some(count_bytes) => &data_from_offset[..count_bytes],
};
Ok(substring.to_owned())
}
// https://dom.spec.whatwg.org/#dom-characterdata-appenddatadata
fn AppendData(self, data: DOMString) {
fn AppendData(&self, data: DOMString) {
self.append_data(&*data);
}
// https://dom.spec.whatwg.org/#dom-characterdata-insertdataoffset-data
fn InsertData(self, offset: u32, arg: DOMString) -> ErrorResult {
fn InsertData(&self, offset: u32, arg: DOMString) -> ErrorResult {
self.ReplaceData(offset, 0, arg)
}
// https://dom.spec.whatwg.org/#dom-characterdata-deletedataoffset-count
fn DeleteData(self, offset: u32, count: u32) -> ErrorResult {
fn DeleteData(&self, offset: u32, count: u32) -> ErrorResult {
self.ReplaceData(offset, count, "".to_owned())
}
// https://dom.spec.whatwg.org/#dom-characterdata-replacedataoffset-count-data
fn ReplaceData(self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
// Step 1.
let length = self.data.borrow().chars().count() as u32;
if offset > length {
// https://dom.spec.whatwg.org/#dom-characterdata-replacedata
fn ReplaceData(&self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
let new_data = {
let data = self.data.borrow();
let (prefix, data_from_offset) = match find_utf16_code_unit_offset(&data, offset) {
Some(offset_bytes) => data.split_at(offset_bytes),
// Step 2.
return Err(IndexSize);
}
// Step 3.
let count = match length - offset {
diff if diff < count => diff,
_ => count,
None => return Err(IndexSize)
};
let suffix = match find_utf16_code_unit_offset(data_from_offset, count) {
// Steps 3.
None => "",
Some(count_bytes) => &data_from_offset[count_bytes..],
};
// Step 4: Mutation observers.
// Step 5.
let mut data = slice_chars(&*self.data.borrow(), 0, offset as usize).to_owned();
data.push_str(&arg);
data.push_str(slice_chars(&*self.data.borrow(), (offset + count) as usize, length as usize));
*self.data.borrow_mut() = data;
// FIXME: Once we have `Range`, we should implement step7 to step11
// Step 5 to 7.
let mut new_data = String::with_capacity(prefix.len() + arg.len() + suffix.len());
new_data.push_str(prefix);
new_data.push_str(&arg);
new_data.push_str(suffix);
new_data
};
*self.data.borrow_mut() = new_data;
// FIXME: Once we have `Range`, we should implement step 8 to step 11
Ok(())
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).before(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-after
fn After(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).after(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).replace_with(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-remove
fn Remove(self) {
fn Remove(&self) {
let node = NodeCast::from_ref(self);
node.remove_self();
}
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
fn GetPreviousElementSibling(self) -> Option<Root<Element>> {
fn GetPreviousElementSibling(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).preceding_siblings()
.filter_map(ElementCast::to_root).next()
}
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
fn GetNextElementSibling(self) -> Option<Root<Element>> {
fn GetNextElementSibling(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).following_siblings()
.filter_map(ElementCast::to_root).next()
}
@ -158,18 +165,14 @@ pub enum CharacterDataTypeId {
ProcessingInstruction,
}
pub trait CharacterDataHelpers<'a> {
fn data(self) -> Ref<'a, DOMString>;
fn append_data(self, data: &str);
}
impl<'a> CharacterDataHelpers<'a> for &'a CharacterData {
impl CharacterData {
#[inline]
fn data(self) -> Ref<'a, DOMString> {
pub fn data(&self) -> Ref<DOMString> {
self.data.borrow()
}
#[inline]
fn append_data(self, data: &str) {
pub fn append_data(&self, data: &str) {
self.data.borrow_mut().push_str(data)
}
}
@ -186,3 +189,32 @@ impl LayoutCharacterDataHelpers for LayoutJS<CharacterData> {
&(*self.unsafe_get()).data.borrow_for_layout()
}
}
/// Given a number of UTF-16 code units from the start of the given string,
/// return the corresponding number of UTF-8 bytes.
///
/// s[find_utf16_code_unit_offset(s, o).unwrap()..] == s.to_utf16()[o..].to_utf8()
fn find_utf16_code_unit_offset(s: &str, offset: u32) -> Option<usize> {
let mut code_units = 0;
for (i, c) in s.char_indices() {
if code_units == offset {
return Some(i)
}
code_units += 1;
if c > '\u{FFFF}' {
if code_units == offset {
panic!("\n\n\
Would split a surrogate pair in CharacterData API.\n\
If you see this in real content, please comment with the URL\n\
on https://github.com/servo/servo/issues/6873\n\
\n");
}
code_units += 1;
}
}
if code_units == offset {
Some(s.len())
} else {
None
}
}

View file

@ -16,7 +16,6 @@ use script_task::ScriptChan;
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CloseEvent {
event: Event,
wasClean: bool,
@ -69,19 +68,19 @@ impl CloseEvent {
}
}
impl<'a> CloseEventMethods for &'a CloseEvent {
impl CloseEventMethods for CloseEvent {
// https://html.spec.whatwg.org/multipage/#dom-closeevent-wasclean
fn WasClean(self) -> bool {
fn WasClean(&self) -> bool {
self.wasClean
}
// https://html.spec.whatwg.org/multipage/#dom-closeevent-code
fn Code(self) -> u16 {
fn Code(&self) -> u16 {
self.code
}
// https://html.spec.whatwg.org/multipage/#dom-closeevent-reason
fn Reason(self) -> DOMString {
fn Reason(&self) -> DOMString {
self.reason.clone()
}
}

View file

@ -16,7 +16,6 @@ use util::str::DOMString;
/// An HTML comment.
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Comment {
characterdata: CharacterData,
}
@ -44,4 +43,3 @@ impl Comment {
Ok(Comment::new(data, document.r()))
}
}

View file

@ -8,12 +8,10 @@ use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods;
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::Root;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::window::WindowHelpers;
use util::str::DOMString;
// https://developer.mozilla.org/en-US/docs/Web/API/Console
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Console {
reflector_: Reflector,
global: GlobalField,
@ -32,9 +30,9 @@ impl Console {
}
}
impl<'a> ConsoleMethods for &'a Console {
impl ConsoleMethods for Console {
// 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 {
println!("{}", message);
propagate_console_msg(&self, prepare_message(LogLevel::Log, message));
@ -42,7 +40,7 @@ impl<'a> ConsoleMethods for &'a Console {
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console
fn Debug(self, messages: Vec<DOMString>) {
fn Debug(&self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
propagate_console_msg(&self, prepare_message(LogLevel::Debug, message));
@ -50,7 +48,7 @@ impl<'a> ConsoleMethods for &'a Console {
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/info
fn Info(self, messages: Vec<DOMString>) {
fn Info(&self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
propagate_console_msg(&self, prepare_message(LogLevel::Info, message));
@ -58,7 +56,7 @@ impl<'a> ConsoleMethods for &'a Console {
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/warn
fn Warn(self, messages: Vec<DOMString>) {
fn Warn(&self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
propagate_console_msg(&self, prepare_message(LogLevel::Warn, message));
@ -66,7 +64,7 @@ impl<'a> ConsoleMethods for &'a Console {
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/error
fn Error(self, messages: Vec<DOMString>) {
fn Error(&self, messages: Vec<DOMString>) {
for message in messages {
println!("{}", message);
propagate_console_msg(&self, prepare_message(LogLevel::Error, message));
@ -74,7 +72,7 @@ impl<'a> ConsoleMethods for &'a Console {
}
// https://developer.mozilla.org/en-US/docs/Web/API/Console/assert
fn Assert(self, condition: bool, message: Option<DOMString>) {
fn Assert(&self, condition: bool, message: Option<DOMString>) {
if !condition {
let message = match message {
Some(ref message) => &**message,

View file

@ -22,7 +22,6 @@ no_jsmanaged_fields!(OsRng);
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Crypto {
reflector_: Reflector,
rng: DOMRefCell<OsRng>,
@ -41,10 +40,10 @@ impl Crypto {
}
}
impl<'a> CryptoMethods for &'a Crypto {
impl CryptoMethods for Crypto {
#[allow(unsafe_code)]
// https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#Crypto-method-getRandomValues
fn GetRandomValues(self, _cx: *mut JSContext, input: *mut JSObject)
fn GetRandomValues(&self, _cx: *mut JSContext, input: *mut JSObject)
-> Fallible<*mut JSObject> {
let mut length = 0;
let mut data = ptr::null_mut();

View file

@ -10,7 +10,6 @@ use util::str::DOMString;
use cssparser::serialize_identifier;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CSS {
reflector_: Reflector,
}

View file

@ -8,10 +8,9 @@ use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::DocumentHelpers;
use dom::element::{ElementHelpers, StylePriority, Element};
use dom::node::{window_from_node, document_from_node, NodeDamage, NodeHelpers};
use dom::window::{Window, WindowHelpers};
use dom::element::{StylePriority, Element};
use dom::node::{window_from_node, document_from_node, NodeDamage};
use dom::window::Window;
use selectors::parser::PseudoElement;
use string_cache::Atom;
use style::properties::PropertyDeclaration;
@ -24,7 +23,6 @@ use std::cell::Ref;
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CSSStyleDeclaration {
reflector_: Reflector,
owner: JS<Element>,
@ -41,10 +39,10 @@ pub enum CSSModificationAccess {
macro_rules! css_properties(
( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => (
$(
fn $getter(self) -> DOMString {
fn $getter(&self) -> DOMString {
self.GetPropertyValue($cssprop.to_owned())
}
fn $setter(self, value: DOMString) -> ErrorResult {
fn $setter(&self, value: DOMString) -> ErrorResult {
self.SetPropertyValue($cssprop.to_owned(), value)
}
)*
@ -76,9 +74,7 @@ impl CSSStyleDeclaration {
GlobalRef::Window(global),
CSSStyleDeclarationBinding::Wrap)
}
}
impl CSSStyleDeclaration {
fn get_computed_style(&self, property: &Atom) -> Option<DOMString> {
let owner = self.owner.root();
let node = NodeCast::from_ref(owner.r());
@ -92,9 +88,9 @@ impl CSSStyleDeclaration {
}
}
impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
fn Length(self) -> u32 {
fn Length(&self) -> u32 {
let owner = self.owner.root();
let elem = ElementCast::from_ref(owner.r());
let len = match *elem.style_attribute().borrow() {
@ -105,7 +101,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
fn Item(self, index: u32) -> DOMString {
fn Item(&self, index: u32) -> DOMString {
let index = index as usize;
let owner = self.owner.root();
let elem = ElementCast::from_ref(owner.r());
@ -126,7 +122,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
fn GetPropertyValue(self, property: DOMString) -> DOMString {
fn GetPropertyValue(&self, property: DOMString) -> DOMString {
let owner = self.owner.root();
// Step 1
@ -169,7 +165,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
fn GetPropertyPriority(self, property: DOMString) -> DOMString {
fn GetPropertyPriority(&self, property: DOMString) -> DOMString {
// Step 1
let property = Atom::from_slice(&property.to_ascii_lowercase());
@ -197,7 +193,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty
fn SetProperty(self, property: DOMString, value: DOMString,
fn SetProperty(&self, property: DOMString, value: DOMString,
priority: DOMString) -> ErrorResult {
// Step 1
if self.readonly {
@ -252,7 +248,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertypriority
fn SetPropertyPriority(self, property: DOMString, priority: DOMString) -> ErrorResult {
fn SetPropertyPriority(&self, property: DOMString, priority: DOMString) -> ErrorResult {
// Step 1
if self.readonly {
return Err(Error::NoModificationAllowed);
@ -286,12 +282,12 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertyvalue
fn SetPropertyValue(self, property: DOMString, value: DOMString) -> ErrorResult {
fn SetPropertyValue(&self, property: DOMString, value: DOMString) -> ErrorResult {
self.SetProperty(property, value, "".to_owned())
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
fn RemoveProperty(self, property: DOMString) -> Fallible<DOMString> {
fn RemoveProperty(&self, property: DOMString) -> Fallible<DOMString> {
// Step 1
if self.readonly {
return Err(Error::NoModificationAllowed);
@ -322,21 +318,22 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
fn CssFloat(self) -> DOMString {
fn CssFloat(&self) -> DOMString {
self.GetPropertyValue("float".to_owned())
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
fn SetCssFloat(self, value: DOMString) -> ErrorResult {
fn SetCssFloat(&self, value: DOMString) -> ErrorResult {
self.SetPropertyValue("float".to_owned(), value)
}
// https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
fn IndexedGetter(self, index: u32, found: &mut bool) -> DOMString {
fn IndexedGetter(&self, index: u32, found: &mut bool) -> DOMString {
let rval = self.Item(index);
*found = index < self.Length();
rval
}
// https://drafts.csswg.org/cssom/#cssstyledeclaration
css_properties_accessors!(css_properties);
}

View file

@ -17,7 +17,6 @@ use util::str::DOMString;
// https://dom.spec.whatwg.org/#interface-customevent
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct CustomEvent {
event: Event,
#[ignore_heap_size_of = "Defined in rust-mozjs"]
@ -63,14 +62,14 @@ impl CustomEvent {
}
}
impl<'a> CustomEventMethods for &'a CustomEvent {
impl CustomEventMethods for CustomEvent {
// 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()
}
// https://dom.spec.whatwg.org/#dom-customevent-initcustomevent
fn InitCustomEvent(self,
fn InitCustomEvent(&self,
_cx: *mut JSContext,
type_: DOMString,
can_bubble: bool,
@ -85,4 +84,3 @@ impl<'a> CustomEventMethods for &'a CustomEvent {
event.InitEvent(type_, can_bubble, cancelable);
}
}

View file

@ -6,7 +6,6 @@ use devtools;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding;
use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods;
use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast};
@ -16,12 +15,12 @@ use dom::bindings::js::{RootCollection, Root};
use dom::bindings::refcounted::LiveDOMReferences;
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::utils::Reflectable;
use dom::errorevent::ErrorEvent;
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::messageevent::MessageEvent;
use dom::worker::{TrustedWorkerAddress, WorkerMessageHandler, WorkerEventHandler, WorkerErrorHandler};
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
use dom::worker::{TrustedWorkerAddress, WorkerMessageHandler, SimpleWorkerErrorHandler};
use dom::workerglobalscope::WorkerGlobalScope;
use dom::workerglobalscope::{WorkerGlobalScopeTypeId, WorkerGlobalScopeInit};
use script_task::ScriptTaskEventCategory::WorkerEvent;
use script_task::{ScriptTask, ScriptChan, TimerSource, ScriptPort, StackRootTLS, CommonScriptMsg};
use devtools_traits::DevtoolScriptControlMsg;
@ -138,7 +137,6 @@ enum MixedMessage {
// https://html.spec.whatwg.org/multipage/#dedicatedworkerglobalscope
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DedicatedWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
id: PipelineId,
@ -189,9 +187,7 @@ impl DedicatedWorkerGlobalScope {
own_sender, receiver);
DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
}
}
impl DedicatedWorkerGlobalScope {
pub fn run_worker_scope(init: WorkerGlobalScopeInit,
worker_url: Url,
id: PipelineId,
@ -210,8 +206,8 @@ impl DedicatedWorkerGlobalScope {
let (url, source) = match load_whole_resource(&init.resource_task, worker_url) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);
parent_sender.send(CommonScriptMsg::RunnableMsg(
box WorkerEventHandler::new(worker))).unwrap();
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
box SimpleWorkerErrorHandler::new(worker))).unwrap();
return;
}
Ok((metadata, bytes)) => {
@ -244,28 +240,19 @@ impl DedicatedWorkerGlobalScope {
}, reporter_name, parent_sender, CommonScriptMsg::CollectReports);
});
}
}
pub trait DedicatedWorkerGlobalScopeHelpers {
fn script_chan(self) -> Box<ScriptChan + Send>;
fn pipeline(self) -> PipelineId;
fn new_script_pair(self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>);
fn process_event(self, msg: CommonScriptMsg);
}
impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
fn script_chan(self) -> Box<ScriptChan + Send> {
pub fn script_chan(&self) -> Box<ScriptChan + Send> {
box WorkerThreadWorkerChan {
sender: self.own_sender.clone(),
worker: self.worker.borrow().as_ref().unwrap().clone(),
}
}
fn pipeline(self) -> PipelineId {
pub fn pipeline(&self) -> PipelineId {
self.id
}
fn new_script_pair(self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
let (tx, rx) = channel();
let chan = box SendableWorkerScriptChan {
sender: tx,
@ -274,21 +261,12 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
(chan, box rx)
}
fn process_event(self, msg: CommonScriptMsg) {
pub fn process_event(&self, msg: CommonScriptMsg) {
self.handle_script_event(WorkerScriptMsg::Common(msg));
}
}
trait PrivateDedicatedWorkerGlobalScopeHelpers {
fn handle_script_event(self, msg: WorkerScriptMsg);
fn dispatch_error_to_worker(self, &ErrorEvent);
fn receive_event(self) -> Result<MixedMessage, RecvError>;
fn handle_event(self, event: MixedMessage);
}
impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
#[allow(unsafe_code)]
fn receive_event(self) -> Result<MixedMessage, RecvError> {
fn receive_event(&self) -> Result<MixedMessage, RecvError> {
let scope = WorkerGlobalScopeCast::from_ref(self);
let worker_port = &self.receiver;
let devtools_port = scope.from_devtools_receiver();
@ -312,7 +290,7 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalS
}
}
fn handle_script_event(self, msg: WorkerScriptMsg) {
fn handle_script_event(&self, msg: WorkerScriptMsg) {
match msg {
WorkerScriptMsg::DOMMessage(data) => {
let scope = WorkerGlobalScopeCast::from_ref(self);
@ -323,7 +301,7 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalS
data.read(GlobalRef::Worker(scope), message.handle_mut());
MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle());
},
WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(runnable)) => {
WorkerScriptMsg::Common(CommonScriptMsg::RunnableMsg(_, runnable)) => {
runnable.handler()
},
WorkerScriptMsg::Common(CommonScriptMsg::RefcountCleanup(addr)) => {
@ -347,7 +325,7 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalS
}
}
fn handle_event(self, event: MixedMessage) {
fn handle_event(&self, event: MixedMessage) {
match event {
MixedMessage::FromDevtools(msg) => {
let global_ref = GlobalRef::Worker(WorkerGlobalScopeCast::from_ref(self));
@ -367,28 +345,19 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalS
},
}
}
fn dispatch_error_to_worker(self, errorevent: &ErrorEvent) {
let msg = errorevent.Message();
let file_name = errorevent.Filename();
let line_num = errorevent.Lineno();
let col_num = errorevent.Colno();
let worker = self.worker.borrow().as_ref().unwrap().clone();
self.parent_sender.send(CommonScriptMsg::RunnableMsg(
box WorkerErrorHandler::new(worker, msg, file_name, line_num, col_num))).unwrap();
}
}
impl<'a> DedicatedWorkerGlobalScopeMethods for &'a DedicatedWorkerGlobalScope {
impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
// https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
fn PostMessage(self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
let data = try!(StructuredCloneData::write(cx, message));
let worker = self.worker.borrow().as_ref().unwrap().clone();
self.parent_sender.send(CommonScriptMsg::RunnableMsg(
self.parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
box WorkerMessageHandler::new(worker, data))).unwrap();
Ok(())
}
// https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
event_handler!(message, GetOnmessage, SetOnmessage);
}

File diff suppressed because it is too large Load diff

View file

@ -15,13 +15,12 @@ use dom::document::Document;
use dom::element::Element;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlcollection::HTMLCollection;
use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::node::{Node, NodeTypeId, window_from_node};
use dom::nodelist::NodeList;
use util::str::DOMString;
// https://dom.spec.whatwg.org/#documentfragment
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DocumentFragment {
node: Node,
}
@ -52,48 +51,47 @@ impl DocumentFragment {
}
}
impl<'a> DocumentFragmentMethods for &'a DocumentFragment {
impl DocumentFragmentMethods for DocumentFragment {
// https://dom.spec.whatwg.org/#dom-parentnode-children
fn Children(self) -> Root<HTMLCollection> {
fn Children(&self) -> Root<HTMLCollection> {
let window = window_from_node(self);
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
}
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
fn GetFirstElementChild(self) -> Option<Root<Element>> {
fn GetFirstElementChild(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).child_elements().next()
}
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
fn GetLastElementChild(self) -> Option<Root<Element>> {
fn GetLastElementChild(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next()
}
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
fn ChildElementCount(self) -> u32 {
fn ChildElementCount(&self) -> u32 {
NodeCast::from_ref(self).child_elements().count() as u32
}
// https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).prepend(nodes)
}
// https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).append(nodes)
}
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
let root = NodeCast::from_ref(self);
root.query_selector(selectors)
}
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> {
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Root<NodeList>> {
let root = NodeCast::from_ref(self);
root.query_selector_all(selectors)
}
}

View file

@ -10,7 +10,7 @@ use dom::bindings::error::ErrorResult;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId};
use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
use std::borrow::ToOwned;
@ -18,7 +18,6 @@ use std::borrow::ToOwned;
// https://dom.spec.whatwg.org/#documenttype
/// The `DOCTYPE` tag.
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DocumentType {
node: Node,
name: DOMString,
@ -74,41 +73,40 @@ impl DocumentType {
}
}
impl<'a> DocumentTypeMethods for &'a DocumentType {
impl DocumentTypeMethods for DocumentType {
// https://dom.spec.whatwg.org/#dom-documenttype-name
fn Name(self) -> DOMString {
fn Name(&self) -> DOMString {
self.name.clone()
}
// https://dom.spec.whatwg.org/#dom-documenttype-publicid
fn PublicId(self) -> DOMString {
fn PublicId(&self) -> DOMString {
self.public_id.clone()
}
// https://dom.spec.whatwg.org/#dom-documenttype-systemid
fn SystemId(self) -> DOMString {
fn SystemId(&self) -> DOMString {
self.system_id.clone()
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).before(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-after
fn After(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).after(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).replace_with(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-remove
fn Remove(self) {
fn Remove(&self) {
let node = NodeCast::from_ref(self);
node.remove_self();
}
}

View file

@ -41,7 +41,6 @@ pub enum DOMErrorName {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMException {
reflector_: Reflector,
code: DOMErrorName,
@ -60,9 +59,9 @@ impl DOMException {
}
}
impl<'a> DOMExceptionMethods for &'a DOMException {
impl DOMExceptionMethods for DOMException {
// https://heycam.github.io/webidl/#dfn-DOMException
fn Code(self) -> u16 {
fn Code(&self) -> u16 {
match self.code {
// https://heycam.github.io/webidl/#dfn-throw
DOMErrorName::EncodingError => 0,
@ -71,12 +70,12 @@ impl<'a> DOMExceptionMethods for &'a DOMException {
}
// https://heycam.github.io/webidl/#idl-DOMException-error-names
fn Name(self) -> DOMString {
fn Name(&self) -> DOMString {
format!("{:?}", self.code)
}
// https://heycam.github.io/webidl/#error-names
fn Message(self) -> DOMString {
fn Message(&self) -> DOMString {
let message = match self.code {
DOMErrorName::IndexSizeError => "The index is not in the allowed range.",
DOMErrorName::HierarchyRequestError => "The operation would yield an incorrect node tree.",

View file

@ -14,7 +14,7 @@ use dom::bindings::js::{JS, Root};
use dom::bindings::utils::validate_qualified_name;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::DocumentSource;
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
use dom::document::{Document, IsHTMLDocument};
use dom::documenttype::DocumentType;
use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlheadelement::HTMLHeadElement;
@ -27,7 +27,6 @@ use std::borrow::ToOwned;
// https://dom.spec.whatwg.org/#domimplementation
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMImplementation {
reflector_: Reflector,
document: JS<Document>,
@ -50,9 +49,9 @@ impl DOMImplementation {
}
// https://dom.spec.whatwg.org/#domimplementation
impl<'a> DOMImplementationMethods for &'a DOMImplementation {
impl DOMImplementationMethods for DOMImplementation {
// 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<Root<DocumentType>> {
try!(validate_qualified_name(&qualified_name));
let document = self.document.root();
@ -60,7 +59,7 @@ impl<'a> DOMImplementationMethods for &'a DOMImplementation {
}
// 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<&DocumentType>) -> Fallible<Root<Document>> {
let doc = self.document.root();
let doc = doc.r();
@ -109,7 +108,7 @@ impl<'a> DOMImplementationMethods for &'a DOMImplementation {
}
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
fn CreateHTMLDocument(self, title: Option<DOMString>) -> Root<Document> {
fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Root<Document> {
let document = self.document.root();
let document = document.r();
let win = document.window();
@ -168,7 +167,7 @@ impl<'a> DOMImplementationMethods for &'a DOMImplementation {
}
// https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
fn HasFeature(self) -> bool {
fn HasFeature(&self) -> bool {
true
}
}

View file

@ -13,15 +13,14 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::document::DocumentSource;
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
use dom::window::{Window, WindowHelpers};
use dom::document::{Document, IsHTMLDocument};
use dom::window::Window;
use parse::html::{ParseContext, parse_html};
use util::str::DOMString;
use std::borrow::ToOwned;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMParser {
reflector_: Reflector,
window: JS<Window>, //XXXjdm Document instead?
@ -45,9 +44,9 @@ impl DOMParser {
}
}
impl<'a> DOMParserMethods for &'a DOMParser {
impl DOMParserMethods for DOMParser {
// https://domparsing.spec.whatwg.org/#the-domparser-interface
fn ParseFromString(self,
fn ParseFromString(&self,
s: DOMString,
ty: DOMParserBinding::SupportedType)
-> Fallible<Root<Document>> {
@ -81,4 +80,3 @@ impl<'a> DOMParserMethods for &'a DOMParser {
}
}
}

View file

@ -12,7 +12,6 @@ use dom::dompointreadonly::{DOMPointReadOnly, DOMPointWriteMethods};
// http://dev.w3.org/fxtf/geometry/Overview.html#dompoint
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMPoint {
point: DOMPointReadOnly
}
@ -34,45 +33,44 @@ impl DOMPoint {
}
}
impl<'a> DOMPointMethods for &'a DOMPoint {
impl DOMPointMethods for DOMPoint {
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-x
fn X(self) -> f64 {
fn X(&self) -> f64 {
self.point.X()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-x
fn SetX(self, value: f64) {
fn SetX(&self, value: f64) {
self.point.SetX(value);
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-y
fn Y(self) -> f64 {
fn Y(&self) -> f64 {
self.point.Y()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-y
fn SetY(self, value: f64) {
fn SetY(&self, value: f64) {
self.point.SetY(value);
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-z
fn Z(self) -> f64 {
fn Z(&self) -> f64 {
self.point.Z()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-z
fn SetZ(self, value: f64) {
fn SetZ(&self, value: f64) {
self.point.SetZ(value);
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-w
fn W(self) -> f64 {
fn W(&self) -> f64 {
self.point.W()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-w
fn SetW(self, value: f64) {
fn SetW(&self, value: f64) {
self.point.SetW(value);
}
}

View file

@ -11,7 +11,6 @@ use std::cell::Cell;
// http://dev.w3.org/fxtf/geometry/Overview.html#dompointreadonly
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMPointReadOnly {
reflector_: Reflector,
x: Cell<f64>,
@ -41,49 +40,49 @@ impl DOMPointReadOnly {
}
}
impl<'a> DOMPointReadOnlyMethods for &'a DOMPointReadOnly {
impl DOMPointReadOnlyMethods for DOMPointReadOnly {
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-x
fn X(self) -> f64 {
fn X(&self) -> f64 {
self.x.get()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-y
fn Y(self) -> f64 {
fn Y(&self) -> f64 {
self.y.get()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-z
fn Z(self) -> f64 {
fn Z(&self) -> f64 {
self.z.get()
}
// https://dev.w3.org/fxtf/geometry/Overview.html#dom-dompointreadonly-w
fn W(self) -> f64 {
fn W(&self) -> f64 {
self.w.get()
}
}
pub trait DOMPointWriteMethods {
fn SetX(self, value: f64);
fn SetY(self, value: f64);
fn SetZ(self, value: f64);
fn SetW(self, value: f64);
fn SetX(&self, value: f64);
fn SetY(&self, value: f64);
fn SetZ(&self, value: f64);
fn SetW(&self, value: f64);
}
impl<'a> DOMPointWriteMethods for &'a DOMPointReadOnly {
fn SetX(self, value: f64) {
impl DOMPointWriteMethods for DOMPointReadOnly {
fn SetX(&self, value: f64) {
self.x.set(value);
}
fn SetY(self, value: f64) {
fn SetY(&self, value: f64) {
self.y.set(value);
}
fn SetZ(self, value: f64) {
fn SetZ(&self, value: f64) {
self.z.set(value);
}
fn SetW(self, value: f64) {
fn SetW(&self, value: f64) {
self.w.set(value);
}
}

View file

@ -12,7 +12,6 @@ use dom::window::Window;
use util::geometry::Au;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMRect {
reflector_: Reflector,
top: f32,
@ -41,37 +40,36 @@ impl DOMRect {
}
}
impl<'a> DOMRectMethods for &'a DOMRect {
impl DOMRectMethods for DOMRect {
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-top
fn Top(self) -> Finite<f32> {
fn Top(&self) -> Finite<f32> {
Finite::wrap(self.top)
}
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-bottom
fn Bottom(self) -> Finite<f32> {
fn Bottom(&self) -> Finite<f32> {
Finite::wrap(self.bottom)
}
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-left
fn Left(self) -> Finite<f32> {
fn Left(&self) -> Finite<f32> {
Finite::wrap(self.left)
}
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-right
fn Right(self) -> Finite<f32> {
fn Right(&self) -> Finite<f32> {
Finite::wrap(self.right)
}
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-width
fn Width(self) -> Finite<f32> {
fn Width(&self) -> Finite<f32> {
let result = (self.right - self.left).abs();
Finite::wrap(result)
}
// https://drafts.fxtf.org/geometry/#dom-domrectreadonly-height
fn Height(self) -> Finite<f32> {
fn Height(&self) -> Finite<f32> {
let result = (self.bottom - self.top).abs();
Finite::wrap(result)
}
}

View file

@ -11,7 +11,6 @@ use dom::domrect::DOMRect;
use dom::window::Window;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMRectList {
reflector_: Reflector,
rects: Vec<JS<DOMRect>>,
@ -33,14 +32,14 @@ impl DOMRectList {
}
}
impl<'a> DOMRectListMethods for &'a DOMRectList {
impl DOMRectListMethods for DOMRectList {
// https://drafts.fxtf.org/geometry/#dom-domrectlist-length
fn Length(self) -> u32 {
fn Length(&self) -> u32 {
self.rects.len() as u32
}
// https://drafts.fxtf.org/geometry/#dom-domrectlist-item
fn Item(self, index: u32) -> Option<Root<DOMRect>> {
fn Item(&self, index: u32) -> Option<Root<DOMRect>> {
let rects = &self.rects;
if index < rects.len() as u32 {
Some(rects[index as usize].root())
@ -50,9 +49,8 @@ impl<'a> DOMRectListMethods for &'a DOMRectList {
}
// check-tidy: no specs after this line
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<DOMRect>> {
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<DOMRect>> {
*found = index < self.rects.len() as u32;
self.Item(index)
}
}

View file

@ -8,12 +8,11 @@ use dom::bindings::error::ErrorResult;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::htmlelement::{HTMLElement, HTMLElementCustomAttributeHelpers};
use dom::htmlelement::HTMLElement;
use dom::node::window_from_node;
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMStringMap {
reflector_: Reflector,
element: JS<HTMLElement>,
@ -35,26 +34,26 @@ impl DOMStringMap {
}
// https://html.spec.whatwg.org/#domstringmap
impl<'a> DOMStringMapMethods for &'a DOMStringMap {
impl DOMStringMapMethods for DOMStringMap {
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-additem
fn NamedCreator(self, name: DOMString, value: DOMString) -> ErrorResult {
fn NamedCreator(&self, name: DOMString, value: DOMString) -> ErrorResult {
self.NamedSetter(name, value)
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem
fn NamedDeleter(self, name: DOMString) {
fn NamedDeleter(&self, name: DOMString) {
let element = self.element.root();
element.r().delete_custom_attr(name)
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem
fn NamedSetter(self, name: DOMString, value: DOMString) -> ErrorResult {
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult {
let element = self.element.root();
element.r().set_custom_attr(name, value)
}
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem
fn NamedGetter(self, name: DOMString, found: &mut bool) -> DOMString {
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> DOMString {
let element = self.element.root();
match element.r().get_custom_attr(name) {
Some(value) => {
@ -69,7 +68,7 @@ impl<'a> DOMStringMapMethods for &'a DOMStringMap {
}
// https://html.spec.whatwg.org/multipage/#domstringmap
fn SupportedPropertyNames(self) -> Vec<DOMString> {
fn SupportedPropertyNames(&self) -> Vec<DOMString> {
// FIXME: unimplemented (https://github.com/servo/servo/issues/7273)
vec![]
}

View file

@ -2,7 +2,7 @@
* 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/. */
use dom::attr::{Attr, AttrHelpers};
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::DOMTokenListBinding;
use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods;
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
@ -10,7 +10,7 @@ use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::element::Element;
use dom::node::window_from_node;
use string_cache::Atom;
@ -19,7 +19,6 @@ use util::str::{DOMString, HTML_SPACE_CHARACTERS, str_join};
use std::borrow::ToOwned;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct DOMTokenList {
reflector_: Reflector,
element: JS<Element>,
@ -41,20 +40,13 @@ impl DOMTokenList {
GlobalRef::Window(window.r()),
DOMTokenListBinding::Wrap)
}
}
trait PrivateDOMTokenListHelpers {
fn attribute(self) -> Option<Root<Attr>>;
fn check_token_exceptions(self, token: &str) -> Fallible<Atom>;
}
impl<'a> PrivateDOMTokenListHelpers for &'a DOMTokenList {
fn attribute(self) -> Option<Root<Attr>> {
fn attribute(&self) -> Option<Root<Attr>> {
let element = self.element.root();
element.r().get_attribute(&ns!(""), &self.local_name)
}
fn check_token_exceptions(self, token: &str) -> Fallible<Atom> {
fn check_token_exceptions(&self, token: &str) -> Fallible<Atom> {
match token {
"" => Err(Syntax),
slice if slice.find(HTML_SPACE_CHARACTERS).is_some() => Err(InvalidCharacter),
@ -64,9 +56,9 @@ impl<'a> PrivateDOMTokenListHelpers for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#domtokenlist
impl<'a> DOMTokenListMethods for &'a DOMTokenList {
impl DOMTokenListMethods for DOMTokenList {
// https://dom.spec.whatwg.org/#dom-domtokenlist-length
fn Length(self) -> u32 {
fn Length(&self) -> u32 {
self.attribute().map(|attr| {
let attr = attr.r();
attr.value().tokens().map(|tokens| tokens.len()).unwrap_or(0)
@ -74,7 +66,7 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-item
fn Item(self, index: u32) -> Option<DOMString> {
fn Item(&self, index: u32) -> Option<DOMString> {
self.attribute().and_then(|attr| {
let attr = attr.r();
attr.value().tokens().and_then(|tokens| {
@ -84,7 +76,7 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// 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.attribute().map(|attr| {
let attr = attr.r();
@ -98,7 +90,7 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-add
fn Add(self, tokens: Vec<DOMString>) -> ErrorResult {
fn Add(&self, tokens: Vec<DOMString>) -> ErrorResult {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in &tokens {
@ -112,7 +104,7 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-remove
fn Remove(self, tokens: Vec<DOMString>) -> ErrorResult {
fn Remove(&self, tokens: Vec<DOMString>) -> ErrorResult {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
for token in &tokens {
@ -126,7 +118,7 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#dom-domtokenlist-toggle
fn Toggle(self, token: DOMString, force: Option<bool>) -> Fallible<bool> {
fn Toggle(&self, token: DOMString, force: Option<bool>) -> Fallible<bool> {
let element = self.element.root();
let mut atoms = element.r().get_tokenlist_attribute(&self.local_name);
let token = try!(self.check_token_exceptions(&token));
@ -151,13 +143,13 @@ impl<'a> DOMTokenListMethods for &'a DOMTokenList {
}
// https://dom.spec.whatwg.org/#stringification-behavior
fn Stringifier(self) -> DOMString {
fn Stringifier(&self) -> DOMString {
let tokenlist = self.element.root().r().get_tokenlist_attribute(&self.local_name);
str_join(&tokenlist, "\x20")
}
// check-tidy: no specs after this line
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<DOMString> {
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString> {
let item = self.Item(index);
*found = item.is_some();
item

View file

@ -6,7 +6,7 @@
use dom::activation::Activatable;
use dom::attr::AttrValue;
use dom::attr::{Attr, AttrSettingType, AttrHelpers, AttrHelpersForLayout};
use dom::attr::{Attr, AttrSettingType, AttrHelpersForLayout};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::ElementBinding;
@ -35,27 +35,26 @@ use dom::bindings::js::{Root, RootedReference};
use dom::bindings::trace::RootedVec;
use dom::bindings::utils::XMLName::InvalidXMLName;
use dom::bindings::utils::{namespace_from_domstring, xml_name_type, validate_and_extract};
use dom::characterdata::CharacterDataHelpers;
use dom::create::create_element;
use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers};
use dom::document::{Document, LayoutDocumentHelpers};
use dom::domrect::DOMRect;
use dom::domrectlist::DOMRectList;
use dom::domtokenlist::DOMTokenList;
use dom::event::{Event, EventHelpers};
use dom::event::Event;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers};
use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlcollection::HTMLCollection;
use dom::htmlelement::HTMLElementTypeId;
use dom::htmlfontelement::{HTMLFontElement, HTMLFontElementHelpers};
use dom::htmliframeelement::{HTMLIFrameElement, RawHTMLIFrameElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers, HTMLInputElementHelpers};
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers};
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers};
use dom::htmltablerowelement::{HTMLTableRowElement, HTMLTableRowElementHelpers};
use dom::htmltablesectionelement::{HTMLTableSectionElement, HTMLTableSectionElementHelpers};
use dom::htmlfontelement::HTMLFontElement;
use dom::htmliframeelement::HTMLIFrameElement;
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers};
use dom::htmltablecellelement::HTMLTableCellElement;
use dom::htmltableelement::HTMLTableElement;
use dom::htmltablerowelement::HTMLTableRowElement;
use dom::htmltablesectionelement::HTMLTableSectionElement;
use dom::htmltextareaelement::{HTMLTextAreaElement, RawLayoutHTMLTextAreaElementHelpers};
use dom::namednodemap::NamedNodeMap;
use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node, NodeHelpers, NodeTypeId, SEQUENTIALLY_FOCUSABLE};
use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node, NodeTypeId, SEQUENTIALLY_FOCUSABLE};
use dom::node::{document_from_node, NodeDamage};
use dom::node::{window_from_node};
use dom::nodelist::NodeList;
@ -92,7 +91,6 @@ use std::mem;
use std::sync::Arc;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Element {
node: Node,
local_name: Atom,
@ -571,38 +569,18 @@ pub enum StylePriority {
Normal,
}
pub trait ElementHelpers<'a> {
fn html_element_in_html_document(self) -> bool;
fn local_name(self) -> &'a Atom;
fn parsed_name(self, name: DOMString) -> Atom;
fn namespace(self) -> &'a Namespace;
fn prefix(self) -> &'a Option<DOMString>;
fn attrs(&self) -> Ref<Vec<JS<Attr>>>;
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>>;
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>;
fn summarize(self) -> Vec<AttrInfo>;
fn is_void(self) -> bool;
fn remove_inline_style_property(self, property: &str);
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority);
fn get_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>>;
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>>;
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
fn get_root_element(self) -> Root<Element>;
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>;
}
impl<'a> ElementHelpers<'a> for &'a Element {
fn html_element_in_html_document(self) -> bool {
impl Element {
pub fn html_element_in_html_document(&self) -> bool {
let node = NodeCast::from_ref(self);
self.namespace == ns!(HTML) && node.is_in_html_doc()
}
fn local_name(self) -> &'a Atom {
pub fn local_name(&self) -> &Atom {
&self.local_name
}
fn parsed_name(self, name: DOMString) -> Atom {
pub fn parsed_name(&self, name: DOMString) -> Atom {
if self.html_element_in_html_document() {
Atom::from_slice(&name.to_ascii_lowercase())
} else {
@ -610,27 +588,27 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
}
fn namespace(self) -> &'a Namespace {
pub fn namespace(&self) -> &Namespace {
&self.namespace
}
fn prefix(self) -> &'a Option<DOMString> {
pub fn prefix(&self) -> &Option<DOMString> {
&self.prefix
}
fn attrs(&self) -> Ref<Vec<JS<Attr>>> {
pub fn attrs(&self) -> Ref<Vec<JS<Attr>>> {
self.attrs.borrow()
}
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> {
pub fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> {
self.attrs.borrow_mut()
}
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
pub fn style_attribute(&self) -> &DOMRefCell<Option<PropertyDeclarationBlock>> {
&self.style_attribute
}
fn summarize(self) -> Vec<AttrInfo> {
pub fn summarize(&self) -> Vec<AttrInfo> {
let attrs = self.Attributes();
let mut summarized = vec!();
for i in 0..attrs.r().Length() {
@ -640,7 +618,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
summarized
}
fn is_void(self) -> bool {
pub fn is_void(&self) -> bool {
if self.namespace != ns!(HTML) {
return false
}
@ -654,7 +632,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
}
fn remove_inline_style_property(self, property: &str) {
pub fn remove_inline_style_property(&self, property: &str) {
let mut inline_declarations = self.style_attribute.borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let index = declarations.normal
@ -675,7 +653,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
}
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority) {
pub fn update_inline_style(&self, property_decl: PropertyDeclaration, style_priority: StylePriority) {
let mut inline_declarations = self.style_attribute().borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let existing_declarations = if style_priority == StylePriority::Important {
@ -709,7 +687,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
});
}
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority) {
pub fn set_inline_style_property_priority(&self, properties: &[&str], style_priority: StylePriority) {
let mut inline_declarations = self.style_attribute().borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let (from, to) = if style_priority == StylePriority::Important {
@ -734,7 +712,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
}
fn get_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>> {
pub fn get_inline_style_declaration(&self, property: &Atom) -> Option<Ref<PropertyDeclaration>> {
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
inline_declarations.as_ref().and_then(|declarations| {
declarations.normal
@ -745,7 +723,8 @@ impl<'a> ElementHelpers<'a> for &'a Element {
})
}
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<Ref<'a, PropertyDeclaration>> {
pub fn get_important_inline_style_declaration(&self, property: &Atom)
-> Option<Ref<PropertyDeclaration>> {
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
inline_declarations.as_ref().and_then(|declarations| {
declarations.important
@ -755,7 +734,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
})
}
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
pub fn serialize(&self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
let node = NodeCast::from_ref(self);
let mut writer = vec![];
match serialize(&mut writer, &node,
@ -769,7 +748,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
// https://html.spec.whatwg.org/multipage/#root-element
fn get_root_element(self) -> Root<Element> {
pub fn get_root_element(&self) -> Root<Element> {
let node = NodeCast::from_ref(self);
node.inclusive_ancestors()
.filter_map(ElementCast::to_root)
@ -778,7 +757,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
// https://dom.spec.whatwg.org/#locate-a-namespace-prefix
fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString> {
pub fn lookup_prefix(&self, namespace: Namespace) -> Option<DOMString> {
for node in NodeCast::from_ref(self).inclusive_ancestors() {
match ElementCast::to_ref(node.r()) {
Some(element) => {
@ -806,16 +785,9 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}
}
pub trait FocusElementHelpers {
/// https://html.spec.whatwg.org/multipage/#focusable-area
fn is_focusable_area(self) -> bool;
/// https://html.spec.whatwg.org/multipage/#concept-element-disabled
fn is_actually_disabled(self) -> bool;
}
impl<'a> FocusElementHelpers for &'a Element {
fn is_focusable_area(self) -> bool {
impl Element {
pub fn is_focusable_area(&self) -> bool {
if self.is_actually_disabled() {
return false;
}
@ -836,7 +808,7 @@ impl<'a> FocusElementHelpers for &'a Element {
}
}
fn is_actually_disabled(self) -> bool {
pub fn is_actually_disabled(&self) -> bool {
let node = NodeCast::from_ref(self);
match node.type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
@ -855,58 +827,9 @@ impl<'a> FocusElementHelpers for &'a Element {
}
}
pub trait AttributeHandlers {
/// Returns the attribute with given namespace and case-sensitive local
/// name, if any.
fn get_attribute(self, namespace: &Namespace, local_name: &Atom)
-> Option<Root<Attr>>;
/// Returns the first attribute with any namespace and given case-sensitive
/// name, if any.
fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>>;
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>);
fn set_attribute_from_parser(self,
name: QualName,
value: DOMString,
prefix: Option<Atom>);
fn set_attribute(self, name: &Atom, value: AttrValue);
fn set_custom_attribute(self, name: DOMString, value: DOMString) -> ErrorResult;
fn do_set_attribute<F>(self, local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace,
prefix: Option<Atom>, cb: F)
where F: Fn(&Attr) -> bool;
fn parse_attribute(self, namespace: &Namespace, local_name: &Atom,
value: DOMString) -> AttrValue;
/// Removes the first attribute with any given namespace and case-sensitive local
/// name, if any.
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
-> Option<Root<Attr>>;
/// Removes the first attribute with any namespace and given case-sensitive name.
fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>>;
/// Removes the first attribute that satisfies `find`.
fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>>
where F: Fn(&Attr) -> bool;
fn has_class(self, name: &Atom) -> bool;
fn set_atomic_attribute(self, local_name: &Atom, value: DOMString);
// https://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes
fn has_attribute(self, local_name: &Atom) -> bool;
fn set_bool_attribute(self, local_name: &Atom, value: bool);
fn get_url_attribute(self, local_name: &Atom) -> DOMString;
fn set_url_attribute(self, local_name: &Atom, value: DOMString);
fn get_string_attribute(self, local_name: &Atom) -> DOMString;
fn set_string_attribute(self, local_name: &Atom, value: DOMString);
fn get_tokenlist_attribute(self, local_name: &Atom) -> Vec<Atom>;
fn set_tokenlist_attribute(self, local_name: &Atom, value: DOMString);
fn set_atomic_tokenlist_attribute(self, local_name: &Atom, tokens: Vec<Atom>);
fn get_uint_attribute(self, local_name: &Atom, default: u32) -> u32;
fn set_uint_attribute(self, local_name: &Atom, value: u32);
}
impl<'a> AttributeHandlers for &'a Element {
fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> {
impl Element {
pub fn get_attribute(&self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> {
let mut attributes = RootedVec::new();
self.get_attributes(local_name, &mut attributes);
attributes.r().iter()
@ -915,14 +838,14 @@ impl<'a> AttributeHandlers for &'a Element {
}
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>> {
pub fn get_attribute_by_name(&self, name: DOMString) -> Option<Root<Attr>> {
let name = &self.parsed_name(name);
self.attrs.borrow().iter().map(|attr| attr.root())
.find(|a| a.r().name() == name)
}
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>) {
pub fn get_attributes(&self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>) {
for ref attr in self.attrs.borrow().iter() {
let attr = attr.root();
if attr.r().local_name() == local_name {
@ -931,7 +854,7 @@ impl<'a> AttributeHandlers for &'a Element {
}
}
fn set_attribute_from_parser(self,
pub fn set_attribute_from_parser(&self,
qname: QualName,
value: DOMString,
prefix: Option<Atom>) {
@ -952,7 +875,7 @@ impl<'a> AttributeHandlers for &'a Element {
self.do_set_attribute(qname.local, value, name, qname.ns, prefix, |_| false)
}
fn set_attribute(self, name: &Atom, value: AttrValue) {
pub fn set_attribute(&self, name: &Atom, value: AttrValue) {
assert!(&**name == name.to_ascii_lowercase());
assert!(!name.contains(":"));
@ -961,7 +884,7 @@ impl<'a> AttributeHandlers for &'a Element {
}
// https://html.spec.whatwg.org/multipage/#attr-data-*
fn set_custom_attribute(self, name: DOMString, value: DOMString) -> ErrorResult {
pub fn set_custom_attribute(&self, name: DOMString, value: DOMString) -> ErrorResult {
// Step 1.
match xml_name_type(&name) {
InvalidXMLName => return Err(InvalidCharacter),
@ -977,7 +900,7 @@ impl<'a> AttributeHandlers for &'a Element {
Ok(())
}
fn do_set_attribute<F>(self,
pub fn do_set_attribute<F>(&self,
local_name: Atom,
value: AttrValue,
name: Atom,
@ -1003,7 +926,7 @@ impl<'a> AttributeHandlers for &'a Element {
(*self.attrs.borrow())[idx].root().r().set_value(set_type, value, self);
}
fn parse_attribute(self, namespace: &Namespace, local_name: &Atom,
pub fn parse_attribute(&self, namespace: &Namespace, local_name: &Atom,
value: DOMString) -> AttrValue {
if *namespace == ns!("") {
vtable_for(&NodeCast::from_ref(self))
@ -1013,18 +936,18 @@ impl<'a> AttributeHandlers for &'a Element {
}
}
fn remove_attribute(self, namespace: &Namespace, local_name: &Atom)
pub fn remove_attribute(&self, namespace: &Namespace, local_name: &Atom)
-> Option<Root<Attr>> {
self.do_remove_attribute(|attr| {
attr.namespace() == namespace && attr.local_name() == local_name
})
}
fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>> {
pub fn remove_attribute_by_name(&self, name: &Atom) -> Option<Root<Attr>> {
self.do_remove_attribute(|attr| attr.name() == name)
}
fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>>
pub fn do_remove_attribute<F>(&self, find: F) -> Option<Root<Attr>>
where F: Fn(&Attr) -> bool
{
let idx = self.attrs.borrow().iter()
@ -1057,7 +980,7 @@ impl<'a> AttributeHandlers for &'a Element {
})
}
fn has_class(self, name: &Atom) -> bool {
pub fn has_class(&self, name: &Atom) -> bool {
let quirks_mode = {
let node = NodeCast::from_ref(self);
let owner_doc = node.owner_doc();
@ -1074,20 +997,20 @@ impl<'a> AttributeHandlers for &'a Element {
}).unwrap_or(false)
}
fn set_atomic_attribute(self, local_name: &Atom, value: DOMString) {
pub fn set_atomic_attribute(&self, local_name: &Atom, value: DOMString) {
assert!(&**local_name == local_name.to_ascii_lowercase());
let value = AttrValue::from_atomic(value);
self.set_attribute(local_name, value);
}
fn has_attribute(self, local_name: &Atom) -> bool {
pub fn has_attribute(&self, local_name: &Atom) -> bool {
assert!(local_name.bytes().all(|b| b.to_ascii_lowercase() == b));
self.attrs.borrow().iter().map(|attr| attr.root()).any(|attr| {
attr.r().local_name() == local_name && attr.r().namespace() == &ns!("")
})
}
fn set_bool_attribute(self, local_name: &Atom, value: bool) {
pub fn set_bool_attribute(&self, local_name: &Atom, value: bool) {
if self.has_attribute(local_name) == value { return; }
if value {
self.set_string_attribute(local_name, String::new());
@ -1096,7 +1019,7 @@ impl<'a> AttributeHandlers for &'a Element {
}
}
fn get_url_attribute(self, local_name: &Atom) -> DOMString {
pub fn get_url_attribute(&self, local_name: &Atom) -> DOMString {
assert!(&**local_name == local_name.to_ascii_lowercase());
if !self.has_attribute(local_name) {
return "".to_owned();
@ -1111,22 +1034,22 @@ impl<'a> AttributeHandlers for &'a Element {
Err(_) => "".to_owned()
}
}
fn set_url_attribute(self, local_name: &Atom, value: DOMString) {
pub fn set_url_attribute(&self, local_name: &Atom, value: DOMString) {
self.set_string_attribute(local_name, value);
}
fn get_string_attribute(self, local_name: &Atom) -> DOMString {
pub fn get_string_attribute(&self, local_name: &Atom) -> DOMString {
match self.get_attribute(&ns!(""), local_name) {
Some(x) => x.r().Value(),
None => "".to_owned()
}
}
fn set_string_attribute(self, local_name: &Atom, value: DOMString) {
pub fn set_string_attribute(&self, local_name: &Atom, value: DOMString) {
assert!(&**local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::String(value));
}
fn get_tokenlist_attribute(self, local_name: &Atom) -> Vec<Atom> {
pub fn get_tokenlist_attribute(&self, local_name: &Atom) -> Vec<Atom> {
self.get_attribute(&ns!(""), local_name).map(|attr| {
attr.r()
.value()
@ -1136,17 +1059,17 @@ impl<'a> AttributeHandlers for &'a Element {
}).unwrap_or(vec!())
}
fn set_tokenlist_attribute(self, local_name: &Atom, value: DOMString) {
pub fn set_tokenlist_attribute(&self, local_name: &Atom, value: DOMString) {
assert!(&**local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::from_serialized_tokenlist(value));
}
fn set_atomic_tokenlist_attribute(self, local_name: &Atom, tokens: Vec<Atom>) {
pub fn set_atomic_tokenlist_attribute(&self, local_name: &Atom, tokens: Vec<Atom>) {
assert!(&**local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::from_atomic_tokens(tokens));
}
fn get_uint_attribute(self, local_name: &Atom, default: u32) -> u32 {
pub fn get_uint_attribute(&self, local_name: &Atom, default: u32) -> u32 {
assert!(local_name.chars().all(|ch| {
!ch.is_ascii() || ch.to_ascii_lowercase() == ch
}));
@ -1162,30 +1085,30 @@ impl<'a> AttributeHandlers for &'a Element {
None => default,
}
}
fn set_uint_attribute(self, local_name: &Atom, value: u32) {
pub fn set_uint_attribute(&self, local_name: &Atom, value: u32) {
assert!(&**local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::UInt(value.to_string(), value));
}
}
impl<'a> ElementMethods for &'a Element {
impl ElementMethods for Element {
// https://dom.spec.whatwg.org/#dom-element-namespaceuri
fn GetNamespaceURI(self) -> Option<DOMString> {
fn GetNamespaceURI(&self) -> Option<DOMString> {
Node::namespace_to_string(self.namespace.clone())
}
// https://dom.spec.whatwg.org/#dom-element-localname
fn LocalName(self) -> DOMString {
fn LocalName(&self) -> DOMString {
(*self.local_name).to_owned()
}
// https://dom.spec.whatwg.org/#dom-element-prefix
fn GetPrefix(self) -> Option<DOMString> {
fn GetPrefix(&self) -> Option<DOMString> {
self.prefix.clone()
}
// https://dom.spec.whatwg.org/#dom-element-tagname
fn TagName(self) -> DOMString {
fn TagName(&self) -> DOMString {
let qualified_name = match self.prefix {
Some(ref prefix) => {
Cow::Owned(format!("{}:{}", &**prefix, &*self.local_name))
@ -1200,32 +1123,32 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-id
fn Id(self) -> DOMString {
fn Id(&self) -> DOMString {
self.get_string_attribute(&atom!("id"))
}
// https://dom.spec.whatwg.org/#dom-element-id
fn SetId(self, id: DOMString) {
fn SetId(&self, id: DOMString) {
self.set_atomic_attribute(&atom!("id"), id);
}
// https://dom.spec.whatwg.org/#dom-element-classname
fn ClassName(self) -> DOMString {
fn ClassName(&self) -> DOMString {
self.get_string_attribute(&atom!("class"))
}
// https://dom.spec.whatwg.org/#dom-element-classname
fn SetClassName(self, class: DOMString) {
fn SetClassName(&self, class: DOMString) {
self.set_tokenlist_attribute(&atom!("class"), class);
}
// https://dom.spec.whatwg.org/#dom-element-classlist
fn ClassList(self) -> Root<DOMTokenList> {
fn ClassList(&self) -> Root<DOMTokenList> {
self.class_list.or_init(|| DOMTokenList::new(self, &atom!("class")))
}
// https://dom.spec.whatwg.org/#dom-element-attributes
fn Attributes(self) -> Root<NamedNodeMap> {
fn Attributes(&self) -> Root<NamedNodeMap> {
self.attr_list.or_init(|| {
let doc = {
let node = NodeCast::from_ref(self);
@ -1237,13 +1160,13 @@ impl<'a> ElementMethods for &'a Element {
}
// 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)
.map(|s| s.r().Value())
}
// https://dom.spec.whatwg.org/#dom-element-getattributens
fn GetAttributeNS(self,
fn GetAttributeNS(&self,
namespace: Option<DOMString>,
local_name: DOMString) -> Option<DOMString> {
let namespace = &namespace_from_domstring(namespace);
@ -1252,7 +1175,7 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-setattribute
fn SetAttribute(self,
fn SetAttribute(&self,
name: DOMString,
value: DOMString) -> ErrorResult {
// Step 1.
@ -1272,7 +1195,7 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-setattributens
fn SetAttributeNS(self,
fn SetAttributeNS(&self,
namespace: Option<DOMString>,
qualified_name: DOMString,
value: DOMString) -> ErrorResult {
@ -1289,13 +1212,13 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-removeattribute
fn RemoveAttribute(self, name: DOMString) {
fn RemoveAttribute(&self, name: DOMString) {
let name = self.parsed_name(name);
self.remove_attribute_by_name(&name);
}
// https://dom.spec.whatwg.org/#dom-element-removeattributens
fn RemoveAttributeNS(self,
fn RemoveAttributeNS(&self,
namespace: Option<DOMString>,
local_name: DOMString) {
let namespace = namespace_from_domstring(namespace);
@ -1304,38 +1227,38 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-hasattribute
fn HasAttribute(self, name: DOMString) -> bool {
fn HasAttribute(&self, name: DOMString) -> bool {
self.GetAttribute(name).is_some()
}
// https://dom.spec.whatwg.org/#dom-element-hasattributens
fn HasAttributeNS(self,
fn HasAttributeNS(&self,
namespace: Option<DOMString>,
local_name: DOMString) -> bool {
self.GetAttributeNS(namespace, local_name).is_some()
}
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagname
fn GetElementsByTagName(self, localname: DOMString) -> Root<HTMLCollection> {
fn GetElementsByTagName(&self, localname: DOMString) -> Root<HTMLCollection> {
let window = window_from_node(self);
HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), localname)
}
// https://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens
fn GetElementsByTagNameNS(self, maybe_ns: Option<DOMString>,
fn GetElementsByTagNameNS(&self, maybe_ns: Option<DOMString>,
localname: DOMString) -> Root<HTMLCollection> {
let window = window_from_node(self);
HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), localname, maybe_ns)
}
// https://dom.spec.whatwg.org/#dom-element-getelementsbyclassname
fn GetElementsByClassName(self, classes: DOMString) -> Root<HTMLCollection> {
fn GetElementsByClassName(&self, classes: DOMString) -> Root<HTMLCollection> {
let window = window_from_node(self);
HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes)
}
// https://drafts.csswg.org/cssom-view/#dom-element-getclientrects
fn GetClientRects(self) -> Root<DOMRectList> {
fn GetClientRects(&self) -> Root<DOMRectList> {
let win = window_from_node(self);
let node = NodeCast::from_ref(self);
let raw_rects = node.get_content_boxes();
@ -1348,7 +1271,7 @@ impl<'a> ElementMethods for &'a Element {
}
// https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect
fn GetBoundingClientRect(self) -> Root<DOMRect> {
fn GetBoundingClientRect(&self) -> Root<DOMRect> {
let win = window_from_node(self);
let node = NodeCast::from_ref(self);
let rect = node.get_bounding_content_box();
@ -1361,37 +1284,37 @@ impl<'a> ElementMethods for &'a Element {
}
// https://drafts.csswg.org/cssom-view/#dom-element-clienttop
fn ClientTop(self) -> i32 {
fn ClientTop(&self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().origin.y
}
// https://drafts.csswg.org/cssom-view/#dom-element-clientleft
fn ClientLeft(self) -> i32 {
fn ClientLeft(&self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().origin.x
}
// https://drafts.csswg.org/cssom-view/#dom-element-clientwidth
fn ClientWidth(self) -> i32 {
fn ClientWidth(&self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().size.width
}
// https://drafts.csswg.org/cssom-view/#dom-element-clientheight
fn ClientHeight(self) -> i32 {
fn ClientHeight(&self) -> i32 {
let node = NodeCast::from_ref(self);
node.get_client_rect().size.height
}
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML
fn GetInnerHTML(self) -> Fallible<DOMString> {
fn GetInnerHTML(&self) -> Fallible<DOMString> {
//XXX TODO: XML case
self.serialize(ChildrenOnly)
}
// 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 = NodeCast::from_ref(self);
// Step 1.
let frag = try!(context_node.parse_fragment(value));
@ -1401,12 +1324,12 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML
fn GetOuterHTML(self) -> Fallible<DOMString> {
fn GetOuterHTML(&self) -> Fallible<DOMString> {
self.serialize(IncludeNode)
}
// 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);
let context_node = NodeCast::from_ref(self);
// Step 1.
@ -1441,83 +1364,83 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
fn GetPreviousElementSibling(self) -> Option<Root<Element>> {
fn GetPreviousElementSibling(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).preceding_siblings()
.filter_map(ElementCast::to_root).next()
}
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
fn GetNextElementSibling(self) -> Option<Root<Element>> {
fn GetNextElementSibling(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).following_siblings()
.filter_map(ElementCast::to_root).next()
}
// https://dom.spec.whatwg.org/#dom-parentnode-children
fn Children(self) -> Root<HTMLCollection> {
fn Children(&self) -> Root<HTMLCollection> {
let window = window_from_node(self);
HTMLCollection::children(window.r(), NodeCast::from_ref(self))
}
// https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild
fn GetFirstElementChild(self) -> Option<Root<Element>> {
fn GetFirstElementChild(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).child_elements().next()
}
// https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild
fn GetLastElementChild(self) -> Option<Root<Element>> {
fn GetLastElementChild(&self) -> Option<Root<Element>> {
NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next()
}
// https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
fn ChildElementCount(self) -> u32 {
fn ChildElementCount(&self) -> u32 {
NodeCast::from_ref(self).child_elements().count() as u32
}
// https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).prepend(nodes)
}
// https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).append(nodes)
}
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector
fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
let root = NodeCast::from_ref(self);
root.query_selector(selectors)
}
// https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> {
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Root<NodeList>> {
let root = NodeCast::from_ref(self);
root.query_selector_all(selectors)
}
// https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).before(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-after
fn After(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).after(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(self, nodes: Vec<NodeOrString>) -> ErrorResult {
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
NodeCast::from_ref(self).replace_with(nodes)
}
// https://dom.spec.whatwg.org/#dom-childnode-remove
fn Remove(self) {
fn Remove(&self) {
let node = NodeCast::from_ref(self);
node.remove_self();
}
// https://dom.spec.whatwg.org/#dom-element-matches
fn Matches(self, selectors: DOMString) -> Fallible<bool> {
fn Matches(&self, selectors: DOMString) -> Fallible<bool> {
match parse_author_origin_selector_list_from_str(&selectors) {
Err(()) => Err(Syntax),
Ok(ref selectors) => {
@ -1527,7 +1450,7 @@ impl<'a> ElementMethods for &'a Element {
}
// https://dom.spec.whatwg.org/#dom-element-closest
fn Closest(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
fn Closest(&self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
match parse_author_origin_selector_list_from_str(&selectors) {
Err(()) => Err(Syntax),
Ok(ref selectors) => {
@ -1545,9 +1468,9 @@ impl<'a> ElementMethods for &'a Element {
}
}
impl<'a> VirtualMethods for &'a Element {
impl VirtualMethods for Element {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let node: &&Node = NodeCast::from_borrowed_ref(self);
let node: &Node = NodeCast::from_ref(self);
Some(node as &VirtualMethods)
}
@ -1556,11 +1479,11 @@ impl<'a> VirtualMethods for &'a Element {
s.after_set_attr(attr);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
match attr.local_name() {
&atom!("style") => {
// Modifying the `style` attribute might change style.
let doc = document_from_node(*self);
let doc = document_from_node(self);
let base_url = doc.r().base_url();
let value = attr.value();
let style = Some(parse_style_attribute(&value, &base_url));
@ -1573,7 +1496,7 @@ impl<'a> VirtualMethods for &'a Element {
&atom!("class") => {
// Modifying a class can change style.
if node.is_in_doc() {
let document = document_from_node(*self);
let document = document_from_node(self);
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
}
}
@ -1581,10 +1504,10 @@ impl<'a> VirtualMethods for &'a Element {
// Modifying an ID might change style.
let value = attr.value();
if node.is_in_doc() {
let doc = document_from_node(*self);
let doc = document_from_node(self);
if !value.is_empty() {
let value = value.atom().unwrap().clone();
doc.r().register_named_element(*self, value);
doc.r().register_named_element(self, value);
}
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
}
@ -1592,7 +1515,7 @@ impl<'a> VirtualMethods for &'a Element {
_ => {
// Modifying any other attribute might change arbitrary things.
if node.is_in_doc() {
let document = document_from_node(*self);
let document = document_from_node(self);
document.r().content_changed(node, NodeDamage::OtherNodeDamage);
}
}
@ -1604,14 +1527,14 @@ impl<'a> VirtualMethods for &'a Element {
s.before_remove_attr(attr);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
match attr.local_name() {
&atom!("style") => {
// Modifying the `style` attribute might change style.
*self.style_attribute.borrow_mut() = None;
if node.is_in_doc() {
let doc = document_from_node(*self);
let doc = document_from_node(self);
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
}
}
@ -1619,10 +1542,10 @@ impl<'a> VirtualMethods for &'a Element {
// Modifying an ID can change style.
let value = attr.value();
if node.is_in_doc() {
let doc = document_from_node(*self);
let doc = document_from_node(self);
if !value.is_empty() {
let value = value.atom().unwrap().clone();
doc.r().unregister_named_element(*self, value);
doc.r().unregister_named_element(self, value);
}
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
}
@ -1630,14 +1553,14 @@ impl<'a> VirtualMethods for &'a Element {
&atom!("class") => {
// Modifying a class can change style.
if node.is_in_doc() {
let document = document_from_node(*self);
let document = document_from_node(self);
document.r().content_changed(node, NodeDamage::NodeStyleDamaged);
}
}
_ => {
// Modifying any other attribute might change arbitrary things.
if node.is_in_doc() {
let doc = document_from_node(*self);
let doc = document_from_node(self);
doc.r().content_changed(node, NodeDamage::OtherNodeDamage);
}
}
@ -1660,11 +1583,11 @@ impl<'a> VirtualMethods for &'a Element {
if !tree_in_doc { return; }
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) {
let doc = document_from_node(*self);
let doc = document_from_node(self);
let value = attr.r().Value();
if !value.is_empty() {
let value = Atom::from_slice(&value);
doc.r().register_named_element(*self, value);
doc.r().register_named_element(self, value);
}
}
}
@ -1677,11 +1600,11 @@ impl<'a> VirtualMethods for &'a Element {
if !tree_in_doc { return; }
if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) {
let doc = document_from_node(*self);
let doc = document_from_node(self);
let value = attr.r().Value();
if !value.is_empty() {
let value = Atom::from_slice(&value);
doc.r().unregister_named_element(*self, value);
doc.r().unregister_named_element(self, value);
}
}
}
@ -1747,7 +1670,7 @@ impl<'a> ::selectors::Element for Root<Element> {
}
fn get_local_name<'b>(&'b self) -> &'b Atom {
ElementHelpers::local_name(&**self)
self.local_name()
}
fn get_namespace<'b>(&'b self) -> &'b Namespace {
self.namespace()
@ -1798,7 +1721,7 @@ impl<'a> ::selectors::Element for Root<Element> {
}
}
fn has_class(&self, name: &Atom) -> bool {
AttributeHandlers::has_class(&**self, name)
Element::has_class(&**self, name)
}
fn each_class<F>(&self, mut callback: F)
where F: FnMut(&Atom)
@ -1859,24 +1782,17 @@ impl<'a> ::selectors::Element for Root<Element> {
}
}
pub trait ActivationElementHelpers<'a> {
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)>;
fn click_in_progress(self) -> bool;
fn set_click_in_progress(self, click: bool);
fn nearest_activable_element(self) -> Option<Root<Element>>;
fn authentic_click_activation<'b>(self, event: &'b Event);
}
impl<'a> ActivationElementHelpers<'a> for &'a Element {
fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)> {
let node = NodeCast::from_ref(*self);
impl Element {
pub fn as_maybe_activatable<'a>(&'a self) -> Option<&'a (Activatable + 'a)> {
let node = NodeCast::from_ref(self);
let element = match node.type_id() {
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
let element = HTMLInputElementCast::to_borrowed_ref(self).unwrap();
let element = HTMLInputElementCast::to_ref(self).unwrap();
Some(element as &'a (Activatable + 'a))
},
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => {
let element = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap();
let element = HTMLAnchorElementCast::to_ref(self).unwrap();
Some(element as &'a (Activatable + 'a))
},
_ => {
@ -1892,18 +1808,18 @@ impl<'a> ActivationElementHelpers<'a> for &'a Element {
})
}
fn click_in_progress(self) -> bool {
pub fn click_in_progress(&self) -> bool {
let node = NodeCast::from_ref(self);
node.get_flag(CLICK_IN_PROGRESS)
}
fn set_click_in_progress(self, click: bool) {
pub fn set_click_in_progress(&self, click: bool) {
let node = NodeCast::from_ref(self);
node.set_flag(CLICK_IN_PROGRESS, click)
}
// https://html.spec.whatwg.org/multipage/#nearest-activatable-element
fn nearest_activable_element(self) -> Option<Root<Element>> {
pub fn nearest_activable_element(&self) -> Option<Root<Element>> {
match self.as_maybe_activatable() {
Some(el) => Some(Root::from_ref(el.as_element())),
None => {
@ -1926,7 +1842,7 @@ impl<'a> ActivationElementHelpers<'a> for &'a Element {
///
/// Use an element's synthetic click activation (or handle_event) for any script-triggered clicks.
/// If the spec says otherwise, check with Manishearth first
fn authentic_click_activation<'b>(self, event: &'b Event) {
pub fn authentic_click_activation<'b>(&self, event: &'b Event) {
// Not explicitly part of the spec, however this helps enforce the invariants
// required to save state between pre-activation and post-activation
// since we cannot nest authentic clicks (unlike synthetic click activation, where

View file

@ -22,7 +22,6 @@ use std::borrow::ToOwned;
use std::cell::Cell;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct ErrorEvent {
event: Event,
message: DOMRefCell<DOMString>,
@ -115,29 +114,29 @@ impl ErrorEvent {
}
impl<'a> ErrorEventMethods for &'a ErrorEvent {
impl ErrorEventMethods for ErrorEvent {
// https://html.spec.whatwg.org/multipage/#dom-errorevent-lineno
fn Lineno(self) -> u32 {
fn Lineno(&self) -> u32 {
self.lineno.get()
}
// https://html.spec.whatwg.org/multipage/#dom-errorevent-colno
fn Colno(self) -> u32 {
fn Colno(&self) -> u32 {
self.colno.get()
}
// https://html.spec.whatwg.org/multipage/#dom-errorevent-message
fn Message(self) -> DOMString {
fn Message(&self) -> DOMString {
self.message.borrow().clone()
}
// https://html.spec.whatwg.org/multipage/#dom-errorevent-filename
fn Filename(self) -> DOMString {
fn Filename(&self) -> DOMString {
self.filename.borrow().clone()
}
// https://html.spec.whatwg.org/multipage/#dom-errorevent-error
fn Error(self, _cx: *mut JSContext) -> JSVal {
fn Error(&self, _cx: *mut JSContext) -> JSVal {
self.error.get()
}

View file

@ -9,7 +9,7 @@ use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::eventtarget::{EventTarget, EventTargetHelpers};
use dom::eventtarget::EventTarget;
use dom::uievent::{UIEventTypeId};
use util::str::DOMString;
@ -54,7 +54,6 @@ pub enum EventCancelable {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct Event {
reflector_: Reflector,
type_id: EventTypeId,
@ -173,67 +172,67 @@ impl Event {
}
}
impl<'a> EventMethods for &'a Event {
impl EventMethods for Event {
// https://dom.spec.whatwg.org/#dom-event-eventphase
fn EventPhase(self) -> u16 {
fn EventPhase(&self) -> u16 {
self.phase.get() as u16
}
// https://dom.spec.whatwg.org/#dom-event-type
fn Type(self) -> DOMString {
fn Type(&self) -> DOMString {
self.type_.borrow().clone()
}
// https://dom.spec.whatwg.org/#dom-event-target
fn GetTarget(self) -> Option<Root<EventTarget>> {
fn GetTarget(&self) -> Option<Root<EventTarget>> {
self.target.get().map(Root::from_rooted)
}
// https://dom.spec.whatwg.org/#dom-event-currenttarget
fn GetCurrentTarget(self) -> Option<Root<EventTarget>> {
fn GetCurrentTarget(&self) -> Option<Root<EventTarget>> {
self.current_target.get().map(Root::from_rooted)
}
// https://dom.spec.whatwg.org/#dom-event-defaultprevented
fn DefaultPrevented(self) -> bool {
fn DefaultPrevented(&self) -> bool {
self.canceled.get()
}
// https://dom.spec.whatwg.org/#dom-event-preventdefault
fn PreventDefault(self) {
fn PreventDefault(&self) {
if self.cancelable.get() {
self.canceled.set(true)
}
}
// https://dom.spec.whatwg.org/#dom-event-stoppropagation
fn StopPropagation(self) {
fn StopPropagation(&self) {
self.stop_propagation.set(true);
}
// https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation
fn StopImmediatePropagation(self) {
fn StopImmediatePropagation(&self) {
self.stop_immediate.set(true);
self.stop_propagation.set(true);
}
// https://dom.spec.whatwg.org/#dom-event-bubbles
fn Bubbles(self) -> bool {
fn Bubbles(&self) -> bool {
self.bubbles.get()
}
// https://dom.spec.whatwg.org/#dom-event-cancelable
fn Cancelable(self) -> bool {
fn Cancelable(&self) -> bool {
self.cancelable.get()
}
// https://dom.spec.whatwg.org/#dom-event-timestamp
fn TimeStamp(self) -> u64 {
fn TimeStamp(&self) -> u64 {
self.timestamp
}
// https://dom.spec.whatwg.org/#dom-event-initevent
fn InitEvent(self,
fn InitEvent(&self,
type_: DOMString,
bubbles: bool,
cancelable: bool) {
@ -253,23 +252,19 @@ impl<'a> EventMethods for &'a Event {
}
// https://dom.spec.whatwg.org/#dom-event-istrusted
fn IsTrusted(self) -> bool {
fn IsTrusted(&self) -> bool {
self.trusted.get()
}
}
pub trait EventHelpers {
fn set_trusted(self, trusted: bool);
fn fire(self, target: &EventTarget) -> bool;
}
impl<'a> EventHelpers for &'a Event {
fn set_trusted(self, trusted: bool) {
impl Event {
pub fn set_trusted(&self, trusted: bool) {
self.trusted.set(trusted);
}
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event
fn fire(self, target: &EventTarget) -> bool {
pub fn fire(&self, target: &EventTarget) -> bool {
self.set_trusted(true);
target.dispatch_event(self)
}

View file

@ -9,7 +9,7 @@ use dom::bindings::js::JS;
use dom::bindings::trace::RootedVec;
use dom::event::{Event, EventPhase};
use dom::eventtarget::{EventTarget, ListenerPhase};
use dom::node::{Node, NodeHelpers};
use dom::node::Node;
use dom::virtualmethods::vtable_for;
// See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm

View file

@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::error::Error::InvalidState;
use dom::bindings::error::{Fallible, report_pending_exception};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::event::{Event, EventHelpers};
use dom::event::Event;
use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId;
use dom::virtualmethods::VirtualMethods;
@ -130,7 +130,6 @@ pub struct EventListenerEntry {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct EventTarget {
reflector_: Reflector,
type_id: EventTargetTypeId,
@ -164,42 +163,18 @@ impl EventTarget {
pub fn type_id<'a>(&'a self) -> &'a EventTargetTypeId {
&self.type_id
}
}
pub trait EventTargetHelpers {
fn dispatch_event_with_target(self,
target: &EventTarget,
event: &Event) -> bool;
fn dispatch_event(self, event: &Event) -> bool;
fn set_inline_event_listener(self,
ty: DOMString,
listener: Option<Rc<EventHandler>>);
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventHandler>>;
fn set_event_handler_uncompiled(self,
cx: *mut JSContext,
url: Url,
scope: HandleObject,
ty: &str,
source: DOMString);
fn set_event_handler_common<T: CallbackContainer>(self, ty: &str,
listener: Option<Rc<T>>);
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>>;
fn has_handlers(self) -> bool;
}
impl<'a> EventTargetHelpers for &'a EventTarget {
fn dispatch_event_with_target(self,
pub fn dispatch_event_with_target(&self,
target: &EventTarget,
event: &Event) -> bool {
dispatch_event(self, Some(target), event)
}
fn dispatch_event(self, event: &Event) -> bool {
pub fn dispatch_event(&self, event: &Event) -> bool {
dispatch_event(self, None, event)
}
fn set_inline_event_listener(self,
pub fn set_inline_event_listener(&self,
ty: DOMString,
listener: Option<Rc<EventHandler>>) {
let mut handlers = self.handlers.borrow_mut();
@ -235,7 +210,7 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
}
}
fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventHandler>> {
pub fn get_inline_event_listener(&self, ty: DOMString) -> Option<Rc<EventHandler>> {
let handlers = self.handlers.borrow();
let entries = handlers.get(&ty);
entries.and_then(|entries| entries.iter().filter_map(|entry| {
@ -247,7 +222,7 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
}
#[allow(unsafe_code)]
fn set_event_handler_uncompiled(self,
pub fn set_event_handler_uncompiled(&self,
cx: *mut JSContext,
url: Url,
scope: HandleObject,
@ -288,27 +263,27 @@ impl<'a> EventTargetHelpers for &'a EventTarget {
self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
}
fn set_event_handler_common<T: CallbackContainer>(
self, ty: &str, listener: Option<Rc<T>>)
pub fn set_event_handler_common<T: CallbackContainer>(
&self, ty: &str, listener: Option<Rc<T>>)
{
let event_listener = listener.map(|listener|
EventHandlerNonNull::new(listener.callback()));
self.set_inline_event_listener(ty.to_owned(), event_listener);
}
fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>> {
pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> {
let listener = self.get_inline_event_listener(ty.to_owned());
listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
}
fn has_handlers(self) -> bool {
pub fn has_handlers(&self) -> bool {
!self.handlers.borrow().is_empty()
}
}
impl<'a> EventTargetMethods for &'a EventTarget {
impl EventTargetMethods for EventTarget {
// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
fn AddEventListener(self,
fn AddEventListener(&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
capture: bool) {
@ -334,7 +309,7 @@ impl<'a> EventTargetMethods for &'a EventTarget {
}
// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
fn RemoveEventListener(self,
fn RemoveEventListener(&self,
ty: DOMString,
listener: Option<Rc<EventListener>>,
capture: bool) {
@ -358,7 +333,7 @@ impl<'a> EventTargetMethods for &'a EventTarget {
}
// https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
fn DispatchEvent(self, event: &Event) -> Fallible<bool> {
fn DispatchEvent(&self, event: &Event) -> Fallible<bool> {
if event.dispatching() || !event.initialized() {
return Err(InvalidState);
}
@ -367,7 +342,7 @@ impl<'a> EventTargetMethods for &'a EventTarget {
}
}
impl<'a> VirtualMethods for &'a EventTarget {
impl VirtualMethods for EventTarget {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
None
}

View file

@ -11,7 +11,6 @@ use dom::blob::{Blob, BlobTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct File {
blob: Blob,
name: DOMString,
@ -40,10 +39,9 @@ impl File {
}
}
impl<'a> FileMethods for &'a File {
impl FileMethods for File {
// https://w3c.github.io/FileAPI/#dfn-name
fn Name(self) -> DOMString {
fn Name(&self) -> DOMString {
self.name.clone()
}
}

View file

@ -12,7 +12,6 @@ use dom::window::Window;
// https://w3c.github.io/FileAPI/#dfn-filelist
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct FileList {
reflector_: Reflector,
list: Vec<JS<File>>
@ -31,22 +30,21 @@ impl FileList {
}
}
impl<'a> FileListMethods for &'a FileList {
impl FileListMethods for FileList {
// https://w3c.github.io/FileAPI/#dfn-length
fn Length(self) -> u32 {
fn Length(&self) -> u32 {
self.list.len() as u32
}
// https://w3c.github.io/FileAPI/#dfn-item
fn Item(self, index: u32) -> Option<Root<File>> {
fn Item(&self, index: u32) -> Option<Root<File>> {
Some(self.list[index as usize].root())
}
// check-tidy: no specs after this line
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<File>> {
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<File>> {
let item = self.Item(index);
*found = item.is_some();
item
}
}

View file

@ -12,16 +12,17 @@ use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{Root, JS, MutNullableHeap};
use dom::bindings::refcounted::Trusted;
use dom::bindings::utils::{reflect_dom_object, Reflectable};
use dom::blob::{Blob, BlobHelpers};
use dom::blob::Blob;
use dom::domexception::{DOMException, DOMErrorName};
use dom::event::{EventHelpers, EventCancelable, EventBubbles};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::event::{EventCancelable, EventBubbles};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::progressevent::ProgressEvent;
use encoding::all::UTF_8;
use encoding::label::encoding_from_whatwg_label;
use encoding::types::{EncodingRef, DecoderTrap};
use hyper::mime::{Mime, Attr};
use rustc_serialize::base64::{Config, ToBase64, CharacterSet, Newline};
use script_task::ScriptTaskEventCategory::FileRead;
use script_task::{ScriptChan, Runnable, ScriptPort, CommonScriptMsg};
use std::cell::{Cell, RefCell};
use std::sync::mpsc;
@ -67,7 +68,6 @@ pub enum FileReaderReadyState {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct FileReader {
eventtarget: EventTarget,
global: GlobalField,
@ -252,27 +252,38 @@ impl FileReader {
}
}
impl<'a> FileReaderMethods for &'a FileReader {
impl FileReaderMethods for FileReader {
// https://w3c.github.io/FileAPI/#dfn-onloadstart
event_handler!(loadstart, GetOnloadstart, SetOnloadstart);
// https://w3c.github.io/FileAPI/#dfn-onprogress
event_handler!(progress, GetOnprogress, SetOnprogress);
// https://w3c.github.io/FileAPI/#dfn-onload
event_handler!(load, GetOnload, SetOnload);
// https://w3c.github.io/FileAPI/#dfn-onabort
event_handler!(abort, GetOnabort, SetOnabort);
// https://w3c.github.io/FileAPI/#dfn-onerror
event_handler!(error, GetOnerror, SetOnerror);
// https://w3c.github.io/FileAPI/#dfn-onloadend
event_handler!(loadend, GetOnloadend, SetOnloadend);
//TODO https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer
// https://w3c.github.io/FileAPI/#dfn-readAsDataURL
fn ReadAsDataURL(self, blob: &Blob) -> ErrorResult {
fn ReadAsDataURL(&self, blob: &Blob) -> ErrorResult {
self.read(FileReaderFunction::ReadAsDataUrl, blob, None)
}
// https://w3c.github.io/FileAPI/#dfn-readAsText
fn ReadAsText(self, blob: &Blob, label: Option<DOMString>) -> ErrorResult {
fn ReadAsText(&self, blob: &Blob, label: Option<DOMString>) -> ErrorResult {
self.read(FileReaderFunction::ReadAsText, blob, label)
}
// https://w3c.github.io/FileAPI/#dfn-abort
fn Abort(self) {
fn Abort(&self) {
// Step 2
if self.ready_state.get() == FileReaderReadyState::Loading {
self.change_ready_state(FileReaderReadyState::Done);
@ -291,30 +302,24 @@ impl<'a> FileReaderMethods for &'a FileReader {
}
// https://w3c.github.io/FileAPI/#dfn-error
fn GetError(self) -> Option<Root<DOMException>> {
fn GetError(&self) -> Option<Root<DOMException>> {
self.error.get().map(|error| error.root())
}
// https://w3c.github.io/FileAPI/#dfn-result
fn GetResult(self) -> Option<DOMString> {
fn GetResult(&self) -> Option<DOMString> {
self.result.borrow().clone()
}
// https://w3c.github.io/FileAPI/#dfn-readyState
fn ReadyState(self) -> u16 {
fn ReadyState(&self) -> u16 {
self.ready_state.get() as u16
}
}
trait PrivateFileReaderHelpers {
fn dispatch_progress_event(self, type_: DOMString, loaded: u64, total: Option<u64>);
fn terminate_ongoing_reading(self);
fn read(self, function: FileReaderFunction, blob: &Blob, label: Option<DOMString>) -> ErrorResult;
fn change_ready_state(self, state: FileReaderReadyState);
}
impl<'a> PrivateFileReaderHelpers for &'a FileReader {
fn dispatch_progress_event(self, type_: DOMString, loaded: u64, total: Option<u64>) {
impl FileReader {
fn dispatch_progress_event(&self, type_: DOMString, loaded: u64, total: Option<u64>) {
let global = self.global.root();
let progressevent = ProgressEvent::new(global.r(),
@ -326,12 +331,12 @@ impl<'a> PrivateFileReaderHelpers for &'a FileReader {
event.fire(target);
}
fn terminate_ongoing_reading(self) {
fn terminate_ongoing_reading(&self) {
let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1));
}
fn read(self, function: FileReaderFunction, blob: &Blob, label: Option<DOMString>) -> ErrorResult {
fn read(&self, function: FileReaderFunction, blob: &Blob, label: Option<DOMString>) -> ErrorResult {
let root = self.global.root();
let global = root.r();
// Step 1
@ -369,7 +374,7 @@ impl<'a> PrivateFileReaderHelpers for &'a FileReader {
Ok(())
}
fn change_ready_state(self, state: FileReaderReadyState) {
fn change_ready_state(&self, state: FileReaderReadyState) {
self.ready_state.set(state);
}
}
@ -408,22 +413,22 @@ fn perform_annotated_read_operation(gen_id: GenerationId, data: ReadMetaData, bl
let chan = &script_chan;
// Step 4
let task = box FileReaderEvent::ProcessRead(filereader.clone(), gen_id);
chan.send(CommonScriptMsg::RunnableMsg(task)).unwrap();
chan.send(CommonScriptMsg::RunnableMsg(FileRead, task)).unwrap();
let task = box FileReaderEvent::ProcessReadData(filereader.clone(),
gen_id, DOMString::new());
chan.send(CommonScriptMsg::RunnableMsg(task)).unwrap();
chan.send(CommonScriptMsg::RunnableMsg(FileRead, task)).unwrap();
let bytes = match blob_contents.recv() {
Ok(bytes) => bytes,
Err(_) => {
let task = box FileReaderEvent::ProcessReadError(filereader,
gen_id, DOMErrorName::NotFoundError);
chan.send(CommonScriptMsg::RunnableMsg(task)).unwrap();
chan.send(CommonScriptMsg::RunnableMsg(FileRead, task)).unwrap();
return;
}
};
let task = box FileReaderEvent::ProcessReadEOF(filereader, gen_id, data, bytes);
chan.send(CommonScriptMsg::RunnableMsg(task)).unwrap();
chan.send(CommonScriptMsg::RunnableMsg(FileRead, task)).unwrap();
}

View file

@ -30,7 +30,6 @@ pub enum FormDatum {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct FormData {
reflector_: Reflector,
data: DOMRefCell<HashMap<DOMString, Vec<FormDatum>>>,
@ -58,10 +57,10 @@ impl FormData {
}
}
impl<'a> FormDataMethods for &'a FormData {
impl FormDataMethods for FormData {
#[allow(unrooted_must_root)]
// https://xhr.spec.whatwg.org/#dom-formdata-append
fn Append(self, name: DOMString, value: &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 mut data = self.data.borrow_mut();
match data.entry(name) {
@ -73,7 +72,7 @@ impl<'a> FormDataMethods for &'a FormData {
}
// https://xhr.spec.whatwg.org/#dom-formdata-append
fn Append_(self, name: DOMString, value: DOMString) {
fn Append_(&self, name: DOMString, value: DOMString) {
let mut data = self.data.borrow_mut();
match data.entry(name) {
Occupied(entry) => entry.into_mut().push(FormDatum::StringData(value)),
@ -82,51 +81,41 @@ impl<'a> FormDataMethods for &'a FormData {
}
// https://xhr.spec.whatwg.org/#dom-formdata-delete
fn Delete(self, name: DOMString) {
fn Delete(&self, name: DOMString) {
self.data.borrow_mut().remove(&name);
}
#[allow(unsafe_code)]
// https://xhr.spec.whatwg.org/#dom-formdata-get
fn Get(self, name: DOMString) -> Option<FileOrString> {
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let data = self.data.borrow();
if data.contains_key(&name) {
match data[&name][0].clone() {
FormDatum::StringData(ref s) => Some(eString(s.clone())),
FormDatum::FileData(ref f) => {
Some(eFile(f.root()))
}
}
} else {
None
}
fn Get(&self, name: DOMString) -> Option<FileOrString> {
self.data.borrow()
.get(&name)
.map(|entry| match entry[0] {
FormDatum::StringData(ref s) => eString(s.clone()),
FormDatum::FileData(ref f) => eFile(f.root()),
})
}
// https://xhr.spec.whatwg.org/#dom-formdata-has
fn Has(self, name: DOMString) -> bool {
fn Has(&self, name: DOMString) -> bool {
self.data.borrow().contains_key(&name)
}
// https://xhr.spec.whatwg.org/#dom-formdata-set
fn Set_(self, name: DOMString, value: DOMString) {
fn Set_(&self, name: DOMString, value: DOMString) {
self.data.borrow_mut().insert(name, vec!(FormDatum::StringData(value)));
}
#[allow(unrooted_must_root)]
// https://xhr.spec.whatwg.org/#dom-formdata-set
fn Set(self, name: DOMString, value: &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)));
self.data.borrow_mut().insert(name, vec!(file));
}
}
trait PrivateFormDataHelpers {
fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File>;
}
impl<'a> PrivateFormDataHelpers for &'a FormData {
fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File> {
impl FormData {
fn get_file_from_blob(&self, value: &Blob, filename: Option<DOMString>) -> Root<File> {
let global = self.global.root();
let f: Option<&File> = FileCast::to_ref(value);
let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".to_owned()));

View file

@ -14,15 +14,14 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLImageElementDerived};
use dom::bindings::codegen::InheritTypes::{MouseEventCast, NodeCast};
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::document::{Document, DocumentHelpers};
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
use dom::element::{Element, AttributeHandlers, ElementTypeId};
use dom::element::{Element, ElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use dom::node::{Node, NodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use util::str::DOMString;
@ -33,7 +32,6 @@ use url::UrlParser;
use std::default::Default;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLAnchorElement {
htmlelement: HTMLElement,
rel_list: MutNullableHeap<JS<DOMTokenList>>,
@ -67,9 +65,9 @@ impl HTMLAnchorElement {
}
}
impl<'a> VirtualMethods for &'a HTMLAnchorElement {
impl VirtualMethods for HTMLAnchorElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -81,30 +79,30 @@ impl<'a> VirtualMethods for &'a HTMLAnchorElement {
}
}
impl<'a> HTMLAnchorElementMethods for &'a HTMLAnchorElement {
impl HTMLAnchorElementMethods for HTMLAnchorElement {
// https://html.spec.whatwg.org/multipage/#dom-a-text
fn Text(self) -> DOMString {
fn Text(&self) -> DOMString {
let node = NodeCast::from_ref(self);
node.GetTextContent().unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-a-text
fn SetText(self, value: DOMString) {
fn SetText(&self, value: DOMString) {
let node = NodeCast::from_ref(self);
node.SetTextContent(Some(value))
}
// https://html.spec.whatwg.org/multipage/#dom-a-rellist
fn RelList(self) -> Root<DOMTokenList> {
fn RelList(&self) -> Root<DOMTokenList> {
self.rel_list.or_init(|| {
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
})
}
}
impl<'a> Activatable for &'a HTMLAnchorElement {
impl Activatable for HTMLAnchorElement {
fn as_element<'b>(&'b self) -> &'b Element {
ElementCast::from_ref(*self)
ElementCast::from_ref(self)
}
fn is_instance_activatable(&self) -> bool {
@ -113,7 +111,7 @@ impl<'a> Activatable for &'a HTMLAnchorElement {
// hyperlink"
// https://html.spec.whatwg.org/multipage/#the-a-element
// "The activation behaviour of a elements *that create hyperlinks*"
ElementCast::from_ref(*self).has_attribute(&atom!("href"))
ElementCast::from_ref(self).has_attribute(&atom!("href"))
}
@ -129,13 +127,13 @@ impl<'a> Activatable for &'a HTMLAnchorElement {
//https://html.spec.whatwg.org/multipage/#the-a-element:activation-behaviour
fn activation_behavior(&self, event: &Event, target: &EventTarget) {
//Step 1. If the node document is not fully active, abort.
let doc = document_from_node(*self);
let doc = document_from_node(self);
if !doc.r().is_fully_active() {
return;
}
//TODO: Step 2. Check if browsing context is specified and act accordingly.
//Step 3. Handle <img ismap/>.
let element = ElementCast::from_ref(*self);
let element = ElementCast::from_ref(self);
let mouse_event = MouseEventCast::to_ref(event).unwrap();
let mut ismap_suffix = None;
if let Some(element) = ElementCast::to_ref(target) {

View file

@ -10,7 +10,7 @@ use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::js::Root;
use dom::document::Document;
use dom::element::{AttributeHandlers, ElementTypeId};
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeTypeId};
@ -20,7 +20,6 @@ use string_cache::Atom;
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLAppletElement {
htmlelement: HTMLElement
}
@ -52,15 +51,17 @@ impl HTMLAppletElement {
}
}
impl<'a> HTMLAppletElementMethods for &'a HTMLAppletElement {
impl HTMLAppletElementMethods for HTMLAppletElement {
// https://html.spec.whatwg.org/#the-applet-element:dom-applet-name
make_getter!(Name);
// https://html.spec.whatwg.org/#the-applet-element:dom-applet-name
make_atomic_setter!(SetName, "name");
}
impl<'a> VirtualMethods for &'a HTMLAppletElement {
impl VirtualMethods for HTMLAppletElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
Some(HTMLElementCast::from_ref(self) as &VirtualMethods)
}
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {

View file

@ -14,7 +14,7 @@ use dom::domtokenlist::DOMTokenList;
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId};
use dom::node::{Node, NodeTypeId};
use dom::virtualmethods::VirtualMethods;
use std::default::Default;
@ -22,7 +22,6 @@ use string_cache::Atom;
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLAreaElement {
htmlelement: HTMLElement,
rel_list: MutNullableHeap<JS<DOMTokenList>>,
@ -53,9 +52,9 @@ impl HTMLAreaElement {
}
}
impl<'a> VirtualMethods for &'a HTMLAreaElement {
impl VirtualMethods for HTMLAreaElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -67,9 +66,9 @@ impl<'a> VirtualMethods for &'a HTMLAreaElement {
}
}
impl<'a> HTMLAreaElementMethods for &'a HTMLAreaElement {
impl HTMLAreaElementMethods for HTMLAreaElement {
// https://html.spec.whatwg.org/multipage/#dom-area-rellist
fn RelList(self) -> Root<DOMTokenList> {
fn RelList(&self) -> Root<DOMTokenList> {
self.rel_list.or_init(|| {
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
})

View file

@ -14,7 +14,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLAudioElement {
htmlmediaelement: HTMLMediaElement
}
@ -46,4 +45,3 @@ impl HTMLAudioElement {
Node::reflect_node(box element, document, HTMLAudioElementBinding::Wrap)
}
}

View file

@ -2,14 +2,14 @@
* 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/. */
use dom::attr::{Attr, AttrHelpers};
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLBaseElementBinding;
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::js::Root;
use dom::document::{Document, DocumentHelpers};
use dom::element::{ElementTypeId, AttributeHandlers};
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeTypeId, document_from_node};
@ -19,7 +19,6 @@ use util::str::DOMString;
use url::{Url, UrlParser};
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLBaseElement {
htmlelement: HTMLElement
}
@ -80,9 +79,9 @@ impl HTMLBaseElement {
}
}
impl<'a> VirtualMethods for &'a HTMLBaseElement {
impl VirtualMethods for HTMLBaseElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
Some(HTMLElementCast::from_ref(self) as &VirtualMethods)
}
fn after_set_attr(&self, attr: &Attr) {

View file

@ -2,7 +2,7 @@
* 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/. */
use dom::attr::{Attr, AttrHelpers};
use dom::attr::Attr;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyElementMethods};
@ -11,13 +11,12 @@ use dom::bindings::codegen::InheritTypes::{EventTargetCast};
use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast};
use dom::bindings::js::Root;
use dom::bindings::utils::Reflectable;
use dom::document::{Document, DocumentHelpers};
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeTypeId, window_from_node, document_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use msg::constellation_msg::ConstellationChan;
use msg::constellation_msg::Msg as ConstellationMsg;
@ -35,7 +34,6 @@ use time;
const INITIAL_REFLOW_DELAY: u64 = 200_000_000;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLBodyElement {
htmlelement: HTMLElement,
background_color: Cell<Option<RGBA>>,
@ -70,45 +68,43 @@ impl HTMLBodyElement {
}
}
impl<'a> HTMLBodyElementMethods for &'a HTMLBodyElement {
impl HTMLBodyElementMethods for HTMLBodyElement {
// https://html.spec.whatwg.org/multipage#dom-body-bgcolor
make_getter!(BgColor, "bgcolor");
// https://html.spec.whatwg.org/multipage#dom-body-bgcolor
make_setter!(SetBgColor, "bgcolor");
// https://html.spec.whatwg.org/multipage/#the-body-element
fn GetOnunload(self) -> Option<Rc<EventHandlerNonNull>> {
fn GetOnunload(&self) -> Option<Rc<EventHandlerNonNull>> {
let win = window_from_node(self);
win.r().GetOnunload()
}
// https://html.spec.whatwg.org/multipage/#the-body-element
fn SetOnunload(self, listener: Option<Rc<EventHandlerNonNull>>) {
fn SetOnunload(&self, listener: Option<Rc<EventHandlerNonNull>>) {
let win = window_from_node(self);
win.r().SetOnunload(listener)
}
}
pub trait HTMLBodyElementHelpers {
fn get_background_color(self) -> Option<RGBA>;
fn get_background(self) -> Option<Url>;
}
impl<'a> HTMLBodyElementHelpers for &'a HTMLBodyElement {
fn get_background_color(self) -> Option<RGBA> {
impl HTMLBodyElement {
pub fn get_background_color(&self) -> Option<RGBA> {
self.background_color.get()
}
#[allow(unsafe_code)]
fn get_background(self) -> Option<Url> {
pub fn get_background(&self) -> Option<Url> {
unsafe {
self.background.borrow_for_layout().clone()
}
}
}
impl<'a> VirtualMethods for &'a HTMLBodyElement {
impl VirtualMethods for HTMLBodyElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let element: &HTMLElement = HTMLElementCast::from_ref(self);
Some(element as &VirtualMethods)
}
@ -121,7 +117,7 @@ impl<'a> VirtualMethods for &'a HTMLBodyElement {
return
}
let window = window_from_node(*self);
let window = window_from_node(self);
let document = window.r().Document();
document.r().set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
let ConstellationChan(ref chan) = window.r().constellation_chan();
@ -141,7 +137,7 @@ impl<'a> VirtualMethods for &'a HTMLBodyElement {
"onbeforeunload", "onhashchange", "onlanguagechange", "onmessage",
"onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate",
"onstorage", "onresize", "onunload", "onerror"];
let window = window_from_node(*self);
let window = window_from_node(self);
let (cx, url, reflector) = (window.r().get_cx(),
window.r().get_url(),
window.r().reflector().get_jsobject());
@ -149,7 +145,7 @@ impl<'a> VirtualMethods for &'a HTMLBodyElement {
if FORWARDED_EVENTS.iter().any(|&event| &**name == event) {
EventTargetCast::from_ref(window.r())
} else {
EventTargetCast::from_ref(*self)
EventTargetCast::from_ref(self)
};
evtarget.set_event_handler_uncompiled(cx, url, reflector,
&name[2..],
@ -161,7 +157,7 @@ impl<'a> VirtualMethods for &'a HTMLBodyElement {
self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
}
&atom!("background") => {
let doc = document_from_node(*self);
let doc = document_from_node(self);
let base = doc.r().url();
*self.background.borrow_mut() = UrlParser::new().base_url(&base).parse(&attr.value()).ok();
@ -183,4 +179,3 @@ impl<'a> VirtualMethods for &'a HTMLBodyElement {
}
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLBRElement {
htmlelement: HTMLElement,
}
@ -41,4 +40,3 @@ impl HTMLBRElement {
Node::reflect_node(box element, document, HTMLBRElementBinding::Wrap)
}
}

View file

@ -4,21 +4,19 @@
use dom::activation::Activatable;
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLButtonElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived};
use dom::bindings::js::Root;
use dom::document::Document;
use dom::element::ActivationElementHelpers;
use dom::element::{AttributeHandlers, Element, ElementTypeId};
use dom::element::{Element, ElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmlformelement::{FormSubmitter, FormControl, HTMLFormElementHelpers};
use dom::htmlformelement::{FormSubmitter, FormControl};
use dom::htmlformelement::{SubmittedFrom};
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use dom::node::{Node, NodeTypeId, document_from_node, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
@ -38,7 +36,6 @@ enum ButtonType {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLButtonElement {
htmlelement: HTMLElement,
button_type: Cell<ButtonType>
@ -73,9 +70,9 @@ impl HTMLButtonElement {
}
}
impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement {
impl HTMLButtonElementMethods for HTMLButtonElement {
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(self) -> Root<ValidityState> {
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
}
@ -87,7 +84,7 @@ impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement {
make_bool_setter!(SetDisabled, "disabled");
// https://html.spec.whatwg.org/multipage/#dom-button-type
fn Type(self) -> DOMString {
fn Type(&self) -> DOMString {
let elem = ElementCast::from_ref(self);
let mut ty = elem.get_string_attribute(&atom!("type"));
ty.make_ascii_lowercase();
@ -101,22 +98,29 @@ impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement {
// https://html.spec.whatwg.org/multipage/#dom-button-type
make_setter!(SetType, "type");
// https://html.spec.whatwg.org/multipage/#htmlbuttonelement
// https://html.spec.whatwg.org/multipage/#dom-fs-formaction
make_url_or_base_getter!(FormAction);
// https://html.spec.whatwg.org/multipage/#dom-fs-formaction
make_setter!(SetFormAction, "formaction");
// https://html.spec.whatwg.org/multipage/#dom-fs-formenctype
make_enumerated_getter!(
FormEnctype, "application/x-www-form-urlencoded", ("text/plain") | ("multipart/form-data"));
// https://html.spec.whatwg.org/multipage/#dom-fs-formenctype
make_setter!(SetFormEnctype, "formenctype");
// https://html.spec.whatwg.org/multipage/#dom-fs-formmethod
make_enumerated_getter!(FormMethod, "get", ("post") | ("dialog"));
// https://html.spec.whatwg.org/multipage/#dom-fs-formmethod
make_setter!(SetFormMethod, "formmethod");
// https://html.spec.whatwg.org/multipage/#dom-fs-formtarget
make_getter!(FormTarget);
// https://html.spec.whatwg.org/multipage/#dom-fs-formtarget
make_setter!(SetFormTarget, "formtarget");
// https://html.spec.whatwg.org/multipage/#dom-fe-name
@ -132,9 +136,9 @@ impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement {
make_setter!(SetValue, "value");
}
impl<'a> VirtualMethods for &'a HTMLButtonElement {
impl VirtualMethods for HTMLButtonElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -145,7 +149,7 @@ impl<'a> VirtualMethods for &'a HTMLButtonElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(true);
node.set_enabled_state(false);
},
@ -160,7 +164,7 @@ impl<'a> VirtualMethods for &'a HTMLButtonElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(false);
node.set_enabled_state(true);
node.check_ancestors_disabled_state_for_form_control();
@ -174,7 +178,7 @@ impl<'a> VirtualMethods for &'a HTMLButtonElement {
s.bind_to_tree(tree_in_doc);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.check_ancestors_disabled_state_for_form_control();
}
@ -183,7 +187,7 @@ impl<'a> VirtualMethods for &'a HTMLButtonElement {
s.unbind_from_tree(tree_in_doc);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
node.check_ancestors_disabled_state_for_form_control();
} else {
@ -253,4 +257,3 @@ impl<'a> Activatable for &'a HTMLButtonElement {
}
}
}

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
@ -15,7 +14,6 @@ use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, HeapGCValue, Root};
use dom::bindings::utils::{Reflectable};
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
use dom::document::Document;
use dom::element::AttributeHandlers;
use dom::element::ElementTypeId;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
@ -47,7 +45,6 @@ pub enum CanvasContext {
impl HeapGCValue for CanvasContext {}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLCanvasElement {
htmlelement: HTMLElement,
context: MutNullableHeap<CanvasContext>,
@ -154,17 +151,9 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
}
}
pub trait HTMLCanvasElementHelpers {
fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>>;
fn get_or_init_webgl_context(self,
cx: *mut JSContext,
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>>;
fn is_valid(self) -> bool;
}
impl<'a> HTMLCanvasElementHelpers for &'a HTMLCanvasElement {
fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>> {
impl HTMLCanvasElement {
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
if self.context.get().is_none() {
let window = window_from_node(self);
let size = self.get_size();
@ -178,7 +167,7 @@ impl<'a> HTMLCanvasElementHelpers for &'a HTMLCanvasElement {
}
}
fn get_or_init_webgl_context(self,
pub fn get_or_init_webgl_context(&self,
cx: *mut JSContext,
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
if self.context.get().is_none() {
@ -211,36 +200,36 @@ impl<'a> HTMLCanvasElementHelpers for &'a HTMLCanvasElement {
}
}
fn is_valid(self) -> bool {
pub fn is_valid(&self) -> bool {
self.height.get() != 0 && self.width.get() != 0
}
}
impl<'a> HTMLCanvasElementMethods for &'a HTMLCanvasElement {
impl HTMLCanvasElementMethods for HTMLCanvasElement {
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
fn Width(self) -> u32 {
fn Width(&self) -> u32 {
self.width.get()
}
// https://html.spec.whatwg.org/multipage/#dom-canvas-width
fn SetWidth(self, width: u32) {
fn SetWidth(&self, width: u32) {
let elem = ElementCast::from_ref(self);
elem.set_uint_attribute(&atom!("width"), width)
}
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
fn Height(self) -> u32 {
fn Height(&self) -> u32 {
self.height.get()
}
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
fn SetHeight(self, height: u32) {
fn SetHeight(&self, height: u32) {
let elem = ElementCast::from_ref(self);
elem.set_uint_attribute(&atom!("height"), height)
}
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
fn GetContext(self,
fn GetContext(&self,
cx: *mut JSContext,
id: DOMString,
attributes: Vec<HandleValue>)
@ -261,9 +250,9 @@ impl<'a> HTMLCanvasElementMethods for &'a HTMLCanvasElement {
}
}
impl<'a> VirtualMethods for &'a HTMLCanvasElement {
impl VirtualMethods for HTMLCanvasElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let element: &HTMLElement = HTMLElementCast::from_ref(self);
Some(element as &VirtualMethods)
}
@ -340,4 +329,3 @@ pub mod utils {
result.image_response
}
}

View file

@ -9,8 +9,8 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{namespace_from_domstring, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers, ElementHelpers};
use dom::node::{Node, NodeHelpers, TreeIterator};
use dom::element::Element;
use dom::node::{Node, TreeIterator};
use dom::window::Window;
use util::str::{DOMString, split_html_space_chars};
@ -26,7 +26,6 @@ pub trait CollectionFilter : JSTraceable {
pub struct Collection(JS<Node>, Box<CollectionFilter + 'static>);
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLCollection {
reflector_: Reflector,
#[ignore_heap_size_of = "Contains a trait object; can't measure due to #6870"]
@ -45,9 +44,7 @@ impl HTMLCollection {
reflect_dom_object(box HTMLCollection::new_inherited(collection),
GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
}
}
impl HTMLCollection {
pub fn create(window: &Window, root: &Node,
filter: Box<CollectionFilter + 'static>) -> Root<HTMLCollection> {
HTMLCollection::new(window, Collection(JS::from_ref(root), filter))
@ -193,19 +190,19 @@ impl<'a> Iterator for HTMLCollectionElementsIter<'a> {
}
}
impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
impl HTMLCollectionMethods for HTMLCollection {
// https://dom.spec.whatwg.org/#dom-htmlcollection-length
fn Length(self) -> u32 {
fn Length(&self) -> u32 {
self.elements_iter().count() as u32
}
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
fn Item(self, index: u32) -> Option<Root<Element>> {
fn Item(&self, index: u32) -> Option<Root<Element>> {
self.elements_iter().nth(index as usize)
}
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
fn NamedItem(self, key: DOMString) -> Option<Root<Element>> {
fn NamedItem(&self, key: DOMString) -> Option<Root<Element>> {
// Step 1.
if key.is_empty() {
return None;
@ -219,21 +216,21 @@ impl<'a> HTMLCollectionMethods for &'a HTMLCollection {
}
// https://dom.spec.whatwg.org/#dom-htmlcollection-item
fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Element>> {
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Element>> {
let maybe_elem = self.Item(index);
*found = maybe_elem.is_some();
maybe_elem
}
// check-tidy: no specs after this line
fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Element>> {
fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<Root<Element>> {
let maybe_elem = self.NamedItem(name);
*found = maybe_elem.is_some();
maybe_elem
}
// https://dom.spec.whatwg.org/#interface-htmlcollection
fn SupportedPropertyNames(self) -> Vec<DOMString> {
fn SupportedPropertyNames(&self) -> Vec<DOMString> {
// Step 1
let mut result = vec![];

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDataElement {
htmlelement: HTMLElement
}
@ -43,4 +42,3 @@ impl HTMLDataElement {
Node::reflect_node(box element, document, HTMLDataElementBinding::Wrap)
}
}

View file

@ -17,7 +17,6 @@ use dom::node::{Node, NodeTypeId, window_from_node};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDataListElement {
htmlelement: HTMLElement
}
@ -49,9 +48,9 @@ impl HTMLDataListElement {
}
}
impl<'a> HTMLDataListElementMethods for &'a HTMLDataListElement {
impl HTMLDataListElementMethods for HTMLDataListElement {
// https://html.spec.whatwg.org/multipage/#dom-datalist-options
fn Options(self) -> Root<HTMLCollection> {
fn Options(&self) -> Root<HTMLCollection> {
#[derive(JSTraceable, HeapSizeOf)]
struct HTMLDataListOptionsFilter;
impl CollectionFilter for HTMLDataListOptionsFilter {
@ -65,4 +64,3 @@ impl<'a> HTMLDataListElementMethods for &'a HTMLDataListElement {
HTMLCollection::create(window.r(), node, filter)
}
}

View file

@ -18,7 +18,6 @@ use util::str::DOMString;
use std::borrow::ToOwned;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDialogElement {
htmlelement: HTMLElement,
return_value: DOMRefCell<DOMString>,
@ -52,7 +51,7 @@ impl HTMLDialogElement {
}
}
impl<'a> HTMLDialogElementMethods for &'a HTMLDialogElement {
impl HTMLDialogElementMethods for HTMLDialogElement {
// https://html.spec.whatwg.org/multipage/#dom-dialog-open
make_bool_getter!(Open);
@ -60,13 +59,13 @@ impl<'a> HTMLDialogElementMethods for &'a HTMLDialogElement {
make_bool_setter!(SetOpen, "open");
// https://html.spec.whatwg.org/multipage/#dom-dialog-returnvalue
fn ReturnValue(self) -> DOMString {
fn ReturnValue(&self) -> DOMString {
let return_value = self.return_value.borrow();
return_value.clone()
}
// https://html.spec.whatwg.org/multipage/#dom-dialog-returnvalue
fn SetReturnValue(self, return_value: DOMString) {
fn SetReturnValue(&self, return_value: DOMString) {
*self.return_value.borrow_mut() = return_value;
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDirectoryElement {
htmlelement: HTMLElement
}
@ -44,4 +43,3 @@ impl HTMLDirectoryElement {
Node::reflect_node(box element, document, HTMLDirectoryElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDivElement {
htmlelement: HTMLElement
}
@ -43,4 +42,3 @@ impl HTMLDivElement {
Node::reflect_node(box element, document, HTMLDivElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLDListElement {
htmlelement: HTMLElement
}
@ -42,4 +41,3 @@ impl HTMLDListElement {
Node::reflect_node(box element, document, HTMLDListElementBinding::Wrap)
}
}

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::attr::AttrValue;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::HTMLElementBinding;
@ -18,16 +17,15 @@ use dom::bindings::error::ErrorResult;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::utils::Reflectable;
use dom::cssstyledeclaration::{CSSStyleDeclaration, CSSModificationAccess};
use dom::document::{Document, DocumentHelpers};
use dom::document::Document;
use dom::domstringmap::DOMStringMap;
use dom::element::{Element, ElementTypeId, ActivationElementHelpers, AttributeHandlers};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::element::{Element, ElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlinputelement::HTMLInputElement;
use dom::htmlmediaelement::HTMLMediaElementTypeId;
use dom::htmltablecellelement::HTMLTableCellElementTypeId;
use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node, SEQUENTIALLY_FOCUSABLE};
use dom::node::{Node, NodeTypeId, document_from_node, window_from_node, SEQUENTIALLY_FOCUSABLE};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use msg::constellation_msg::FocusType;
use util::str::DOMString;
@ -40,7 +38,6 @@ use std::intrinsics;
use std::rc::Rc;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLElement {
element: Element,
style_decl: MutNullableHeap<JS<CSSStyleDeclaration>>,
@ -80,20 +77,13 @@ impl HTMLElement {
let element = HTMLElement::new_inherited(HTMLElementTypeId::HTMLElement, localName, prefix, document);
Node::reflect_node(box element, document, HTMLElementBinding::Wrap)
}
}
trait PrivateHTMLElementHelpers {
fn is_body_or_frameset(self) -> bool;
fn update_sequentially_focusable_status(self);
}
impl<'a> PrivateHTMLElementHelpers for &'a HTMLElement {
fn is_body_or_frameset(self) -> bool {
fn is_body_or_frameset(&self) -> bool {
let eventtarget = EventTargetCast::from_ref(self);
eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement()
}
fn update_sequentially_focusable_status(self) {
fn update_sequentially_focusable_status(&self) {
let element = ElementCast::from_ref(self);
let node = NodeCast::from_ref(self);
if element.has_attribute(&atom!("tabindex")) {
@ -131,34 +121,40 @@ impl<'a> PrivateHTMLElementHelpers for &'a HTMLElement {
}
}
impl<'a> HTMLElementMethods for &'a HTMLElement {
impl HTMLElementMethods for HTMLElement {
// https://html.spec.whatwg.org/multipage/#the-style-attribute
fn Style(self) -> Root<CSSStyleDeclaration> {
fn Style(&self) -> Root<CSSStyleDeclaration> {
self.style_decl.or_init(|| {
let global = window_from_node(self);
CSSStyleDeclaration::new(global.r(), ElementCast::from_ref(self), None, CSSModificationAccess::ReadWrite)
})
}
// https://html.spec.whatwg.org/multipage/#attr-title
make_getter!(Title);
// https://html.spec.whatwg.org/multipage/#attr-title
make_setter!(SetTitle, "title");
// https://html.spec.whatwg.org/multipage/#attr-lang
make_getter!(Lang);
// https://html.spec.whatwg.org/multipage/#attr-lang
make_setter!(SetLang, "lang");
// https://html.spec.whatwg.org/multipage/#dom-hidden
make_bool_getter!(Hidden);
// https://html.spec.whatwg.org/multipage/#dom-hidden
make_bool_setter!(SetHidden, "hidden");
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
global_event_handlers!(NoOnload);
// https://html.spec.whatwg.org/multipage/#dom-dataset
fn Dataset(self) -> Root<DOMStringMap> {
fn Dataset(&self) -> Root<DOMStringMap> {
self.dataset.or_init(|| DOMStringMap::new(self))
}
// https://html.spec.whatwg.org/multipage/#handler-onload
fn GetOnload(self) -> Option<Rc<EventHandlerNonNull>> {
fn GetOnload(&self) -> Option<Rc<EventHandlerNonNull>> {
if self.is_body_or_frameset() {
let win = window_from_node(self);
win.r().GetOnload()
@ -169,7 +165,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://html.spec.whatwg.org/multipage/#handler-onload
fn SetOnload(self, listener: Option<Rc<EventHandlerNonNull>>) {
fn SetOnload(&self, listener: Option<Rc<EventHandlerNonNull>>) {
if self.is_body_or_frameset() {
let win = window_from_node(self);
win.r().SetOnload(listener)
@ -180,7 +176,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://html.spec.whatwg.org/multipage/#dom-click
fn Click(self) {
fn Click(&self) {
let maybe_input: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self);
if let Some(i) = maybe_input {
if i.Disabled() {
@ -193,7 +189,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://html.spec.whatwg.org/multipage/#dom-focus
fn Focus(self) {
fn Focus(&self) {
// TODO: Mark the element as locked for focus and run the focusing steps.
// https://html.spec.whatwg.org/multipage/#focusing-steps
let element = ElementCast::from_ref(self);
@ -205,7 +201,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://html.spec.whatwg.org/multipage/#dom-blur
fn Blur(self) {
fn Blur(&self) {
// TODO: Run the unfocusing steps.
let node = NodeCast::from_ref(self);
if !node.get_focus_state() {
@ -219,7 +215,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
fn GetOffsetParent(self) -> Option<Root<Element>> {
fn GetOffsetParent(&self) -> Option<Root<Element>> {
if self.is_htmlbodyelement() || self.is_htmlhtmlelement() {
return None;
}
@ -232,7 +228,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
fn OffsetTop(self) -> i32 {
fn OffsetTop(&self) -> i32 {
if self.is_htmlbodyelement() {
return 0;
}
@ -245,7 +241,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
fn OffsetLeft(self) -> i32 {
fn OffsetLeft(&self) -> i32 {
if self.is_htmlbodyelement() {
return 0;
}
@ -258,7 +254,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
fn OffsetWidth(self) -> i32 {
fn OffsetWidth(&self) -> i32 {
let node = NodeCast::from_ref(self);
let window = window_from_node(self);
let (_, rect) = window.offset_parent_query(node.to_trusted_node_address());
@ -267,7 +263,7 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface
fn OffsetHeight(self) -> i32 {
fn OffsetHeight(&self) -> i32 {
let node = NodeCast::from_ref(self);
let window = window_from_node(self);
let (_, rect) = window.offset_parent_query(node.to_trusted_node_address());
@ -277,11 +273,6 @@ impl<'a> HTMLElementMethods for &'a HTMLElement {
}
// https://html.spec.whatwg.org/#attr-data-*
pub trait HTMLElementCustomAttributeHelpers {
fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult;
fn get_custom_attr(self, name: DOMString) -> Option<DOMString>;
fn delete_custom_attr(self, name: DOMString);
}
fn to_snake_case(name: DOMString) -> DOMString {
let mut attr_name = "data-".to_owned();
@ -296,8 +287,8 @@ fn to_snake_case(name: DOMString) -> DOMString {
attr_name
}
impl<'a> HTMLElementCustomAttributeHelpers for &'a HTMLElement {
fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult {
impl HTMLElement {
pub fn set_custom_attr(&self, name: DOMString, value: DOMString) -> ErrorResult {
if name.chars()
.skip_while(|&ch| ch != '\u{2d}')
.nth(1).map_or(false, |ch| ch >= 'a' && ch <= 'z') {
@ -307,7 +298,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for &'a HTMLElement {
element.set_custom_attribute(to_snake_case(name), value)
}
fn get_custom_attr(self, local_name: DOMString) -> Option<DOMString> {
pub fn get_custom_attr(&self, local_name: DOMString) -> Option<DOMString> {
let element = ElementCast::from_ref(self);
let local_name = Atom::from_slice(&to_snake_case(local_name));
element.get_attribute(&ns!(""), &local_name).map(|attr| {
@ -315,16 +306,16 @@ impl<'a> HTMLElementCustomAttributeHelpers for &'a HTMLElement {
})
}
fn delete_custom_attr(self, local_name: DOMString) {
pub fn delete_custom_attr(&self, local_name: DOMString) {
let element = ElementCast::from_ref(self);
let local_name = Atom::from_slice(&to_snake_case(local_name));
element.remove_attribute(&ns!(""), &local_name);
}
}
impl<'a> VirtualMethods for &'a HTMLElement {
impl VirtualMethods for HTMLElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let element: &&Element = ElementCast::from_borrowed_ref(self);
let element: &Element = ElementCast::from_ref(self);
Some(element as &VirtualMethods)
}
@ -348,11 +339,11 @@ impl<'a> VirtualMethods for &'a HTMLElement {
let name = attr.local_name();
if name.starts_with("on") {
let window = window_from_node(*self);
let window = window_from_node(self);
let (cx, url, reflector) = (window.r().get_cx(),
window.r().get_url(),
window.r().reflector().get_jsobject());
let evtarget = EventTargetCast::from_ref(*self);
let evtarget = EventTargetCast::from_ref(self);
evtarget.set_event_handler_uncompiled(cx, url, reflector,
&name[2..],
(**attr.value()).to_owned());

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLEmbedElement {
htmlelement: HTMLElement
}
@ -41,4 +40,3 @@ impl HTMLEmbedElement {
Node::reflect_node(box element, document, HTMLEmbedElementBinding::Wrap)
}
}

View file

@ -3,26 +3,23 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLLegendElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::element::{AttributeHandlers, Element, ElementHelpers};
use dom::element::{Element, ElementTypeId};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::node::{Node, NodeTypeId, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use util::str::{DOMString, StaticStringVec};
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLFieldSetElement {
htmlelement: HTMLElement
}
@ -54,9 +51,9 @@ impl HTMLFieldSetElement {
}
}
impl<'a> HTMLFieldSetElementMethods for &'a HTMLFieldSetElement {
impl HTMLFieldSetElementMethods for HTMLFieldSetElement {
// https://www.whatwg.org/html/#dom-fieldset-elements
fn Elements(self) -> Root<HTMLCollection> {
fn Elements(&self) -> Root<HTMLCollection> {
#[derive(JSTraceable, HeapSizeOf)]
struct ElementsFilter;
impl CollectionFilter for ElementsFilter {
@ -73,7 +70,7 @@ impl<'a> HTMLFieldSetElementMethods for &'a HTMLFieldSetElement {
}
// https://html.spec.whatwg.org/multipage/#dom-cva-validity
fn Validity(self) -> Root<ValidityState> {
fn Validity(&self) -> Root<ValidityState> {
let window = window_from_node(self);
ValidityState::new(window.r())
}
@ -85,9 +82,9 @@ impl<'a> HTMLFieldSetElementMethods for &'a HTMLFieldSetElement {
make_bool_setter!(SetDisabled, "disabled");
}
impl<'a> VirtualMethods for &'a HTMLFieldSetElement {
impl VirtualMethods for HTMLFieldSetElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -98,7 +95,7 @@ impl<'a> VirtualMethods for &'a HTMLFieldSetElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(true);
node.set_enabled_state(false);
let maybe_legend = node.children()
@ -138,7 +135,7 @@ impl<'a> VirtualMethods for &'a HTMLFieldSetElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(false);
node.set_enabled_state(true);
let maybe_legend = node.children()
@ -171,4 +168,3 @@ impl<'a> VirtualMethods for &'a HTMLFieldSetElement {
}
}
}

View file

@ -2,7 +2,7 @@
* 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/. */
use dom::attr::{Attr, AttrHelpers};
use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLFontElementBinding;
use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived};
@ -19,7 +19,6 @@ use cssparser::RGBA;
use std::cell::Cell;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLFontElement {
htmlelement: HTMLElement,
color: Cell<Option<RGBA>>,
@ -50,14 +49,17 @@ impl HTMLFontElement {
}
}
impl<'a> HTMLFontElementMethods for &'a HTMLFontElement {
impl HTMLFontElementMethods for HTMLFontElement {
// https://html.spec.whatwg.org/multipage/#dom-font-color
make_getter!(Color, "color");
// https://html.spec.whatwg.org/multipage/#dom-font-color
make_setter!(SetColor, "color");
}
impl<'a> VirtualMethods for &'a HTMLFontElement {
impl VirtualMethods for HTMLFontElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -86,13 +88,9 @@ impl<'a> VirtualMethods for &'a HTMLFontElement {
}
}
pub trait HTMLFontElementHelpers {
fn get_color(&self) -> Option<RGBA>;
}
impl HTMLFontElementHelpers for HTMLFontElement {
fn get_color(&self) -> Option<RGBA> {
impl HTMLFontElement {
pub fn get_color(&self) -> Option<RGBA> {
self.color.get()
}
}

View file

@ -18,16 +18,14 @@ use dom::bindings::codegen::InheritTypes::HTMLInputElementCast;
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{Root};
use dom::document::{Document, DocumentHelpers};
use dom::element::ElementTypeId;
use dom::element::{Element, AttributeHandlers};
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
use dom::document::Document;
use dom::element::{Element, ElementTypeId};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlbuttonelement::{HTMLButtonElement};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmlinputelement::{HTMLInputElement, HTMLInputElementHelpers};
use dom::htmltextareaelement::HTMLTextAreaElementHelpers;
use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use dom::htmlinputelement::HTMLInputElement;
use dom::node::{Node, NodeTypeId, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use hyper::header::ContentType;
use hyper::method::Method;
@ -43,7 +41,6 @@ use std::borrow::ToOwned;
use std::cell::Cell;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLFormElement {
htmlelement: HTMLElement,
marked_for_reset: Cell<bool>,
@ -82,7 +79,7 @@ impl HTMLFormElement {
}
}
impl<'a> HTMLFormElementMethods for &'a HTMLFormElement {
impl HTMLFormElementMethods for HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#dom-form-acceptcharset
make_getter!(AcceptCharset, "accept-charset");
@ -108,12 +105,12 @@ impl<'a> HTMLFormElementMethods for &'a HTMLFormElement {
make_setter!(SetEnctype, "enctype");
// https://html.spec.whatwg.org/multipage/#dom-fs-encoding
fn Encoding(self) -> DOMString {
fn Encoding(&self) -> DOMString {
self.Enctype()
}
// https://html.spec.whatwg.org/multipage/#dom-fs-encoding
fn SetEncoding(self, value: DOMString) {
fn SetEncoding(&self, value: DOMString) {
self.SetEnctype(value)
}
@ -125,6 +122,8 @@ impl<'a> HTMLFormElementMethods for &'a HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#dom-form-name
make_getter!(Name);
// https://html.spec.whatwg.org/multipage/#dom-form-name
make_atomic_setter!(SetName, "name");
// https://html.spec.whatwg.org/multipage/#dom-fs-novalidate
@ -140,12 +139,12 @@ impl<'a> HTMLFormElementMethods for &'a HTMLFormElement {
make_setter!(SetTarget, "target");
// https://html.spec.whatwg.org/multipage/#the-form-element:concept-form-submit
fn Submit(self) {
fn Submit(&self) {
self.submit(SubmittedFrom::FromFormSubmitMethod, FormSubmitter::FormElement(self));
}
// https://html.spec.whatwg.org/multipage/#dom-form-reset
fn Reset(self) {
fn Reset(&self) {
self.reset(ResetFrom::FromFormResetMethod);
}
}
@ -162,17 +161,9 @@ pub enum ResetFrom {
NotFromFormResetMethod
}
pub trait HTMLFormElementHelpers {
// https://html.spec.whatwg.org/multipage/#concept-form-submit
fn submit(self, submit_method_flag: SubmittedFrom, submitter: FormSubmitter);
// https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set
fn get_form_dataset(self, submitter: Option<FormSubmitter>) -> Vec<FormDatum>;
// https://html.spec.whatwg.org/multipage/#dom-form-reset
fn reset(self, submit_method_flag: ResetFrom);
}
impl<'a> HTMLFormElementHelpers for &'a HTMLFormElement {
fn submit(self, _submit_method_flag: SubmittedFrom, submitter: FormSubmitter) {
impl HTMLFormElement {
pub fn submit(&self, _submit_method_flag: SubmittedFrom, submitter: FormSubmitter) {
// Step 1
let doc = document_from_node(self);
let win = window_from_node(self);
@ -236,7 +227,7 @@ impl<'a> HTMLFormElementHelpers for &'a HTMLFormElement {
win.r().pipeline(), load_data)).unwrap();
}
fn get_form_dataset<'b>(self, submitter: Option<FormSubmitter<'b>>) -> Vec<FormDatum> {
pub fn get_form_dataset<'b>(&self, submitter: Option<FormSubmitter<'b>>) -> Vec<FormDatum> {
fn clean_crlf(s: &str) -> DOMString {
// https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set
// Step 4
@ -363,7 +354,7 @@ impl<'a> HTMLFormElementHelpers for &'a HTMLFormElement {
ret
}
fn reset(self, _reset_method_flag: ResetFrom) {
pub fn reset(&self, _reset_method_flag: ResetFrom) {
// https://html.spec.whatwg.org/multipage/#locked-for-reset
if self.marked_for_reset.get() {
return;
@ -571,9 +562,9 @@ pub trait FormControl<'a> : Copy + Sized {
fn to_element(self) -> &'a Element;
}
impl<'a> VirtualMethods for &'a HTMLFormElement {
impl VirtualMethods for HTMLFormElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods)
Some(HTMLElementCast::from_ref(self) as &VirtualMethods)
}
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLFrameElement {
htmlelement: HTMLElement
}
@ -41,4 +40,3 @@ impl HTMLFrameElement {
Node::reflect_node(box element, document, HTMLFrameElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLFrameSetElement {
htmlelement: HTMLElement
}
@ -44,4 +43,3 @@ impl HTMLFrameSetElement {
Node::reflect_node(box element, document, HTMLFrameSetElementBinding::Wrap)
}
}

View file

@ -15,7 +15,6 @@ use dom::virtualmethods::VirtualMethods;
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLHeadElement {
htmlelement: HTMLElement
}
@ -46,12 +45,12 @@ impl HTMLHeadElement {
}
}
impl<'a> VirtualMethods for &'a HTMLHeadElement {
impl VirtualMethods for HTMLHeadElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
fn bind_to_tree(&self, _tree_in_doc: bool) {
load_script(*self);
load_script(self);
}
}

View file

@ -23,7 +23,6 @@ pub enum HeadingLevel {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLHeadingElement {
htmlelement: HTMLElement,
level: HeadingLevel,
@ -58,4 +57,3 @@ impl HTMLHeadingElement {
Node::reflect_node(box element, document, HTMLHeadingElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLHRElement {
htmlelement: HTMLElement,
}
@ -41,4 +40,3 @@ impl HTMLHRElement {
Node::reflect_node(box element, document, HTMLHRElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLHtmlElement {
htmlelement: HTMLElement
}
@ -41,4 +40,3 @@ impl HTMLHtmlElement {
Node::reflect_node(box element, document, HTMLHtmlElementBinding::Wrap)
}
}

View file

@ -2,7 +2,7 @@
* 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/. */
use dom::attr::{Attr, AttrHelpers, AttrHelpersForLayout, AttrValue};
use dom::attr::{Attr, AttrHelpersForLayout, AttrValue};
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
@ -17,22 +17,20 @@ use dom::bindings::js::{Root};
use dom::bindings::utils::Reflectable;
use dom::customevent::CustomEvent;
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::element::{self, AttributeHandlers};
use dom::event::EventHelpers;
use dom::element::{ElementTypeId, self};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::node::{Node, NodeTypeId, window_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::{Window, WindowHelpers};
use dom::window::Window;
use page::IterablePage;
use msg::constellation_msg::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::{PipelineId, SubpageId, ConstellationChan, MozBrowserEvent, NavigationDirection};
use string_cache::Atom;
use util::opts;
use util::prefs;
use util::str::DOMString;
use js::jsapi::{RootedValue, JSAutoRequest, JSAutoCompartment};
@ -43,6 +41,10 @@ use std::cell::Cell;
use url::{Url, UrlParser};
use util::str::{self, LengthOrPercentageOrAuto};
pub fn mozbrowser_enabled() -> bool {
prefs::get_pref("dom.mozbrowser.enabled", false)
}
#[derive(HeapSizeOf)]
enum SandboxAllowance {
AllowNothing = 0x00,
@ -55,7 +57,6 @@ enum SandboxAllowance {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
subpage_id: Cell<Option<SubpageId>>,
@ -71,28 +72,14 @@ impl HTMLIFrameElementDerived for EventTarget {
}
}
pub trait HTMLIFrameElementHelpers {
fn is_sandboxed(self) -> bool;
fn get_url(self) -> Option<Url>;
/// https://www.whatwg.org/html/#process-the-iframe-attributes
fn process_the_iframe_attributes(self);
fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>);
fn navigate_child_browsing_context(self, url: Url);
fn dispatch_mozbrowser_event(self, event: MozBrowserEvent);
fn update_subpage_id(self, new_subpage_id: SubpageId);
}
pub trait RawHTMLIFrameElementHelpers {
fn get_width(&self) -> LengthOrPercentageOrAuto;
fn get_height(&self) -> LengthOrPercentageOrAuto;
}
impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
fn is_sandboxed(self) -> bool {
impl HTMLIFrameElement {
pub fn is_sandboxed(&self) -> bool {
self.sandbox.get().is_some()
}
fn get_url(self) -> Option<Url> {
pub fn get_url(&self) -> Option<Url> {
let element = ElementCast::from_ref(self);
element.get_attribute(&ns!(""), &atom!("src")).and_then(|src| {
let url = src.r().value();
@ -106,7 +93,7 @@ impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
})
}
fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>) {
pub fn generate_new_subpage_id(&self) -> (SubpageId, Option<SubpageId>) {
let old_subpage_id = self.subpage_id.get();
let win = window_from_node(self);
let subpage_id = win.r().get_next_subpage_id();
@ -114,7 +101,7 @@ impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
(subpage_id, old_subpage_id)
}
fn navigate_child_browsing_context(self, url: Url) {
pub fn navigate_child_browsing_context(&self, url: Url) {
let sandboxed = if self.is_sandboxed() {
IFrameSandboxed
} else {
@ -134,13 +121,13 @@ impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
old_subpage_id,
sandboxed)).unwrap();
if opts::experimental_enabled() {
if mozbrowser_enabled() {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
self.dispatch_mozbrowser_event(MozBrowserEvent::LoadStart);
}
}
fn process_the_iframe_attributes(self) {
pub fn process_the_iframe_attributes(&self) {
let url = match self.get_url() {
Some(url) => url.clone(),
None => Url::parse("about:blank").unwrap(),
@ -149,11 +136,11 @@ impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
self.navigate_child_browsing_context(url);
}
fn dispatch_mozbrowser_event(self, event: MozBrowserEvent) {
pub fn dispatch_mozbrowser_event(&self, event: MozBrowserEvent) {
// TODO(gw): Support mozbrowser event types that have detail which is not a string.
// See https://developer.mozilla.org/en-US/docs/Web/API/Using_the_Browser_API
// for a list of mozbrowser events.
assert!(opts::experimental_enabled());
assert!(mozbrowser_enabled());
if self.Mozbrowser() {
let window = window_from_node(self);
@ -173,14 +160,12 @@ impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement {
}
}
fn update_subpage_id(self, new_subpage_id: SubpageId) {
pub fn update_subpage_id(&self, new_subpage_id: SubpageId) {
self.subpage_id.set(Some(new_subpage_id));
}
}
impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
#[allow(unsafe_code)]
fn get_width(&self) -> LengthOrPercentageOrAuto {
pub fn get_width(&self) -> LengthOrPercentageOrAuto {
unsafe {
element::get_attr_for_layout(ElementCast::from_ref(&*self),
&ns!(""),
@ -191,7 +176,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
}
#[allow(unsafe_code)]
fn get_height(&self) -> LengthOrPercentageOrAuto {
pub fn get_height(&self) -> LengthOrPercentageOrAuto {
unsafe {
element::get_attr_for_layout(ElementCast::from_ref(&*self),
&ns!(""),
@ -200,9 +185,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement {
}).unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}
}
impl HTMLIFrameElement {
fn new_inherited(localName: DOMString,
prefix: Option<DOMString>,
document: &Document) -> HTMLIFrameElement {
@ -255,33 +238,33 @@ pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> F
}
}
impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
impl HTMLIFrameElementMethods for HTMLIFrameElement {
// https://html.spec.whatwg.org/multipage/#dom-iframe-src
fn Src(self) -> DOMString {
fn Src(&self) -> DOMString {
let element = ElementCast::from_ref(self);
element.get_string_attribute(&atom!("src"))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-src
fn SetSrc(self, src: DOMString) {
fn SetSrc(&self, src: DOMString) {
let element = ElementCast::from_ref(self);
element.set_url_attribute(&atom!("src"), src)
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox
fn Sandbox(self) -> DOMString {
fn Sandbox(&self) -> DOMString {
let element = ElementCast::from_ref(self);
element.get_string_attribute(&atom!("sandbox"))
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox
fn SetSandbox(self, sandbox: DOMString) {
fn SetSandbox(&self, sandbox: DOMString) {
let element = ElementCast::from_ref(self);
element.set_tokenlist_attribute(&atom!("sandbox"), sandbox);
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow
fn GetContentWindow(self) -> Option<Root<Window>> {
fn GetContentWindow(&self) -> Option<Root<Window>> {
self.subpage_id.get().and_then(|subpage_id| {
let window = window_from_node(self);
let window = window.r();
@ -294,7 +277,7 @@ impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
}
// https://html.spec.whatwg.org/multipage/#dom-iframe-contentdocument
fn GetContentDocument(self) -> Option<Root<Document>> {
fn GetContentDocument(&self) -> Option<Root<Document>> {
self.GetContentWindow().and_then(|window| {
let self_url = match self.get_url() {
Some(self_url) => self_url,
@ -318,8 +301,8 @@ impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
// exposing these APIs. See https://github.com/servo/servo/issues/5264.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser
fn Mozbrowser(self) -> bool {
if opts::experimental_enabled() {
fn Mozbrowser(&self) -> bool {
if mozbrowser_enabled() {
let element = ElementCast::from_ref(self);
element.has_attribute(&Atom::from_slice("mozbrowser"))
} else {
@ -328,8 +311,8 @@ impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
}
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser
fn SetMozbrowser(self, value: bool) -> ErrorResult {
if opts::experimental_enabled() {
fn SetMozbrowser(&self, value: bool) -> ErrorResult {
if mozbrowser_enabled() {
let element = ElementCast::from_ref(self);
element.set_bool_attribute(&Atom::from_slice("mozbrowser"), value);
}
@ -337,37 +320,39 @@ impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement {
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
fn GoBack(self) -> Fallible<()> {
fn GoBack(&self) -> Fallible<()> {
Navigate(self, NavigationDirection::Back)
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goForward
fn GoForward(self) -> Fallible<()> {
fn GoForward(&self) -> Fallible<()> {
Navigate(self, NavigationDirection::Forward)
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/reload
fn Reload(self, _hardReload: bool) -> Fallible<()> {
fn Reload(&self, _hardReload: bool) -> Fallible<()> {
Err(NotSupported)
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/stop
fn Stop(self) -> Fallible<()> {
fn Stop(&self) -> Fallible<()> {
Err(NotSupported)
}
// https://html.spec.whatwg.org/multipage/#dom-dim-width
make_getter!(Width);
// https://html.spec.whatwg.org/multipage/#dom-dim-width
make_setter!(SetWidth, "width");
// https://html.spec.whatwg.org/multipage/#dom-dim-height
make_getter!(Height);
// https://html.spec.whatwg.org/multipage/#dom-dim-height
make_setter!(SetHeight, "height");
}
impl<'a> VirtualMethods for &'a HTMLIFrameElement {
impl VirtualMethods for HTMLIFrameElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -395,7 +380,7 @@ impl<'a> VirtualMethods for &'a HTMLIFrameElement {
self.sandbox.set(Some(modes));
}
&atom!("src") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
if node.is_in_doc() {
self.process_the_iframe_attributes()
}
@ -440,7 +425,7 @@ impl<'a> VirtualMethods for &'a HTMLIFrameElement {
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
match (self.containing_page_pipeline_id(), self.subpage_id()) {
(Some(containing_pipeline_id), Some(subpage_id)) => {
let window = window_from_node(*self);
let window = window_from_node(self);
let window = window.r();
let ConstellationChan(ref chan) = window.constellation_chan();

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::attr::Attr;
use dom::attr::{AttrHelpers, AttrValue};
use dom::attr::AttrValue;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
@ -14,15 +14,14 @@ use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{LayoutJS, Root};
use dom::bindings::refcounted::Trusted;
use dom::document::{Document, DocumentHelpers};
use dom::element::AttributeHandlers;
use dom::document::Document;
use dom::element::ElementTypeId;
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{document_from_node, Node, NodeTypeId, NodeHelpers, NodeDamage, window_from_node};
use dom::node::{document_from_node, Node, NodeTypeId, NodeDamage, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use script_task::ScriptTaskEventCategory::UpdateReplacedElement;
use script_task::{Runnable, ScriptChan, CommonScriptMsg};
use string_cache::Atom;
use util::str::DOMString;
@ -37,7 +36,6 @@ use std::borrow::ToOwned;
use std::sync::Arc;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLImageElement {
htmlelement: HTMLElement,
url: DOMRefCell<Option<Url>>,
@ -52,19 +50,13 @@ impl HTMLImageElementDerived for EventTarget {
}
}
pub trait HTMLImageElementHelpers {
fn get_url(&self) -> Option<Url>;
}
impl<'a> HTMLImageElementHelpers for &'a HTMLImageElement {
fn get_url(&self) -> Option<Url>{
impl HTMLImageElement {
pub fn get_url(&self) -> Option<Url>{
self.url.borrow().clone()
}
}
trait PrivateHTMLImageElementHelpers {
fn update_image(self, value: Option<(DOMString, &Url)>);
}
struct ImageResponseHandlerRunnable {
element: Trusted<HTMLImageElement>,
@ -113,10 +105,10 @@ impl Runnable for ImageResponseHandlerRunnable {
}
}
impl<'a> PrivateHTMLImageElementHelpers for &'a HTMLImageElement {
impl HTMLImageElement {
/// 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.
fn update_image(self, value: Option<(DOMString, &Url)>) {
fn update_image(&self, value: Option<(DOMString, &Url)>) {
let node = NodeCast::from_ref(self);
let document = node.owner_doc();
let window = document.r().window();
@ -140,7 +132,7 @@ impl<'a> PrivateHTMLImageElementHelpers for &'a HTMLImageElement {
// Return the image via a message to the script task, which marks the element
// as dirty and triggers a reflow.
let image_response = message.to().unwrap();
script_chan.send(CommonScriptMsg::RunnableMsg(
script_chan.send(CommonScriptMsg::RunnableMsg(UpdateReplacedElement,
box ImageResponseHandlerRunnable::new(
trusted_node.clone(), image_response))).unwrap();
});
@ -151,9 +143,7 @@ impl<'a> PrivateHTMLImageElementHelpers for &'a HTMLImageElement {
}
}
}
}
impl HTMLImageElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLImageElement {
HTMLImageElement {
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLImageElement, localName, prefix, document),
@ -206,55 +196,59 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> {
}
}
impl<'a> HTMLImageElementMethods for &'a HTMLImageElement {
impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-alt
make_getter!(Alt);
// https://html.spec.whatwg.org/multipage/#dom-img-alt
make_setter!(SetAlt, "alt");
// https://html.spec.whatwg.org/multipage/#dom-img-src
make_url_getter!(Src);
// https://html.spec.whatwg.org/multipage/#dom-img-src
make_setter!(SetSrc, "src");
// https://html.spec.whatwg.org/multipage/#dom-img-usemap
make_getter!(UseMap);
// https://html.spec.whatwg.org/multipage/#dom-img-usemap
make_setter!(SetUseMap, "usemap");
// https://html.spec.whatwg.org/multipage/#dom-img-ismap
make_bool_getter!(IsMap);
// https://html.spec.whatwg.org/multipage/#dom-img-ismap
fn SetIsMap(self, is_map: bool) {
fn SetIsMap(&self, is_map: bool) {
let element = ElementCast::from_ref(self);
element.set_string_attribute(&atom!("ismap"), is_map.to_string())
}
// https://html.spec.whatwg.org/multipage/#dom-img-width
fn Width(self) -> u32 {
fn Width(&self) -> u32 {
let node = NodeCast::from_ref(self);
let rect = node.get_bounding_content_box();
rect.size.width.to_px() as u32
}
// https://html.spec.whatwg.org/multipage/#dom-img-width
fn SetWidth(self, width: u32) {
fn SetWidth(&self, width: u32) {
let elem = ElementCast::from_ref(self);
elem.set_uint_attribute(&atom!("width"), width)
}
// https://html.spec.whatwg.org/multipage/#dom-img-height
fn Height(self) -> u32 {
fn Height(&self) -> u32 {
let node = NodeCast::from_ref(self);
let rect = node.get_bounding_content_box();
rect.size.height.to_px() as u32
}
// https://html.spec.whatwg.org/multipage/#dom-img-height
fn SetHeight(self, height: u32) {
fn SetHeight(&self, height: u32) {
let elem = ElementCast::from_ref(self);
elem.set_uint_attribute(&atom!("height"), height)
}
// https://html.spec.whatwg.org/multipage/#dom-img-naturalwidth
fn NaturalWidth(self) -> u32 {
fn NaturalWidth(&self) -> u32 {
let image = self.image.borrow();
match *image {
@ -264,7 +258,7 @@ impl<'a> HTMLImageElementMethods for &'a HTMLImageElement {
}
// https://html.spec.whatwg.org/multipage/#dom-img-naturalheight
fn NaturalHeight(self) -> u32 {
fn NaturalHeight(&self) -> u32 {
let image = self.image.borrow();
match *image {
@ -274,39 +268,51 @@ impl<'a> HTMLImageElementMethods for &'a HTMLImageElement {
}
// https://html.spec.whatwg.org/multipage/#dom-img-complete
fn Complete(self) -> bool {
fn Complete(&self) -> bool {
let image = self.image.borrow();
image.is_some()
}
// https://html.spec.whatwg.org/#dom-img-name
// https://html.spec.whatwg.org/multipage/#dom-img-name
make_getter!(Name);
// https://html.spec.whatwg.org/multipage/#dom-img-name
make_atomic_setter!(SetName, "name");
// https://html.spec.whatwg.org/multipage/#dom-img-align
make_getter!(Align);
// https://html.spec.whatwg.org/multipage/#dom-img-align
make_setter!(SetAlign, "align");
// https://html.spec.whatwg.org/multipage/#dom-img-hspace
make_uint_getter!(Hspace);
// https://html.spec.whatwg.org/multipage/#dom-img-hspace
make_uint_setter!(SetHspace, "hspace");
// https://html.spec.whatwg.org/multipage/#dom-img-vspace
make_uint_getter!(Vspace);
// https://html.spec.whatwg.org/multipage/#dom-img-vspace
make_uint_setter!(SetVspace, "vspace");
// https://html.spec.whatwg.org/multipage/#dom-img-longdesc
make_getter!(LongDesc);
// https://html.spec.whatwg.org/multipage/#dom-img-longdesc
make_setter!(SetLongDesc, "longdesc");
// https://html.spec.whatwg.org/multipage/#dom-img-border
make_getter!(Border);
// https://html.spec.whatwg.org/multipage/#dom-img-border
make_setter!(SetBorder, "border");
}
impl<'a> VirtualMethods for &'a HTMLImageElement {
impl VirtualMethods for HTMLImageElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -317,7 +323,7 @@ impl<'a> VirtualMethods for &'a HTMLImageElement {
match attr.local_name() {
&atom!("src") => {
let window = window_from_node(*self);
let window = window_from_node(self);
let url = window.r().get_url();
self.update_image(Some(((**attr.value()).to_owned(), &url)));
},

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::activation::Activatable;
use dom::attr::AttrHelpers;
use dom::attr::{Attr, AttrValue};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
@ -16,20 +15,17 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInp
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
use dom::document::{Document, DocumentHelpers};
use dom::element::ElementTypeId;
use dom::element::{AttributeHandlers, Element};
use dom::element::{RawLayoutElementHelpers, ActivationElementHelpers};
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
use dom::document::Document;
use dom::element::{Element, ElementTypeId, RawLayoutElementHelpers};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmlformelement::{FormSubmitter, FormControl, HTMLFormElement, HTMLFormElementHelpers};
use dom::htmlformelement::{FormSubmitter, FormControl, HTMLFormElement};
use dom::htmlformelement::{SubmittedFrom, ResetFrom};
use dom::keyboardevent::KeyboardEvent;
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, NodeDamage, NodeTypeId};
use dom::node::{Node, NodeDamage, NodeTypeId};
use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use msg::constellation_msg::ConstellationChan;
use textinput::KeyReaction::{TriggerDefaultAction, DispatchInput, Nothing};
use textinput::Lines::Single;
@ -60,7 +56,6 @@ enum InputType {
}
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLInputElement {
htmlelement: HTMLElement,
input_type: Cell<InputType>,
@ -221,7 +216,7 @@ impl RawLayoutHTMLInputElementHelpers for HTMLInputElement {
}
}
impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
impl HTMLInputElementMethods for HTMLInputElement {
// https://www.whatwg.org/html/#dom-fe-disabled
make_bool_getter!(Disabled);
@ -235,12 +230,12 @@ impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
make_bool_setter!(SetDefaultChecked, "checked");
// https://html.spec.whatwg.org/multipage/#dom-input-checked
fn Checked(self) -> bool {
fn Checked(&self) -> bool {
self.checked.get()
}
// https://html.spec.whatwg.org/multipage/#dom-input-checked
fn SetChecked(self, checked: bool) {
fn SetChecked(&self, checked: bool) {
self.update_checked_state(checked, true);
}
@ -252,6 +247,8 @@ impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-size
make_uint_getter!(Size, "size", DEFAULT_INPUT_SIZE);
// https://html.spec.whatwg.org/multipage/#dom-input-size
make_limited_uint_setter!(SetSize, "size", DEFAULT_INPUT_SIZE);
// https://html.spec.whatwg.org/multipage/#dom-input-type
@ -267,12 +264,12 @@ impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
make_setter!(SetType, "type");
// https://html.spec.whatwg.org/multipage/#dom-input-value
fn Value(self) -> DOMString {
fn Value(&self) -> DOMString {
self.textinput.borrow().get_content()
}
// https://html.spec.whatwg.org/multipage/#dom-input-value
fn SetValue(self, value: DOMString) {
fn SetValue(&self, value: DOMString) {
self.textinput.borrow_mut().set_content(value);
self.value_changed.set(true);
self.force_relayout();
@ -322,26 +319,16 @@ impl<'a> HTMLInputElementMethods for &'a HTMLInputElement {
make_setter!(SetFormTarget, "formtarget");
// https://html.spec.whatwg.org/multipage/#dom-input-indeterminate
fn Indeterminate(self) -> bool {
fn Indeterminate(&self) -> bool {
self.indeterminate.get()
}
// https://html.spec.whatwg.org/multipage/#dom-input-indeterminate
fn SetIndeterminate(self, val: bool) {
fn SetIndeterminate(&self, val: bool) {
self.indeterminate.set(val)
}
}
pub trait HTMLInputElementHelpers {
fn force_relayout(self);
fn radio_group_updated(self, group: Option<&str>);
fn get_radio_group_name(self) -> Option<String>;
fn update_checked_state(self, checked: bool, dirty: bool);
fn get_size(self) -> u32;
fn get_indeterminate_state(self) -> bool;
fn mutable(self) -> bool;
fn reset(self);
}
#[allow(unsafe_code)]
fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&str>) {
@ -385,27 +372,27 @@ fn in_same_group<'a,'b>(other: &'a HTMLInputElement,
}
}
impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement {
fn force_relayout(self) {
impl HTMLInputElement {
pub fn force_relayout(&self) {
let doc = document_from_node(self);
let node = NodeCast::from_ref(self);
doc.r().content_changed(node, NodeDamage::OtherNodeDamage)
}
fn radio_group_updated(self, group: Option<&str>) {
pub fn radio_group_updated(&self, group: Option<&str>) {
if self.Checked() {
broadcast_radio_checked(self, group);
}
}
fn get_radio_group_name(self) -> Option<String> {
pub fn get_radio_group_name(&self) -> Option<String> {
//TODO: determine form owner
let elem = ElementCast::from_ref(self);
elem.get_attribute(&ns!(""), &atom!("name"))
.map(|name| name.r().Value())
}
fn update_checked_state(self, checked: bool, dirty: bool) {
pub fn update_checked_state(&self, checked: bool, dirty: bool) {
self.checked.set(checked);
if dirty {
@ -423,16 +410,16 @@ impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement {
//TODO: dispatch change event
}
fn get_size(self) -> u32 {
pub fn get_size(&self) -> u32 {
self.size.get()
}
fn get_indeterminate_state(self) -> bool {
pub fn get_indeterminate_state(&self) -> bool {
self.indeterminate.get()
}
// https://html.spec.whatwg.org/multipage/#concept-fe-mutable
fn mutable(self) -> bool {
pub fn mutable(&self) -> bool {
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
let node = NodeCast::from_ref(self);
@ -440,7 +427,7 @@ impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement {
}
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control
fn reset(self) {
pub fn reset(&self) {
match self.input_type.get() {
InputType::InputRadio | InputType::InputCheckbox => {
self.update_checked_state(self.DefaultChecked(), false);
@ -456,9 +443,9 @@ impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement {
}
}
impl<'a> VirtualMethods for &'a HTMLInputElement {
impl VirtualMethods for HTMLInputElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -469,7 +456,7 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(true);
node.set_enabled_state(false);
}
@ -532,7 +519,7 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
match attr.local_name() {
&atom!("disabled") => {
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.set_disabled_state(false);
node.set_enabled_state(true);
node.check_ancestors_disabled_state_for_form_control();
@ -548,7 +535,7 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
}
&atom!("type") => {
if self.input_type.get() == InputType::InputRadio {
broadcast_radio_checked(*self,
broadcast_radio_checked(self,
self.get_radio_group_name()
.as_ref()
.map(|group| &**group));
@ -584,7 +571,7 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
s.bind_to_tree(tree_in_doc);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
node.check_ancestors_disabled_state_for_form_control();
}
@ -593,7 +580,7 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
s.unbind_from_tree(tree_in_doc);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
node.check_ancestors_disabled_state_for_form_control();
} else {
@ -617,8 +604,8 @@ impl<'a> VirtualMethods for &'a HTMLInputElement {
//TODO: set the editing position for text inputs
let doc = document_from_node(*self);
doc.r().request_focus(ElementCast::from_ref(*self));
let doc = document_from_node(self);
doc.r().request_focus(ElementCast::from_ref(self));
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() &&
(self.input_type.get() == InputType::InputText ||
self.input_type.get() == InputType::InputPassword) {
@ -652,9 +639,9 @@ impl<'a> FormControl<'a> for &'a HTMLInputElement {
}
}
impl<'a> Activatable for &'a HTMLInputElement {
impl Activatable for HTMLInputElement {
fn as_element<'b>(&'b self) -> &'b Element {
ElementCast::from_ref(*self)
ElementCast::from_ref(self)
}
fn is_instance_activatable(&self) -> bool {
@ -698,7 +685,7 @@ impl<'a> Activatable for &'a HTMLInputElement {
InputType::InputRadio => {
//TODO: if not in document, use root ancestor instead of document
let owner = self.form_owner();
let doc = document_from_node(*self);
let doc = document_from_node(self);
let doc_node = NodeCast::from_ref(doc.r());
let group = self.get_radio_group_name();;
@ -803,19 +790,19 @@ impl<'a> Activatable for &'a HTMLInputElement {
// 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
if self.mutable() {
let win = window_from_node(*self);
let win = window_from_node(self);
let event = Event::new(GlobalRef::Window(win.r()),
"input".to_owned(),
EventBubbles::Bubbles,
EventCancelable::NotCancelable);
let target = EventTargetCast::from_ref(*self);
let target = EventTargetCast::from_ref(self);
event.r().fire(target);
let event = Event::new(GlobalRef::Window(win.r()),
"change".to_owned(),
EventBubbles::Bubbles,
EventCancelable::NotCancelable);
let target = EventTargetCast::from_ref(*self);
let target = EventTargetCast::from_ref(self);
event.r().fire(target);
}
},
@ -826,7 +813,7 @@ impl<'a> Activatable for &'a HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#implicit-submission
#[allow(unsafe_code)]
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
let doc = document_from_node(*self);
let doc = document_from_node(self);
let node = NodeCast::from_ref(doc.r());
let owner = self.form_owner();
let form = match owner {
@ -834,7 +821,7 @@ impl<'a> Activatable for &'a HTMLInputElement {
Some(ref f) => f
};
let elem = ElementCast::from_ref(*self);
let elem = ElementCast::from_ref(self);
if elem.click_in_progress() {
return;
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLLabelElement {
htmlelement: HTMLElement,
}
@ -44,4 +43,3 @@ impl HTMLLabelElement {
Node::reflect_node(box element, document, HTMLLabelElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLLegendElement {
htmlelement: HTMLElement,
}
@ -44,4 +43,3 @@ impl HTMLLegendElement {
Node::reflect_node(box element, document, HTMLLegendElementBinding::Wrap)
}
}

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLLIElement {
htmlelement: HTMLElement,
}
@ -41,4 +40,3 @@ impl HTMLLIElement {
Node::reflect_node(box element, document, HTMLLIElementBinding::Wrap)
}
}

View file

@ -4,7 +4,6 @@
use cssparser::Parser as CssParser;
use document_loader::LoadType;
use dom::attr::AttrHelpers;
use dom::attr::{Attr, AttrValue};
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding;
use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods;
@ -15,16 +14,14 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::js::{RootedReference};
use dom::bindings::refcounted::Trusted;
use dom::document::{Document, DocumentHelpers};
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
use dom::element::ElementTypeId;
use dom::element::{AttributeHandlers, Element};
use dom::event::{EventBubbles, EventCancelable, Event, EventHelpers};
use dom::element::{Element, ElementTypeId};
use dom::event::{EventBubbles, EventCancelable, Event};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
use dom::node::{Node, NodeTypeId, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use layout_interface::{LayoutChan, Msg};
use msg::constellation_msg::ConstellationChan;
use msg::constellation_msg::Msg as ConstellationMsg;
@ -39,7 +36,6 @@ use string_cache::Atom;
use url::UrlParser;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLLinkElement {
htmlelement: HTMLElement,
rel_list: MutNullableHeap<JS<DOMTokenList>>,
@ -101,9 +97,9 @@ fn is_favicon(value: &Option<String>) -> bool {
}
}
impl<'a> VirtualMethods for &'a HTMLLinkElement {
impl VirtualMethods for HTMLLinkElement {
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self);
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
Some(htmlelement as &VirtualMethods)
}
@ -112,12 +108,12 @@ impl<'a> VirtualMethods for &'a HTMLLinkElement {
s.after_set_attr(attr);
}
let node = NodeCast::from_ref(*self);
let node = NodeCast::from_ref(self);
if !node.is_in_doc() {
return;
}
let element = ElementCast::from_ref(*self);
let element = ElementCast::from_ref(self);
let rel = get_attr(element, &atom!("rel"));
match (rel, attr.local_name()) {
@ -150,7 +146,7 @@ impl<'a> VirtualMethods for &'a HTMLLinkElement {
}
if tree_in_doc {
let element = ElementCast::from_ref(*self);
let element = ElementCast::from_ref(self);
let rel = get_attr(element, &atom!("rel"));
let href = get_attr(element, &atom!("href"));
@ -168,13 +164,9 @@ impl<'a> VirtualMethods for &'a HTMLLinkElement {
}
}
trait PrivateHTMLLinkElementHelpers {
fn handle_stylesheet_url(self, href: &str);
fn handle_favicon_url(self, href: &str);
}
impl<'a> PrivateHTMLLinkElementHelpers for &'a HTMLLinkElement {
fn handle_stylesheet_url(self, href: &str) {
impl HTMLLinkElement {
fn handle_stylesheet_url(&self, href: &str) {
let window = window_from_node(self);
let window = window.r();
match UrlParser::new().base_url(&window.get_url()).parse(href) {
@ -202,7 +194,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for &'a HTMLLinkElement {
}
}
fn handle_favicon_url(self, href: &str) {
fn handle_favicon_url(&self, href: &str) {
let window = window_from_node(self);
let window = window.r();
match UrlParser::new().base_url(&window.get_url()).parse(href) {
@ -216,24 +208,39 @@ impl<'a> PrivateHTMLLinkElementHelpers for &'a HTMLLinkElement {
}
}
impl<'a> HTMLLinkElementMethods for &'a HTMLLinkElement {
impl HTMLLinkElementMethods for HTMLLinkElement {
// https://html.spec.whatwg.org/multipage/#dom-link-href
make_url_getter!(Href);
// https://html.spec.whatwg.org/multipage/#dom-link-href
make_setter!(SetHref, "href");
// https://html.spec.whatwg.org/multipage/#dom-link-rel
make_getter!(Rel);
// https://html.spec.whatwg.org/multipage/#dom-link-rel
make_setter!(SetRel, "rel");
// https://html.spec.whatwg.org/multipage/#dom-link-media
make_getter!(Media);
// https://html.spec.whatwg.org/multipage/#dom-link-media
make_setter!(SetMedia, "media");
// https://html.spec.whatwg.org/multipage/#dom-link-hreflang
make_getter!(Hreflang);
// https://html.spec.whatwg.org/multipage/#dom-link-hreflang
make_setter!(SetHreflang, "hreflang");
// https://html.spec.whatwg.org/multipage/#dom-link-type
make_getter!(Type);
// https://html.spec.whatwg.org/multipage/#dom-link-type
make_setter!(SetType, "type");
// https://html.spec.whatwg.org/multipage/#dom-link-rellist
fn RelList(self) -> Root<DOMTokenList> {
fn RelList(&self) -> Root<DOMTokenList> {
self.rel_list.or_init(|| {
DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel"))
})

View file

@ -13,7 +13,6 @@ use dom::node::{Node, NodeTypeId};
use util::str::DOMString;
#[dom_struct]
#[derive(HeapSizeOf)]
pub struct HTMLMapElement {
htmlelement: HTMLElement
}
@ -43,4 +42,3 @@ impl HTMLMapElement {
Node::reflect_node(box element, document, HTMLMapElementBinding::Wrap)
}
}

Some files were not shown because too many files have changed in this diff Show more