auto merge of #1934 : larsbergstrom/servo/rust_20140224_squashed, r=jdm

For review only - don't approve yet (need to squash and land submodule updates first). 

critic? @metajack
This commit is contained in:
bors-servo 2014-03-19 12:35:17 -04:00
commit f7aa6e3d9b
148 changed files with 1405 additions and 1227 deletions

2
.gitmodules vendored
View file

@ -69,7 +69,7 @@
url = https://github.com/mozilla-servo/skia.git url = https://github.com/mozilla-servo/skia.git
[submodule "src/compiler/rust"] [submodule "src/compiler/rust"]
path = src/compiler/rust path = src/compiler/rust
url = https://github.com/mozilla-servo/rust.git url = https://github.com/mozilla/rust.git
[submodule "src/support/alert/rust-alert"] [submodule "src/support/alert/rust-alert"]
path = src/support/alert/rust-alert path = src/support/alert/rust-alert
url = https://github.com/mozilla-servo/rust-alert.git url = https://github.com/mozilla-servo/rust-alert.git

View file

@ -35,18 +35,13 @@ ifdef CFG_DISABLE_OPTIMIZE
$(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE)) $(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE))
CFG_RUSTC_FLAGS += CFG_RUSTC_FLAGS +=
else else
CFG_RUSTC_FLAGS += -O -Z no-debug-borrows CFG_RUSTC_FLAGS += -O
endif endif
CFG_RUSTC_FLAGS += -g
ifdef CFG_ENABLE_DEBUG ifdef CFG_ENABLE_DEBUG
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG)) $(info cfg: enabling more debugging in RUSTC (CFG_ENABLE_DEBUG))
CFG_RUSTC_FLAGS += -Z extra-debug-info CFG_RUSTC_SELF_FLAGS += -g
CFG_RUSTC_SELF_FLAGS += -Z extra-debug-info
else
# Enable debug!() etc even without configure --enable-debug
# The evaluation of these prints & their arguments is controlled
# at runtime by the environment variable RUST_LOG.
CFG_RUSTC_FLAGS += -Z debug-info
endif endif
export CFG_RUSTC export CFG_RUSTC
@ -135,8 +130,6 @@ endif
# their name already, while others don't. # their name already, while others don't.
DONE_$(1) = $$(B)src/$$(PATH_$(1))/lib*.dummy DONE_$(1) = $$(B)src/$$(PATH_$(1))/lib*.dummy
DEPS_SUBMODULES += $$(PATH_$(1)) DEPS_SUBMODULES += $$(PATH_$(1))
DEPS_SUBMODULES += $$(PATH_$(1))/.libs
DEPS_SUBMODULES += $$(PATH_$(1))/src/.libs
endef endef
# these will get populated. # these will get populated.
@ -163,7 +156,7 @@ endef
define DEF_SUBMODULE_RULES define DEF_SUBMODULE_RULES
ENV_RLDFLAGS_$(1) = -L $$(CFG_BUILD_HOME)workspace/lib/$$(CFG_TARGET_TRIPLES) ENV_RLDFLAGS_$(1) = -L $$(CFG_BUILD_HOME)workspace/lib/$$(CFG_TARGET_TRIPLES)
ENV_RLDFLAGS_$(1) += $$(foreach dep,$$(DEPS_$(1)),-L $$(B)src/$$(PATH_$$(dep)) -L $$(B)src/$$(PATH_$$(dep))/.libs -L $$(B)src/$$(PATH_$$(dep))/src/.libs) ENV_RLDFLAGS_$(1) += $$(foreach dep,$$(DEPS_$(1)),-L $$(B)src/$$(PATH_$$(dep)))
# variables that depend on dependency definitions from sub.mk! # variables that depend on dependency definitions from sub.mk!
ENV_CFLAGS_$(1) = CFLAGS="$$(CFLAGS_$(1))" ENV_CFLAGS_$(1) = CFLAGS="$$(CFLAGS_$(1))"
@ -329,11 +322,11 @@ $(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \
ifneq ($(CFG_OSTYPE),linux-androideabi) ifneq ($(CFG_OSTYPE),linux-androideabi)
servo: $(DEPS_servo) servo: $(DEPS_servo)
@$(call E, compile: $@) @$(call E, compile: $@)
$(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $< --bin $(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $<
else else
servo: $(DEPS_servo) servo: $(DEPS_servo)
@$(call E, compile: $@) @$(call E, compile: $@)
$(Q)$(RUSTC) $(RFLAGS_servo) -Z gen-crate-map -o $@ $< --lib $(Q)$(RUSTC) $(RFLAGS_servo) -C gen-crate-map -o $@ $< --crate-type lib
endif endif
# Darwin app packaging # Darwin app packaging

2
configure vendored
View file

@ -385,7 +385,7 @@ case ${TARGET_OSTYPE} in
probe CFG_RANLIB arm-linux-androideabi-ranlib probe CFG_RANLIB arm-linux-androideabi-ranlib
export PATH=${OLD_PATH} export PATH=${OLD_PATH}
CFG_RUSTC_FLAGS="--target=${CFG_TARGET_TRIPLES} --android-cross-path=${CFG_ANDROID_CROSS_PATH}" CFG_RUSTC_FLAGS="--target=${CFG_TARGET_TRIPLES} -C android-cross-path=${CFG_ANDROID_CROSS_PATH}"
;; ;;
*) *)
CFG_PATH=$PATH CFG_PATH=$PATH

@ -1 +1 @@
Subproject commit d3b3c66a3a54a0455b068ede8fe2f48ed99ca908 Subproject commit 68a4f7d9babb0c638f3425ced08e13f9fbfdcf56

View file

@ -1,4 +1,4 @@
# If this file is modified, then rust will be forcibly cleaned and then rebuilt. # If this file is modified, then rust will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the # The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime. # build bots then the contents should be changed so git updates the mtime.
2014-01-08 2014-02-24

View file

@ -2,12 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use collections::hashmap::HashMap;
use geom::size::Size2D; use geom::size::Size2D;
use layers::platform::surface::NativePaintingGraphicsContext; use layers::platform::surface::NativePaintingGraphicsContext;
use servo_msg::compositor_msg::Tile; use servo_msg::compositor_msg::Tile;
use std::hashmap::HashMap; use std::hash::Hash;
use std::to_bytes::Cb; use std::hash::sip::SipState;
use std::util; use std::mem;
/// This is a struct used to store buffers when they are not in use. /// This is a struct used to store buffers when they are not in use.
/// The render task can quickly query for a particular size of buffer when it /// The render task can quickly query for a particular size of buffer when it
@ -27,16 +28,18 @@ pub struct BufferMap<T> {
/// A key with which to store buffers. It is based on the size of the buffer. /// A key with which to store buffers. It is based on the size of the buffer.
struct BufferKey([uint, ..2]); struct BufferKey([uint, ..2]);
impl IterBytes for BufferKey { impl Hash for BufferKey {
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { fn hash(&self, state: &mut SipState) {
let i = if lsb0 {0} else {1}; let BufferKey(ref bytes) = *self;
self[i].iter_bytes(lsb0, |x| f(x)) && self[1 - i].iter_bytes(lsb0, |x| f(x)) bytes.as_slice().hash(state);
} }
} }
impl Eq for BufferKey { impl Eq for BufferKey {
fn eq(&self, other: &BufferKey) -> bool { fn eq(&self, other: &BufferKey) -> bool {
self[0] == other[0] && self[1] == other[1] let BufferKey(s) = *self;
let BufferKey(o) = *other;
s[0] == o[0] && s[1] == o[1]
} }
} }
@ -79,9 +82,10 @@ impl<T: Tile> BufferMap<T> {
self.mem += new_buffer.get_mem(); self.mem += new_buffer.get_mem();
// use lazy insertion function to prevent unnecessary allocation // use lazy insertion function to prevent unnecessary allocation
let counter = &self.counter;
self.map.find_or_insert_with(new_key, |_| BufferValue { self.map.find_or_insert_with(new_key, |_| BufferValue {
buffers: ~[], buffers: ~[],
last_action: self.counter last_action: *counter
}).buffers.push(new_buffer); }).buffers.push(new_buffer);
let mut opt_key: Option<BufferKey> = None; let mut opt_key: Option<BufferKey> = None;
@ -97,7 +101,7 @@ impl<T: Tile> BufferMap<T> {
}; };
if { if {
let list = &mut self.map.get_mut(&old_key).buffers; let list = &mut self.map.get_mut(&old_key).buffers;
let condemned_buffer = list.pop(); let condemned_buffer = list.pop().take_unwrap();
self.mem -= condemned_buffer.get_mem(); self.mem -= condemned_buffer.get_mem();
condemned_buffer.destroy(graphics_context); condemned_buffer.destroy(graphics_context);
list.is_empty() list.is_empty()
@ -120,7 +124,7 @@ impl<T: Tile> BufferMap<T> {
buffer_val.last_action = self.counter; buffer_val.last_action = self.counter;
self.counter += 1; self.counter += 1;
let buffer = buffer_val.buffers.pop(); let buffer = buffer_val.buffers.pop().take_unwrap();
self.mem -= buffer.get_mem(); self.mem -= buffer.get_mem();
if buffer_val.buffers.is_empty() { if buffer_val.buffers.is_empty() {
flag = true; flag = true;
@ -139,7 +143,7 @@ impl<T: Tile> BufferMap<T> {
/// Destroys all buffers. /// Destroys all buffers.
pub fn clear(&mut self, graphics_context: &NativePaintingGraphicsContext) { pub fn clear(&mut self, graphics_context: &NativePaintingGraphicsContext) {
let map = util::replace(&mut self.map, HashMap::new()); let map = mem::replace(&mut self.map, HashMap::new());
for (_, value) in map.move_iter() { for (_, value) in map.move_iter() {
for tile in value.buffers.move_iter() { for tile in value.buffers.move_iter() {
tile.destroy(graphics_context) tile.destroy(graphics_context)

View file

@ -18,14 +18,14 @@ use color::Color;
use render_context::RenderContext; use render_context::RenderContext;
use text::TextRun; use text::TextRun;
use extra::arc::Arc;
use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use geom::{Point2D, Rect, Size2D, SideOffsets2D};
use servo_net::image::base::Image; use servo_net::image::base::Image;
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cast::transmute_region; use std::cast::transmute_region;
use std::vec::VecIterator; use std::vec::Items;
use style::computed_values::border_style; use style::computed_values::border_style;
use sync::Arc;
pub struct DisplayListCollection<E> { pub struct DisplayListCollection<E> {
lists: ~[DisplayList<E>] lists: ~[DisplayList<E>]
@ -70,7 +70,7 @@ pub struct DisplayList<E> {
pub enum DisplayListIterator<'a,E> { pub enum DisplayListIterator<'a,E> {
EmptyDisplayListIterator, EmptyDisplayListIterator,
ParentDisplayListIterator(VecIterator<'a,DisplayList<E>>), ParentDisplayListIterator(Items<'a,DisplayList<E>>),
} }
impl<'a,E> Iterator<&'a DisplayList<E>> for DisplayListIterator<'a,E> { impl<'a,E> Iterator<&'a DisplayList<E>> for DisplayListIterator<'a,E> {
@ -226,7 +226,7 @@ pub struct ClipDisplayItem<E> {
pub enum DisplayItemIterator<'a,E> { pub enum DisplayItemIterator<'a,E> {
EmptyDisplayItemIterator, EmptyDisplayItemIterator,
ParentDisplayItemIterator(VecIterator<'a,DisplayItem<E>>), ParentDisplayItemIterator(Items<'a,DisplayItem<E>>),
} }
impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> { impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> {

View file

@ -5,7 +5,6 @@
use azure::{AzFloat, AzScaledFontRef}; use azure::{AzFloat, AzScaledFontRef};
use azure::azure_hl::{BackendType, ColorPattern}; use azure::azure_hl::{BackendType, ColorPattern};
use azure::scaled_font::ScaledFont; use azure::scaled_font::ScaledFont;
use extra::arc::Arc;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use std::cast; use std::cast;
use std::ptr; use std::ptr;
@ -15,6 +14,7 @@ use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache}; use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range; use servo_util::range::Range;
use style::computed_values::{text_decoration, font_weight, font_style}; use style::computed_values::{text_decoration, font_weight, font_style};
use sync::Arc;
use color::Color; use color::Color;
use font_context::FontContext; use font_context::FontContext;
@ -230,7 +230,7 @@ impl<'a> Font {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
return Ok(Rc::from_mut(RefCell::new(Font { return Ok(Rc::new(RefCell::new(Font {
handle: handle, handle: handle,
azure_font: None, azure_font: None,
shaper: None, shaper: None,
@ -269,7 +269,7 @@ impl<'a> Font {
Err(()) => return Err(()) Err(()) => return Err(())
}; };
return Ok(Rc::from_mut(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend)))); return Ok(Rc::new(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend))));
} }
fn make_shaper(&'a mut self) -> &'a Shaper { fn make_shaper(&'a mut self) -> &'a Shaper {
@ -394,9 +394,9 @@ impl Font {
// TODO(Issue #64): this call needs to move into azure_hl.rs // TODO(Issue #64): this call needs to move into azure_hl.rs
AzDrawTargetFillGlyphs(target.azure_draw_target, AzDrawTargetFillGlyphs(target.azure_draw_target,
azfontref, azfontref,
ptr::to_unsafe_ptr(&glyphbuf), &glyphbuf,
azure_pattern, azure_pattern,
ptr::to_unsafe_ptr(&options), &options,
ptr::null()); ptr::null());
} }
} }
@ -428,9 +428,10 @@ impl Font {
//FIXME (ksh8281) //FIXME (ksh8281)
self.make_shaper(); self.make_shaper();
let shaper = &self.shaper;
self.shape_cache.find_or_create(&text, |txt| { self.shape_cache.find_or_create(&text, |txt| {
let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace); let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace);
self.shaper.get_ref().shape_text(*txt, &mut glyphs); shaper.get_ref().shape_text(*txt, &mut glyphs);
Arc::new(glyphs) Arc::new(glyphs)
}) })
} }
@ -444,8 +445,9 @@ impl Font {
} }
pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel { pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel {
let handle = &self.handle;
self.glyph_advance_cache.find_or_create(&glyph, |glyph| { self.glyph_advance_cache.find_or_create(&glyph, |glyph| {
match self.handle.glyph_h_advance(*glyph) { match handle.glyph_h_advance(*glyph) {
Some(adv) => adv, Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel
} }

View file

@ -9,9 +9,9 @@ use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType; use azure::azure_hl::BackendType;
use collections::hashmap::HashMap;
use servo_util::cache::{Cache, LRUCache}; use servo_util::cache::{Cache, LRUCache};
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::hashmap::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
@ -148,7 +148,7 @@ impl FontContext {
Some(ref result) => { Some(ref result) => {
found = true; found = true;
let instance = self.get_font_by_descriptor(result); let instance = self.get_font_by_descriptor(result);
instance.map(|font| fonts.push(font.clone())); let _ = instance.map(|font| fonts.push(font.clone()));
}, },
_ => {} _ => {}
} }
@ -186,7 +186,7 @@ impl FontContext {
match font_desc { match font_desc {
Some(ref fd) => { Some(ref fd) => {
let instance = self.get_font_by_descriptor(fd); let instance = self.get_font_by_descriptor(fd);
instance.map(|font| fonts.push(font.clone())); let _ = instance.map(|font| fonts.push(font.clone()));
}, },
None => { } None => { }
}; };
@ -198,11 +198,9 @@ impl FontContext {
debug!("(create font group) --- finished ---"); debug!("(create font group) --- finished ---");
unsafe { Rc::new(
Rc::new_unchecked( RefCell::new(
RefCell::new( FontGroup::new(style.families.to_owned(), &used_style, fonts)))
FontGroup::new(style.families.to_owned(), &used_style, fonts)))
}
} }
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> { fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> {
@ -213,7 +211,7 @@ impl FontContext {
desc.style.clone()); desc.style.clone());
result_handle.and_then(|handle| { result_handle.and_then(|handle| {
Ok( Ok(
Rc::from_mut( Rc::new(
RefCell::new( RefCell::new(
Font::new_from_adopted_handle(self, Font::new_from_adopted_handle(self,
handle, handle,

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use collections::hashmap::HashMap;
use font::SpecifiedFontStyle; use font::SpecifiedFontStyle;
use gfx_font::FontHandleMethods; use gfx_font::FontHandleMethods;
use platform::font::FontHandle; use platform::font::FontHandle;
@ -11,7 +12,6 @@ use style::computed_values::{font_weight, font_style};
use servo_util::time::{ProfilerChan, profile}; use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use std::hashmap::HashMap;
pub type FontFamilyMap = HashMap<~str, FontFamily>; pub type FontFamilyMap = HashMap<~str, FontFamily>;

View file

@ -7,29 +7,31 @@
#[feature(globs, managed_boxes, macro_rules)]; #[feature(globs, managed_boxes, macro_rules)];
extern mod azure; extern crate azure;
extern mod extra; extern crate collections;
extern mod geom; extern crate extra;
extern mod layers; extern crate geom;
extern mod stb_image; extern crate layers;
extern mod png; extern crate stb_image;
extern mod servo_net = "net"; extern crate png;
extern mod servo_util = "util"; extern crate servo_net = "net";
extern mod style; extern crate servo_util = "util";
extern mod servo_msg = "msg"; extern crate servo_msg = "msg";
extern crate style;
extern crate sync;
// Eventually we would like the shaper to be pluggable, as many operating systems have their own // Eventually we would like the shaper to be pluggable, as many operating systems have their own
// shapers. For now, however, this is a hard dependency. // shapers. For now, however, this is a hard dependency.
extern mod harfbuzz; extern crate harfbuzz;
// Linux and Android-specific library dependencies // Linux and Android-specific library dependencies
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern mod fontconfig; #[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate fontconfig;
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern mod freetype; #[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate freetype;
// Mac OS-specific library dependencies // Mac OS-specific library dependencies
#[cfg(target_os="macos")] extern mod core_foundation; #[cfg(target_os="macos")] extern crate core_foundation;
#[cfg(target_os="macos")] extern mod core_graphics; #[cfg(target_os="macos")] extern crate core_graphics;
#[cfg(target_os="macos")] extern mod core_text; #[cfg(target_os="macos")] extern crate core_text;
pub use gfx_font = font; pub use gfx_font = font;
pub use gfx_font_context = font_context; pub use gfx_font_context = font_context;

View file

@ -9,12 +9,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(this) = self;
(this & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(this) = *self;
*self = $bitfieldname((this & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};
@ -102,8 +102,8 @@ impl FontHandleMethods for FontHandle {
let mut face: FT_Face = ptr::null(); let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long, let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
if !result.succeeded() || face.is_null() { if !result.succeeded() || face.is_null() {
return Err(()); return Err(());
} }
@ -286,7 +286,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());
@ -313,7 +313,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());

View file

@ -14,7 +14,7 @@ use std::ptr;
use std::rc::Rc; use std::rc::Rc;
#[deriving(Clone)] #[deriving(Clone)]
struct FreeTypeLibraryHandle { pub struct FreeTypeLibraryHandle {
ctx: FT_Library, ctx: FT_Library,
} }

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
extern mod fontconfig; extern crate fontconfig;
use fontconfig::fontconfig::{ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcChar8, FcResultMatch, FcSetSystem, FcPattern,
@ -25,7 +25,7 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::font::FontHandle; use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use std::hashmap::HashMap; use collections::hashmap::HashMap;
use std::libc; use std::libc;
use std::libc::{c_int, c_char}; use std::libc::{c_int, c_char};
use std::ptr; use std::ptr;
@ -68,7 +68,7 @@ impl FontListHandle {
unsafe { unsafe {
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem); let font_set = FcConfigGetFonts(config, FcSetSystem);
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set); let font_set_array_ptr = &font_set;
let pattern = FcPatternCreate(); let pattern = FcPatternCreate();
assert!(pattern.is_not_null()); assert!(pattern.is_not_null());
"family".to_c_str().with_ref(|FC_FAMILY| { "family".to_c_str().with_ref(|FC_FAMILY| {

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};
@ -102,8 +102,8 @@ impl FontHandleMethods for FontHandle {
let mut face: FT_Face = ptr::null(); let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long, let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
if !result.succeeded() || face.is_null() { if !result.succeeded() || face.is_null() {
return Err(()); return Err(());
} }
@ -286,7 +286,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());
@ -313,7 +313,7 @@ impl<'a> FontHandle {
let face_index = 0 as FT_Long; let face_index = 0 as FT_Long;
file.to_c_str().with_ref(|file_str| { file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str, FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face)); face_index, &mut face);
}); });
if face.is_null() { if face.is_null() {
return Err(()); return Err(());

View file

@ -14,7 +14,7 @@ use std::ptr;
use std::rc::Rc; use std::rc::Rc;
#[deriving(Clone)] #[deriving(Clone)]
struct FreeTypeLibraryHandle { pub struct FreeTypeLibraryHandle {
ctx: FT_Library, ctx: FT_Library,
} }

View file

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod freetype; extern crate freetype;
extern mod fontconfig; extern crate fontconfig;
use fontconfig::fontconfig::{ use fontconfig::fontconfig::{
FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcChar8, FcResultMatch, FcSetSystem, FcPattern,
@ -25,7 +25,7 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::font::FontHandle; use platform::font::FontHandle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use std::hashmap::HashMap; use collections::HashMap;
use std::libc; use std::libc;
use std::libc::{c_int, c_char}; use std::libc::{c_int, c_char};
use std::ptr; use std::ptr;
@ -68,7 +68,7 @@ impl FontListHandle {
unsafe { unsafe {
let config = FcConfigGetCurrent(); let config = FcConfigGetCurrent();
let font_set = FcConfigGetFonts(config, FcSetSystem); let font_set = FcConfigGetFonts(config, FcSetSystem);
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set); let font_set_array_ptr = &font_set;
let pattern = FcPatternCreate(); let pattern = FcPatternCreate();
assert!(pattern.is_not_null()); assert!(pattern.is_not_null());
"family".to_c_str().with_ref(|FC_FAMILY| { "family".to_c_str().with_ref(|FC_FAMILY| {

View file

@ -4,9 +4,9 @@
/// Implementation of Quartz (CoreGraphics) fonts. /// Implementation of Quartz (CoreGraphics) fonts.
extern mod core_foundation; extern crate core_foundation;
extern mod core_graphics; extern crate core_graphics;
extern mod core_text; extern crate core_text;
use font::{FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontHandleMethods, FontMetrics, FontTableMethods};
use font::FontTableTag; use font::FontTableTag;
@ -130,8 +130,8 @@ impl FontHandleMethods for FontHandle {
let glyphs: [CGGlyph, ..1] = [0 as CGGlyph]; let glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
let count: CFIndex = 1; let count: CFIndex = 1;
let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]), let result = self.ctfont.get_glyphs_for_characters(&characters[0],
ptr::to_unsafe_ptr(&glyphs[0]), &glyphs[0],
count); count);
if !result { if !result {

View file

@ -7,12 +7,12 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
use platform::macos::font::FontHandle; use platform::macos::font::FontHandle;
use platform::macos::font_context::FontContextHandle; use platform::macos::font_context::FontContextHandle;
use collections::hashmap::HashMap;
use core_foundation::base::TCFType; use core_foundation::base::TCFType;
use core_foundation::string::{CFString, CFStringRef}; use core_foundation::string::{CFString, CFStringRef};
use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef}; use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
use core_text; use core_text;
use std::cast; use std::cast;
use std::hashmap::HashMap;
pub struct FontListHandle { pub struct FontListHandle {
fctx: FontContextHandle, fctx: FontContextHandle,

View file

@ -9,7 +9,6 @@ use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions};
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions}; use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions};
use azure::AZ_CAP_BUTT; use azure::AZ_CAP_BUTT;
use azure::AzFloat; use azure::AzFloat;
use extra::arc::Arc;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -20,6 +19,7 @@ use servo_util::geometry::Au;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use std::libc::types::common::c99::uint16_t; use std::libc::types::common::c99::uint16_t;
use std::libc::size_t; use std::libc::size_t;
use sync::Arc;
pub struct RenderContext<'a> { pub struct RenderContext<'a> {
draw_target: &'a DrawTarget, draw_target: &'a DrawTarget,
@ -273,16 +273,6 @@ impl<'a> RenderContext<'a> {
} }
} }
trait to_float {
fn to_float(&self) -> f64;
}
impl to_float for u8 {
fn to_float(&self) -> f64 {
(*self as f64) / 255f64
}
}
trait ToAzureRect { trait ToAzureRect {
fn to_azure_rect(&self) -> Rect<AzFloat>; fn to_azure_rect(&self) -> Rect<AzFloat>;
} }

View file

@ -22,9 +22,9 @@ use servo_util::time::{ProfilerChan, profile};
use servo_util::time; use servo_util::time;
use servo_util::task::send_on_failure; use servo_util::task::send_on_failure;
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port};
use std::task; use std::task;
use extra::arc::Arc; use sync::Arc;
use buffer_map::BufferMap; use buffer_map::BufferMap;
use display_list::DisplayListCollection; use display_list::DisplayListCollection;
@ -66,7 +66,7 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
// FIXME(rust#9155): this should be a newtype struct, but // FIXME(rust#9155): this should be a newtype struct, but
// generic newtypes ICE when compiled cross-crate // generic newtypes ICE when compiled cross-crate
pub struct RenderChan<T> { pub struct RenderChan<T> {
chan: SharedChan<Msg<T>>, chan: Chan<Msg<T>>,
} }
impl<T: Send> Clone for RenderChan<T> { impl<T: Send> Clone for RenderChan<T> {
@ -79,7 +79,7 @@ impl<T: Send> Clone for RenderChan<T> {
impl<T: Send> RenderChan<T> { impl<T: Send> RenderChan<T> {
pub fn new() -> (Port<Msg<T>>, RenderChan<T>) { pub fn new() -> (Port<Msg<T>>, RenderChan<T>) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let render_chan = RenderChan { let render_chan = RenderChan {
chan: chan, chan: chan,
}; };
@ -149,9 +149,9 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) { shutdown_chan: Chan<()>) {
let mut builder = task::task(); let mut builder = task::task().named("RenderTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(c) = constellation_chan.clone();
builder.name("RenderTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), c);
builder.spawn(proc() { builder.spawn(proc() {
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg { // Ensures RenderTask and graphics context are destroyed before shutdown msg
@ -191,8 +191,10 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
render_task.start(); render_task.start();
// Destroy all the buffers. // Destroy all the buffers.
render_task.native_graphics_context.as_ref().map( match render_task.native_graphics_context.as_ref() {
|ctx| render_task.buffer_map.clear(ctx)); Some(ctx) => render_task.buffer_map.clear(ctx),
None => (),
}
} }
debug!("render_task: shutdown_chan send"); debug!("render_task: shutdown_chan send");
@ -211,7 +213,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.compositor.set_layer_page_size_and_color(self.id, render_layer.size, self.epoch, render_layer.color); self.compositor.set_layer_page_size_and_color(self.id, render_layer.size, self.epoch, render_layer.color);
} else { } else {
debug!("render_task: render ready msg"); debug!("render_task: render ready msg");
self.constellation_chan.send(RendererReadyMsg(self.id)); let ConstellationChan(ref mut c) = self.constellation_chan;
c.send(RendererReadyMsg(self.id));
} }
self.render_layer = Some(render_layer); self.render_layer = Some(render_layer);
} }
@ -251,12 +254,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
} }
fn render(&mut self, tiles: ~[BufferRequest], scale: f32) { fn render(&mut self, tiles: ~[BufferRequest], scale: f32) {
let render_layer; if self.render_layer.is_none() {
match self.render_layer { return
Some(ref r_layer) => {
render_layer = r_layer;
}
_ => return, // nothing to do
} }
self.compositor.set_render_state(RenderingRenderState); self.compositor.set_render_state(RenderingRenderState);
@ -311,6 +310,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
// Draw the display list. // Draw the display list.
profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || { profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || {
let render_layer = self.render_layer.as_ref().unwrap();
render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx); render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx);
ctx.draw_target.flush(); ctx.draw_target.flush();
}); });
@ -395,7 +395,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.compositor.paint(self.id, layer_buffer_set, self.epoch); self.compositor.paint(self.id, layer_buffer_set, self.epoch);
} else { } else {
debug!("render_task: RendererReadyMsg send"); debug!("render_task: RendererReadyMsg send");
self.constellation_chan.send(RendererReadyMsg(self.id)); let ConstellationChan(ref mut c) = self.constellation_chan;
c.send(RendererReadyMsg(self.id));
} }
self.compositor.set_render_state(IdleRenderState); self.compositor.set_render_state(IdleRenderState);
}) })

View file

@ -9,9 +9,9 @@ use servo_util::geometry;
use std::cmp::{Ord, Eq}; use std::cmp::{Ord, Eq};
use std::num::NumCast; use std::num::NumCast;
use std::mem;
use std::u16; use std::u16;
use std::vec; use std::vec;
use std::util;
use std::iter; use std::iter;
use geom::point::Point2D; use geom::point::Point2D;
@ -45,7 +45,8 @@ impl GlyphEntry {
assert!(is_simple_advance(advance)); assert!(is_simple_advance(advance));
let index_mask = index as u32; let index_mask = index as u32;
let advance_mask = (*advance as u32) << GLYPH_ADVANCE_SHIFT; let Au(advance) = advance;
let advance_mask = (advance as u32) << GLYPH_ADVANCE_SHIFT;
GlyphEntry::new(index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH) GlyphEntry::new(index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH)
} }
@ -53,7 +54,7 @@ impl GlyphEntry {
// Create a GlyphEntry for uncommon case; should be accompanied by // Create a GlyphEntry for uncommon case; should be accompanied by
// initialization of the actual DetailedGlyph data in DetailedGlyphStore // initialization of the actual DetailedGlyph data in DetailedGlyphStore
fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: uint) -> GlyphEntry { fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: uint) -> GlyphEntry {
assert!(glyph_count <= u16::max_value as uint); assert!(glyph_count <= u16::MAX as uint);
debug!("creating complex glyph entry: starts_cluster={}, starts_ligature={}, \ debug!("creating complex glyph entry: starts_cluster={}, starts_ligature={}, \
glyph_count={}", glyph_count={}",
@ -77,7 +78,7 @@ impl GlyphEntry {
/// Create a GlyphEntry for the case where glyphs couldn't be found for the specified /// Create a GlyphEntry for the case where glyphs couldn't be found for the specified
/// character. /// character.
fn missing(glyph_count: uint) -> GlyphEntry { fn missing(glyph_count: uint) -> GlyphEntry {
assert!(glyph_count <= u16::max_value as uint); assert!(glyph_count <= u16::MAX as uint);
GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT) GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT)
} }
@ -404,7 +405,7 @@ impl<'a> DetailedGlyphStore {
// Thar be dragons here. You have been warned. (Tips accepted.) // Thar be dragons here. You have been warned. (Tips accepted.)
let mut unsorted_records: ~[DetailedGlyphRecord] = ~[]; let mut unsorted_records: ~[DetailedGlyphRecord] = ~[];
util::swap(&mut self.detail_lookup, &mut unsorted_records); mem::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records; let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
mut_records.sort_by(|a, b| { mut_records.sort_by(|a, b| {
if a < b { if a < b {
@ -414,7 +415,7 @@ impl<'a> DetailedGlyphStore {
} }
}); });
let mut sorted_records = mut_records; let mut sorted_records = mut_records;
util::swap(&mut self.detail_lookup, &mut sorted_records); mem::swap(&mut self.detail_lookup, &mut sorted_records);
self.lookup_is_sorted = true; self.lookup_is_sorted = true;
} }

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern mod harfbuzz; extern crate harfbuzz;
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
use platform::font::FontTable; use platform::font::FontTable;
@ -39,10 +39,9 @@ use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cast::transmute; use std::cast::transmute;
use std::char; use std::char;
use std::cmp;
use std::libc::{c_uint, c_int, c_void, c_char}; use std::libc::{c_uint, c_int, c_void, c_char};
use std::num;
use std::ptr::null; use std::ptr::null;
use std::ptr;
use std::vec; use std::vec;
static NO_GLYPH: i32 = -1; static NO_GLYPH: i32 = -1;
@ -86,7 +85,7 @@ impl ShapedGlyphData {
assert!(i < self.count); assert!(i < self.count);
unsafe { unsafe {
let glyph_info_i = ptr::offset(self.glyph_infos, i as int); let glyph_info_i = self.glyph_infos.offset(i as int);
(*glyph_info_i).cluster as uint (*glyph_info_i).cluster as uint
} }
} }
@ -100,8 +99,8 @@ impl ShapedGlyphData {
assert!(i < self.count); assert!(i < self.count);
unsafe { unsafe {
let glyph_info_i = ptr::offset(self.glyph_infos, i as int); let glyph_info_i = self.glyph_infos.offset(i as int);
let pos_info_i = ptr::offset(self.pos_infos, i as int); let pos_info_i = self.pos_infos.offset(i as int);
let x_offset = Shaper::fixed_to_float((*pos_info_i).x_offset); let x_offset = Shaper::fixed_to_float((*pos_info_i).x_offset);
let y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset); let y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset);
let x_advance = Shaper::fixed_to_float((*pos_info_i).x_advance); let x_advance = Shaper::fixed_to_float((*pos_info_i).x_advance);
@ -318,7 +317,7 @@ impl Shaper {
let mut max_glyph_idx = glyph_span.end(); let mut max_glyph_idx = glyph_span.end();
for i in char_byte_span.eachi() { for i in char_byte_span.eachi() {
if byteToGlyph[i] > NO_GLYPH { if byteToGlyph[i] > NO_GLYPH {
max_glyph_idx = num::max(byteToGlyph[i] as uint + 1, max_glyph_idx); max_glyph_idx = cmp::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
} }
} }
@ -393,7 +392,7 @@ impl Shaper {
// clamp to end of text. (I don't think this will be necessary, but..) // clamp to end of text. (I don't think this will be necessary, but..)
let end = covered_byte_span.end(); // FIXME: borrow checker workaround let end = covered_byte_span.end(); // FIXME: borrow checker workaround
covered_byte_span.extend_to(num::min(end, byte_max)); covered_byte_span.extend_to(cmp::min(end, byte_max));
// fast path: 1-to-1 mapping of single char and single glyph. // fast path: 1-to-1 mapping of single char and single glyph.
if glyph_span.length() == 1 { if glyph_span.length() == 1 {

View file

@ -2,12 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use extra::arc::Arc;
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics}; use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::vec::VecIterator; use std::vec::Items;
use style::computed_values::text_decoration; use style::computed_values::text_decoration;
use sync::Arc;
use text::glyph::GlyphStore; use text::glyph::GlyphStore;
/// A text run. /// A text run.
@ -22,7 +22,7 @@ pub struct TextRun {
} }
pub struct SliceIterator<'a> { pub struct SliceIterator<'a> {
priv glyph_iter: VecIterator<'a, Arc<GlyphStore>>, priv glyph_iter: Items<'a, Arc<GlyphStore>>,
priv range: Range, priv range: Range,
priv offset: uint, priv offset: uint,
} }

View file

@ -18,7 +18,6 @@ use windowing::{WindowEvent, WindowMethods,
use azure::azure_hl::{SourceSurfaceMethods, Color}; use azure::azure_hl::{SourceSurfaceMethods, Color};
use azure::azure_hl; use azure::azure_hl;
use extra::time::precise_time_s;
use geom::matrix::identity; use geom::matrix::identity;
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
@ -36,19 +35,16 @@ use servo_msg::constellation_msg;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::{profile, ProfilerChan, Timer}; use servo_util::time::{profile, ProfilerChan, Timer};
use servo_util::{time, url}; use servo_util::{time, url};
use std::comm::Port; use std::cmp;
use std::num::Orderable; use std::comm::{Empty, Disconnected, Data, Port};
use std::path::Path; use std::path::Path;
use std::rc::Rc;
use time::precise_time_s;
//FIXME: switch to std::rc when we upgrade Rust
use layers::temp_rc::Rc;
//use std::rc::Rc;
use std::rc;
pub struct IOCompositor { pub struct IOCompositor {
/// The application window. /// The application window.
window: rc::Rc<Window>, window: Rc<Window>,
/// The port on which we receive messages. /// The port on which we receive messages.
port: Port<Msg>, port: Port<Msg>,
@ -120,7 +116,7 @@ impl IOCompositor {
port: Port<Msg>, port: Port<Msg>,
constellation_chan: ConstellationChan, constellation_chan: ConstellationChan,
profiler_chan: ProfilerChan) -> IOCompositor { profiler_chan: ProfilerChan) -> IOCompositor {
let window: rc::Rc<Window> = WindowMethods::new(app); let window: Rc<Window> = WindowMethods::new(app);
// Create an initial layer tree. // Create an initial layer tree.
// //
@ -171,14 +167,17 @@ impl IOCompositor {
fn run (&mut self) { fn run (&mut self) {
// Tell the constellation about the initial window size. // Tell the constellation about the initial window size.
self.constellation_chan.send(ResizedWindowMsg(self.window_size)); {
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ResizedWindowMsg(self.window_size));
}
// Enter the main event loop. // Enter the main event loop.
while !self.done { while !self.done {
// Check for new messages coming from the rendering task. // Check for new messages coming from the rendering task.
self.handle_message(); self.handle_message();
if (self.done) { if self.done {
// We have exited the compositor and passing window // We have exited the compositor and passing window
// messages to script may crash. // messages to script may crash.
debug!("Exiting the compositor due to a request from script."); debug!("Exiting the compositor due to a request from script.");
@ -213,80 +212,89 @@ impl IOCompositor {
// Drain compositor port, sometimes messages contain channels that are blocking // Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds) // another task from finishing (i.e. SetIds)
while self.port.try_recv().is_some() {} loop {
match self.port.try_recv() {
Empty | Disconnected => break,
Data(_) => {},
}
}
// Tell the profiler to shut down. // Tell the profiler to shut down.
self.profiler_chan.send(time::ExitMsg); let ProfilerChan(ref chan) = self.profiler_chan;
chan.send(time::ExitMsg);
} }
fn handle_message(&mut self) { fn handle_message(&mut self) {
loop { loop {
match (self.port.try_recv(), self.shutting_down) { match (self.port.try_recv(), self.shutting_down) {
(None, _) => break, (Empty, _) => break,
(Some(Exit(chan)), _) => { (Disconnected, _) => break,
(Data(Exit(chan)), _) => {
debug!("shutting down the constellation"); debug!("shutting down the constellation");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref con_chan) = self.constellation_chan;
con_chan.send(ExitMsg);
chan.send(()); chan.send(());
self.shutting_down = true; self.shutting_down = true;
} }
(Some(ShutdownComplete), _) => { (Data(ShutdownComplete), _) => {
debug!("constellation completed shutdown"); debug!("constellation completed shutdown");
self.done = true; self.done = true;
} }
(Some(ChangeReadyState(ready_state)), false) => { (Data(ChangeReadyState(ready_state)), false) => {
self.window.borrow().set_ready_state(ready_state); self.window.borrow().set_ready_state(ready_state);
self.ready_state = ready_state; self.ready_state = ready_state;
} }
(Some(ChangeRenderState(render_state)), false) => { (Data(ChangeRenderState(render_state)), false) => {
self.change_render_state(render_state); self.change_render_state(render_state);
} }
(Some(SetUnRenderedColor(_id, color)), false) => { (Data(SetUnRenderedColor(_id, color)), false) => {
self.set_unrendered_color(_id, color); self.set_unrendered_color(_id, color);
} }
(Some(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => { (Data(SetIds(frame_tree, response_chan, new_constellation_chan)), _) => {
self.set_ids(frame_tree, response_chan, new_constellation_chan); self.set_ids(frame_tree, response_chan, new_constellation_chan);
} }
(Some(GetGraphicsMetadata(chan)), false) => { (Data(GetGraphicsMetadata(chan)), false) => {
chan.send(Some(azure_hl::current_graphics_metadata())); chan.send(Some(azure_hl::current_graphics_metadata()));
} }
(Some(NewLayer(_id, new_size)), false) => { (Data(NewLayer(_id, new_size)), false) => {
self.create_new_layer(_id, new_size); self.create_new_layer(_id, new_size);
} }
(Some(SetLayerPageSize(id, new_size, epoch)), false) => { (Data(SetLayerPageSize(id, new_size, epoch)), false) => {
self.set_layer_page_size(id, new_size, epoch); self.set_layer_page_size(id, new_size, epoch);
} }
(Some(SetLayerClipRect(id, new_rect)), false) => { (Data(SetLayerClipRect(id, new_rect)), false) => {
self.set_layer_clip_rect(id, new_rect); self.set_layer_clip_rect(id, new_rect);
} }
(Some(DeleteLayer(id)), _) => { (Data(DeleteLayer(id)), _) => {
self.delete_layer(id); self.delete_layer(id);
} }
(Some(Paint(id, new_layer_buffer_set, epoch)), false) => { (Data(Paint(id, new_layer_buffer_set, epoch)), false) => {
self.paint(id, new_layer_buffer_set, epoch); self.paint(id, new_layer_buffer_set, epoch);
} }
(Some(InvalidateRect(id, rect)), false) => { (Data(InvalidateRect(id, rect)), false) => {
self.invalidate_rect(id, rect); self.invalidate_rect(id, rect);
} }
(Some(ScrollFragmentPoint(id, point)), false) => { (Data(ScrollFragmentPoint(id, point)), false) => {
self.scroll_fragment_to_point(id, point); self.scroll_fragment_to_point(id, point);
} }
(Some(LoadComplete(..)), false) => { (Data(LoadComplete(..)), false) => {
self.load_complete = true; self.load_complete = true;
} }
@ -350,7 +358,10 @@ impl IOCompositor {
let window_size = self.window.borrow().size(); let window_size = self.window.borrow().size();
let window_size = Size2D(window_size.width as uint, let window_size = Size2D(window_size.width as uint,
window_size.height as uint); window_size.height as uint);
new_constellation_chan.send(ResizedWindowMsg(window_size)); {
let ConstellationChan(ref chan) = new_constellation_chan;
chan.send(ResizedWindowMsg(window_size));
}
self.constellation_chan = new_constellation_chan; self.constellation_chan = new_constellation_chan;
} }
@ -397,7 +408,7 @@ impl IOCompositor {
let page_window = Size2D(window_size.width as f32 / world_zoom, let page_window = Size2D(window_size.width as f32 / world_zoom,
window_size.height as f32 / world_zoom); window_size.height as f32 / world_zoom);
layer.resize(id, new_size, page_window, epoch); layer.resize(id, new_size, page_window, epoch);
let move = self.fragment_point.take().map_default(false, |point| layer.move(point, page_window)); let move = self.fragment_point.take().map_or(false, |point| layer.move(point, page_window));
(true, move) (true, move)
} }
@ -551,14 +562,16 @@ impl IOCompositor {
let exit = self.opts.exit_after_load; let exit = self.opts.exit_after_load;
if exit { if exit {
debug!("shutting down the constellation for FinishedWindowEvent"); debug!("shutting down the constellation for FinishedWindowEvent");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
} }
QuitWindowEvent => { QuitWindowEvent => {
debug!("shutting down the constellation for QuitWindowEvent"); debug!("shutting down the constellation for QuitWindowEvent");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
} }
@ -569,7 +582,8 @@ impl IOCompositor {
if self.window_size != new_size { if self.window_size != new_size {
debug!("osmain: window resized to {:u}x{:u}", width, height); debug!("osmain: window resized to {:u}x{:u}", width, height);
self.window_size = new_size; self.window_size = new_size;
self.constellation_chan.send(ResizedWindowMsg(new_size)) let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ResizedWindowMsg(new_size))
} else { } else {
debug!("osmain: dropping window resize since size is still {:u}x{:u}", width, height); debug!("osmain: dropping window resize since size is still {:u}x{:u}", width, height);
} }
@ -584,7 +598,8 @@ impl IOCompositor {
}; };
let msg = LoadUrlMsg(root_pipeline_id, url::parse_url(url_string, None)); let msg = LoadUrlMsg(root_pipeline_id, url::parse_url(url_string, None));
self.constellation_chan.send(msg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(msg);
} }
fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) { fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) {
@ -628,7 +643,7 @@ impl IOCompositor {
let window_size = &self.window_size; let window_size = &self.window_size;
// Determine zoom amount // Determine zoom amount
self.world_zoom = (self.world_zoom * magnification).max(&1.0); self.world_zoom = cmp::max(self.world_zoom * magnification, 1.0);
let world_zoom = self.world_zoom; let world_zoom = self.world_zoom;
self.root_layer.borrow().common.with_mut(|common| common.set_transform(identity().scale(world_zoom, world_zoom, 1f32))); self.root_layer.borrow().common.with_mut(|common| common.set_transform(identity().scale(world_zoom, world_zoom, 1f32)));
@ -652,7 +667,8 @@ impl IOCompositor {
windowing::Forward => constellation_msg::Forward, windowing::Forward => constellation_msg::Forward,
windowing::Back => constellation_msg::Back, windowing::Back => constellation_msg::Back,
}; };
self.constellation_chan.send(NavigateMsg(direction)) let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(NavigateMsg(direction))
} }
/// Get BufferRequests from each layer. /// Get BufferRequests from each layer.
@ -721,7 +737,8 @@ impl IOCompositor {
assert!(res.is_ok()); assert!(res.is_ok());
debug!("shutting down the constellation after generating an output file"); debug!("shutting down the constellation after generating an output file");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
self.shutting_down = true; self.shutting_down = true;
} }
@ -730,7 +747,8 @@ impl IOCompositor {
let exit = self.opts.exit_after_load; let exit = self.opts.exit_after_load;
if exit { if exit {
debug!("shutting down the constellation for exit_after_load"); debug!("shutting down the constellation for exit_after_load");
self.constellation_chan.send(ExitMsg); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ExitMsg);
} }
} }

View file

@ -19,12 +19,11 @@ use layers::texturegl::{Texture, TextureTarget};
#[cfg(target_os="macos")] use layers::texturegl::TextureTargetRectangle; #[cfg(target_os="macos")] use layers::texturegl::TextureTargetRectangle;
use pipeline::CompositionPipeline; use pipeline::CompositionPipeline;
use script::dom::event::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; use script::dom::event::{ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
use script::script_task::SendEventMsg; use script::script_task::{ScriptChan, SendEventMsg};
use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch, Tile}; use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch, Tile};
use servo_msg::constellation_msg::PipelineId; use servo_msg::constellation_msg::PipelineId;
//FIXME: switch to std::rc when we upgrade Rust use std::cmp;
use layers::temp_rc::Rc; use std::rc::Rc;
//use std::rc::Rc;
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent}; use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
use windowing::{MouseWindowMouseUpEvent}; use windowing::{MouseWindowMouseUpEvent};
use azure::azure_hl::Color; use azure::azure_hl::Color;
@ -105,6 +104,25 @@ enum ScrollBehavior {
FixedPosition, FixedPosition,
} }
trait Clampable {
fn clamp(&self, mn: &Self, mx: &Self) -> Self;
}
impl Clampable for f32 {
/// Returns the number constrained within the range `mn <= self <= mx`.
/// If any of the numbers are `NAN` then `NAN` is returned.
#[inline]
fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
match () {
_ if self.is_nan() => *self,
_ if !(*self <= *mx) => *mx,
_ if !(*self >= *mn) => *mn,
_ => *self,
}
}
}
impl CompositorLayer { impl CompositorLayer {
/// Creates a new CompositorLayer with an optional page size. If no page size is given, /// Creates a new CompositorLayer with an optional page size. If no page size is given,
/// the layer is initially hidden and initialized without a quadtree. /// the layer is initially hidden and initialized without a quadtree.
@ -207,9 +225,9 @@ impl CompositorLayer {
Some(size) => size, Some(size) => size,
None => fail!("CompositorLayer: tried to scroll with no page size set"), None => fail!("CompositorLayer: tried to scroll with no page size set"),
}; };
let min_x = (window_size.width - page_size.width).min(&0.0); let min_x = cmp::min(window_size.width - page_size.width, 0.0);
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0); self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
let min_y = (window_size.height - page_size.height).min(&0.0); let min_y = cmp::min(window_size.height - page_size.height, 0.0);
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0); self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
// check to see if we scrolled // check to see if we scrolled
@ -253,13 +271,15 @@ impl CompositorLayer {
MouseWindowClickEvent(button, _) => ClickEvent(button, cursor), MouseWindowClickEvent(button, _) => ClickEvent(button, cursor),
MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor), MouseWindowMouseDownEvent(button, _) => MouseDownEvent(button, cursor),
MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor), MouseWindowMouseUpEvent(button, _) => MouseUpEvent(button, cursor),
}; };
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message)); let ScriptChan(ref chan) = self.pipeline.script_chan;
chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
} }
pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) { pub fn send_mouse_move_event(&self, cursor: Point2D<f32>) {
let message = MouseMoveEvent(cursor); let message = MouseMoveEvent(cursor);
self.pipeline.script_chan.try_send(SendEventMsg(self.pipeline.id.clone(), message)); let ScriptChan(ref chan) = self.pipeline.script_chan;
chan.try_send(SendEventMsg(self.pipeline.id.clone(), message));
} }
// Given the current window size, determine which tiles need to be (re)rendered // Given the current window size, determine which tiles need to be (re)rendered
@ -410,9 +430,9 @@ impl CompositorLayer {
Some(size) => size, Some(size) => size,
None => fail!("CompositorLayer: tried to scroll with no page size set"), None => fail!("CompositorLayer: tried to scroll with no page size set"),
}; };
let min_x = (window_size.width - page_size.width).min(&0.0); let min_x = cmp::min(window_size.width - page_size.width, 0.0);
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0); self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
let min_y = (window_size.height - page_size.height).min(&0.0); let min_y = cmp::min(window_size.height - page_size.height, 0.0);
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0); self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
// check to see if we scrolled // check to see if we scrolled
@ -674,7 +694,7 @@ impl CompositorLayer {
NoTree(..) => {} // Nothing to do NoTree(..) => {} // Nothing to do
Tree(ref mut quadtree) => { Tree(ref mut quadtree) => {
// NOTE: work around borrowchk // NOTE: work around borrowchk
let tmp = child.container.borrow().scissor.borrow(); let tmp = child.get_ref().container.borrow().scissor.borrow();
match *tmp.get() { match *tmp.get() {
Some(rect) => { Some(rect) => {
quadtree.set_status_page(rect, Normal, false); // Unhide this rect quadtree.set_status_page(rect, Normal, false); // Unhide this rect
@ -685,7 +705,7 @@ impl CompositorLayer {
} }
// Send back all tiles to renderer. // Send back all tiles to renderer.
child.child.clear(); child.get_mut_ref().child.clear();
self.build_layer_tree(graphics_context); self.build_layer_tree(graphics_context);
true true

View file

@ -14,12 +14,11 @@ use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata}; use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
use servo_msg::compositor_msg::{Epoch, RenderListener, LayerBufferSet, RenderState, ReadyState}; use servo_msg::compositor_msg::{Epoch, RenderListener, LayerBufferSet, RenderState, ReadyState};
use servo_msg::compositor_msg::{ScriptListener, Tile}; use servo_msg::compositor_msg::ScriptListener;
use servo_msg::constellation_msg::{ConstellationChan, PipelineId}; use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::comm::{Chan, SharedChan, Port}; use std::comm::{Chan, Port};
use std::num::Orderable;
use extra::url::Url; use extra::url::Url;
@ -36,7 +35,7 @@ mod headless;
#[deriving(Clone)] #[deriving(Clone)]
pub struct CompositorChan { pub struct CompositorChan {
/// A channel on which messages can be sent to the compositor. /// A channel on which messages can be sent to the compositor.
chan: SharedChan<Msg>, chan: Chan<Msg>,
} }
/// Implementation of the abstract `ScriptListener` interface. /// Implementation of the abstract `ScriptListener` interface.
@ -106,7 +105,7 @@ impl RenderListener for CompositorChan {
impl CompositorChan { impl CompositorChan {
pub fn new() -> (Port<Msg>, CompositorChan) { pub fn new() -> (Port<Msg>, CompositorChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let compositor_chan = CompositorChan { let compositor_chan = CompositorChan {
chan: chan, chan: chan,
}; };

View file

@ -6,7 +6,7 @@ use compositing::*;
use geom::size::Size2D; use geom::size::Size2D;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
use std::comm::Port; use std::comm::{Empty, Disconnected, Data, Port};
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use servo_util::time; use servo_util::time;
@ -32,12 +32,20 @@ impl NullCompositor {
let compositor = NullCompositor::new(port); let compositor = NullCompositor::new(port);
// Tell the constellation about the initial fake size. // Tell the constellation about the initial fake size.
constellation_chan.send(ResizedWindowMsg(Size2D(640u, 480u))); {
let ConstellationChan(ref chan) = constellation_chan;
chan.send(ResizedWindowMsg(Size2D(640u, 480u)));
}
compositor.handle_message(constellation_chan); compositor.handle_message(constellation_chan);
// Drain compositor port, sometimes messages contain channels that are blocking // Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds) // another task from finishing (i.e. SetIds)
while compositor.port.try_recv().is_some() {} loop {
match compositor.port.try_recv() {
Empty | Disconnected => break,
Data(_) => {},
}
}
profiler_chan.send(time::ExitMsg); profiler_chan.send(time::ExitMsg);
} }
@ -47,7 +55,8 @@ impl NullCompositor {
match self.port.recv() { match self.port.recv() {
Exit(chan) => { Exit(chan) => {
debug!("shutting down the constellation"); debug!("shutting down the constellation");
constellation_chan.send(ExitMsg); let ConstellationChan(ref con_chan) = constellation_chan;
con_chan.send(ExitMsg);
chan.send(()); chan.send(());
} }

View file

@ -9,9 +9,10 @@ use geom::point::Point2D;
use geom::size::Size2D; use geom::size::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
use gfx::render_task::BufferRequest; use gfx::render_task::BufferRequest;
use std::uint::{div_ceil, next_power_of_two}; use std::cmp;
use std::num::next_power_of_two;
use std::vec; use std::vec;
use std::util::replace; use std::mem::replace;
use std::vec::build; use std::vec::build;
use servo_msg::compositor_msg::Tile; use servo_msg::compositor_msg::Tile;
@ -72,6 +73,12 @@ enum Quadrant {
BR = 3, BR = 3,
} }
fn div_ceil(x: uint, y: uint) -> uint {
let div = x / y;
if x % y == 0u { div }
else { div + 1u }
}
impl<T: Tile> Quadtree<T> { impl<T: Tile> Quadtree<T> {
/// Public method to create a new Quadtree /// Public method to create a new Quadtree
/// Takes in the initial width and height of the space, a maximum tile size, and /// Takes in the initial width and height of the space, a maximum tile size, and
@ -79,7 +86,7 @@ impl<T: Tile> Quadtree<T> {
/// Set max_mem to None to turn off automatic tile removal. /// Set max_mem to None to turn off automatic tile removal.
pub fn new(clip_size: Size2D<uint>, tile_size: uint, max_mem: Option<uint>) -> Quadtree<T> { pub fn new(clip_size: Size2D<uint>, tile_size: uint, max_mem: Option<uint>) -> Quadtree<T> {
// Spaces must be squares and powers of 2, so expand the space until it is // Spaces must be squares and powers of 2, so expand the space until it is
let longer = clip_size.width.max(&clip_size.height); let longer = cmp::max(clip_size.width, clip_size.height);
let num_tiles = div_ceil(longer, tile_size); let num_tiles = div_ceil(longer, tile_size);
let power_of_two = next_power_of_two(num_tiles); let power_of_two = next_power_of_two(num_tiles);
let size = power_of_two * tile_size; let size = power_of_two * tile_size;
@ -153,7 +160,7 @@ impl<T: Tile> Quadtree<T> {
/// Creates a new quadtree at the specified size. This should be called when the window changes size. /// Creates a new quadtree at the specified size. This should be called when the window changes size.
pub fn resize(&mut self, width: uint, height: uint) -> ~[T] { pub fn resize(&mut self, width: uint, height: uint) -> ~[T] {
// Spaces must be squares and powers of 2, so expand the space until it is // Spaces must be squares and powers of 2, so expand the space until it is
let longer = width.max(&height); let longer = cmp::max(width, height);
let num_tiles = div_ceil(longer, self.max_tile_size); let num_tiles = div_ceil(longer, self.max_tile_size);
let power_of_two = next_power_of_two(num_tiles); let power_of_two = next_power_of_two(num_tiles);
let size = power_of_two * self.max_tile_size; let size = power_of_two * self.max_tile_size;
@ -176,7 +183,7 @@ impl<T: Tile> Quadtree<T> {
#[cfg(test)] #[cfg(test)]
pub fn bad_resize(&mut self, width: uint, height: uint) { pub fn bad_resize(&mut self, width: uint, height: uint) {
self.clip_size = Size2D(width, height); self.clip_size = Size2D(width, height);
let longer = width.max(&height); let longer = cmp::max(width, height);
let new_num_tiles = div_ceil(longer, self.max_tile_size); let new_num_tiles = div_ceil(longer, self.max_tile_size);
let new_size = next_power_of_two(new_num_tiles); let new_size = next_power_of_two(new_num_tiles);
// difference here indicates the number of times the underlying size of the quadtree needs // difference here indicates the number of times the underlying size of the quadtree needs
@ -348,8 +355,8 @@ impl<T: Tile> QuadtreeNode<T> {
if self.size <= tile_size { if self.size <= tile_size {
let pix_x = (self.origin.x * scale).ceil() as uint; let pix_x = (self.origin.x * scale).ceil() as uint;
let pix_y = (self.origin.y * scale).ceil() as uint; let pix_y = (self.origin.y * scale).ceil() as uint;
let page_width = (clip_x - self.origin.x).min(&self.size); let page_width = cmp::min(clip_x - self.origin.x, self.size);
let page_height = (clip_y - self.origin.y).min(&self.size); let page_height = cmp::min(clip_y - self.origin.y, self.size);
let pix_width = (page_width * scale).ceil() as uint; let pix_width = (page_width * scale).ceil() as uint;
let pix_height = (page_height * scale).ceil() as uint; let pix_height = (page_height * scale).ceil() as uint;
self.status = Rendering; self.status = Rendering;
@ -472,8 +479,8 @@ impl<T: Tile> QuadtreeNode<T> {
} }
// clip window to visible region // clip window to visible region
let w_width = (clip.width - w_x).min(&w_width); let w_width = cmp::min(clip.width - w_x, w_width);
let w_height = (clip.height - w_y).min(&w_height); let w_height = cmp::min(clip.height - w_y, w_height);
if s_size <= tile_size { // We are the child if s_size <= tile_size { // We are the child
return match self.tile { return match self.tile {
@ -545,20 +552,20 @@ impl<T: Tile> QuadtreeNode<T> {
// Recurse into child // Recurse into child
let new_window = match *quad { let new_window = match *quad {
TL => Rect(window.origin, TL => Rect(window.origin,
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)), Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
w_height.min(&(s_y + s_size / 2.0 - w_y)))), cmp::min(w_height, (s_y + s_size / 2.0 - w_y)))),
TR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)), TR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
w_y), w_y),
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))), Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
w_height.min(&(s_y + s_size / 2.0 - w_y)))), cmp::min(w_height, s_y + s_size / 2.0 - w_y))),
BL => Rect(Point2D(w_x, BL => Rect(Point2D(w_x,
w_y.max(&(s_y + s_size / 2.0))), cmp::max(w_y, s_y + s_size / 2.0)),
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)), Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))), cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
BR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)), BR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
w_y.max(&(s_y + s_size / 2.0))), cmp::max(w_y, s_y + s_size / 2.0)),
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))), Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))), cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
}; };

View file

@ -4,6 +4,7 @@
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete}; use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
use collections::hashmap::{HashMap, HashSet};
use extra::url::Url; use extra::url::Url;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -11,6 +12,8 @@ use gfx::render_task;
use pipeline::{Pipeline, CompositionPipeline}; use pipeline::{Pipeline, CompositionPipeline};
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg}; use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg};
use script::layout_interface; use script::layout_interface;
use script::layout_interface::LayoutChan;
use script::script_task::ScriptChan;
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg}; use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, Failure, FrameRectMsg};
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg}; use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg}; use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
@ -25,13 +28,10 @@ use servo_util::time::ProfilerChan;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
use std::cell::RefCell; use std::cell::RefCell;
use std::hashmap::{HashMap, HashSet}; use std::mem::replace;
//FIXME: switch to std::rc when we upgrade Rust
use layers::temp_rc::Rc;
//use std::rc::Rc;
use std::util::replace;
use std::io; use std::io;
use std::libc; use std::libc;
use std::rc::Rc;
/// Maintains the pipelines and navigation context and grants permission to composite /// Maintains the pipelines and navigation context and grants permission to composite
pub struct Constellation { pub struct Constellation {
@ -199,12 +199,12 @@ impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
let next = self.stack.pop(); let next = self.stack.pop();
{ {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = next.borrow().children.borrow(); let tmp = next.get_ref().borrow().children.borrow();
for cft in tmp.get().rev_iter() { for cft in tmp.get().rev_iter() {
self.stack.push(cft.frame_tree.clone()); self.stack.push(cft.frame_tree.clone());
} }
} }
Some(next) Some(next.unwrap())
} else { } else {
None None
} }
@ -239,14 +239,14 @@ impl NavigationContext {
pub fn back(&mut self) -> Rc<FrameTree> { pub fn back(&mut self) -> Rc<FrameTree> {
self.next.push(self.current.take_unwrap()); self.next.push(self.current.take_unwrap());
let prev = self.previous.pop(); let prev = self.previous.pop().unwrap();
self.current = Some(prev.clone()); self.current = Some(prev.clone());
prev prev
} }
pub fn forward(&mut self) -> Rc<FrameTree> { pub fn forward(&mut self) -> Rc<FrameTree> {
self.previous.push(self.current.take_unwrap()); self.previous.push(self.current.take_unwrap());
let next = self.next.pop(); let next = self.next.pop().unwrap();
self.current = Some(next.clone()); self.current = Some(next.clone());
next next
} }
@ -335,7 +335,8 @@ impl Constellation {
/// Helper function for getting a unique pipeline Id /// Helper function for getting a unique pipeline Id
fn get_next_pipeline_id(&mut self) -> PipelineId { fn get_next_pipeline_id(&mut self) -> PipelineId {
let id = self.next_pipeline_id; let id = self.next_pipeline_id;
*self.next_pipeline_id += 1; let PipelineId(ref mut i) = self.next_pipeline_id;
*i += 1;
id id
} }
@ -427,8 +428,8 @@ impl Constellation {
// It's quite difficult to make Servo exit cleanly if some tasks have failed. // It's quite difficult to make Servo exit cleanly if some tasks have failed.
// Hard fail exists for test runners so we crash and that's good enough. // Hard fail exists for test runners so we crash and that's good enough.
let mut stderr = io::stderr(); let mut stderr = io::stderr();
stderr.write_str("Pipeline failed in hard-fail mode. Crashing!\n"); stderr.write_str("Pipeline failed in hard-fail mode. Crashing!\n").unwrap();
stderr.flush(); stderr.flush().unwrap();
unsafe { libc::exit(1); } unsafe { libc::exit(1); }
} }
@ -437,9 +438,11 @@ impl Constellation {
Some(id) => id.clone() Some(id) => id.clone()
}; };
old_pipeline.borrow().script_chan.try_send(ExitPipelineMsg(pipeline_id)); let ScriptChan(ref old_script) = old_pipeline.borrow().script_chan;
old_pipeline.borrow().render_chan.try_send(render_task::ExitMsg(None)); old_script.try_send(ExitPipelineMsg(pipeline_id));
old_pipeline.borrow().layout_chan.try_send(layout_interface::ExitNowMsg); old_pipeline.borrow().render_chan.chan.try_send(render_task::ExitMsg(None));
let LayoutChan(ref old_layout) = old_pipeline.borrow().layout_chan;
old_layout.try_send(layout_interface::ExitNowMsg);
self.pipelines.remove(&pipeline_id); self.pipelines.remove(&pipeline_id);
let new_id = self.get_next_pipeline_id(); let new_id = self.get_next_pipeline_id();
@ -508,51 +511,56 @@ impl Constellation {
== subpage_id == subpage_id
}; };
// Update a child's frame rect and inform its script task of the change, {
// if it hasn't been already. Optionally inform the compositor if // Update a child's frame rect and inform its script task of the change,
// resize happens immediately. // if it hasn't been already. Optionally inform the compositor if
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| { // resize happens immediately.
child_frame_tree.rect = Some(rect.clone()); let compositor_chan = self.compositor_chan.clone();
// NOTE: work around borrowchk issues let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow(); child_frame_tree.rect = Some(rect.clone());
if !already_sent.contains(&pipeline.get().borrow().id) {
let Size2D { width, height } = rect.size;
if is_active {
let pipeline = pipeline.get().borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, Size2D {
width: width as uint,
height: height as uint
}));
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
} else {
let pipeline = pipeline.get().borrow();
pipeline.script_chan.send(ResizeInactiveMsg(pipeline.id,
Size2D(width as uint, height as uint)));
}
let pipeline = pipeline.get().borrow();
already_sent.insert(pipeline.id);
}
};
// If the subframe is in the current frame tree, the compositor needs the new size
for current_frame in self.current_frame().iter() {
debug!("Constellation: Sending size for frame in current frame tree.");
let source_frame = current_frame.borrow().find(pipeline_id);
for source_frame in source_frame.iter() {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let mut tmp = source_frame.borrow().children.borrow_mut(); let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child)); if !already_sent.contains(&pipeline.get().borrow().id) {
found_child.map(|child| update_child_rect(child, true)); let Size2D { width, height } = rect.size;
} if is_active {
} let pipeline = pipeline.get().borrow();
let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeMsg(pipeline.id, Size2D {
width: width as uint,
height: height as uint
}));
compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
} else {
let pipeline = pipeline.get().borrow();
let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeInactiveMsg(pipeline.id,
Size2D(width as uint, height as uint)));
}
let pipeline = pipeline.get().borrow();
already_sent.insert(pipeline.id);
}
};
// Update all frames with matching pipeline- and subpage-ids // If the subframe is in the current frame tree, the compositor needs the new size
let frames = self.find_all(pipeline_id); for current_frame in self.current_frame().iter() {
for frame_tree in frames.iter() { debug!("Constellation: Sending size for frame in current frame tree.");
// NOTE: work around borrowchk issues let source_frame = current_frame.borrow().find(pipeline_id);
let mut tmp = frame_tree.borrow().children.borrow_mut(); for source_frame in source_frame.iter() {
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child)); // NOTE: work around borrowchk issues
found_child.map(|child| update_child_rect(child, false)); let mut tmp = source_frame.borrow().children.borrow_mut();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
found_child.map(|child| update_child_rect(child, true));
}
}
// Update all frames with matching pipeline- and subpage-ids
let frames = self.find_all(pipeline_id);
for frame_tree in frames.iter() {
// NOTE: work around borrowchk issues
let mut tmp = frame_tree.borrow().children.borrow_mut();
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
found_child.map(|child| update_child_rect(child, false));
}
} }
// At this point, if no pipelines were sent a resize msg, then this subpage id // At this point, if no pipelines were sent a resize msg, then this subpage id
@ -871,7 +879,8 @@ impl Constellation {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = frame_tree.borrow().pipeline.borrow(); let tmp = frame_tree.borrow().pipeline.borrow();
let pipeline = tmp.get().borrow(); let pipeline = tmp.get().borrow();
pipeline.script_chan.try_send(ResizeMsg(pipeline.id, new_size)); let ScriptChan(ref chan) = pipeline.script_chan;
chan.try_send(ResizeMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
for frame_tree in self.navigation_context.previous.iter() for frame_tree in self.navigation_context.previous.iter()
@ -881,7 +890,8 @@ impl Constellation {
let pipeline = &tmp.get().borrow(); let pipeline = &tmp.get().borrow();
if !already_seen.contains(&pipeline.id) { if !already_seen.contains(&pipeline.id) {
debug!("constellation sending resize message to inactive frame"); debug!("constellation sending resize message to inactive frame");
pipeline.script_chan.try_send(ResizeInactiveMsg(pipeline.id, new_size)); let ScriptChan(ref chan) = pipeline.script_chan;
chan.try_send(ResizeInactiveMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id); already_seen.insert(pipeline.id);
} }
} }
@ -897,7 +907,8 @@ impl Constellation {
// NOTE: work around borrowchk issues // NOTE: work around borrowchk issues
let tmp = frame_tree.pipeline.borrow(); let tmp = frame_tree.pipeline.borrow();
let pipeline = tmp.get().borrow(); let pipeline = tmp.get().borrow();
pipeline.script_chan.send(ResizeMsg(pipeline.id, new_size)) let ScriptChan(ref chan) = pipeline.script_chan;
chan.send(ResizeMsg(pipeline.id, new_size))
} }
} }

View file

@ -11,16 +11,16 @@ use layout::extra::LayoutAuxMethods;
use layout::util::{LayoutDataAccess, LayoutDataWrapper}; use layout::util::{LayoutDataAccess, LayoutDataWrapper};
use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode};
use extra::arc::Arc;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
use servo_util::namespace::Null; use servo_util::namespace::Null;
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16}; use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16};
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::cast; use std::cast;
use std::to_bytes; use std::hash::{Hash, sip};
use std::vec::VecIterator; use std::vec::Items;
use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade}; use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade};
use sync::Arc;
pub struct ApplicableDeclarations { pub struct ApplicableDeclarations {
normal: SmallVec16<MatchedProperty>, normal: SmallVec16<MatchedProperty>,
@ -73,9 +73,10 @@ impl Eq for ApplicableDeclarationsCacheEntry {
} }
} }
impl IterBytes for ApplicableDeclarationsCacheEntry { impl Hash for ApplicableDeclarationsCacheEntry {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { fn hash(&self, state: &mut sip::SipState) {
ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()).iter_bytes(lsb0, f) let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
tmp.hash(state);
} }
} }
@ -115,16 +116,15 @@ impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCache
} }
} }
impl<'a> IterBytes for ApplicableDeclarationsCacheQuery<'a> {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
let mut result = true; fn hash(&self, state: &mut sip::SipState) {
for declaration in self.declarations.iter() { for declaration in self.declarations.iter() {
let ptr: uint = unsafe { let ptr: uint = unsafe {
cast::transmute_copy(declaration) cast::transmute_copy(declaration)
}; };
result = ptr.iter_bytes(lsb0, |x| f(x)); ptr.hash(state);
} }
result
} }
} }
@ -160,13 +160,13 @@ pub struct StyleSharingCandidateCache {
#[deriving(Clone)] #[deriving(Clone)]
struct StyleSharingCandidate { struct StyleSharingCandidate {
priv style: Arc<ComputedValues>, style: Arc<ComputedValues>,
priv parent_style: Arc<ComputedValues>, parent_style: Arc<ComputedValues>,
// TODO(pcwalton): Intern. // TODO(pcwalton): Intern.
priv local_name: DOMString, local_name: DOMString,
priv class: Option<DOMString>, class: Option<DOMString>,
} }
impl Eq for StyleSharingCandidate { impl Eq for StyleSharingCandidate {
@ -255,7 +255,7 @@ impl StyleSharingCandidateCache {
} }
} }
pub fn iter<'a>(&'a self) -> VecIterator<'a,(StyleSharingCandidate,())> { pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> {
self.cache.iter() self.cache.iter()
} }

View file

@ -8,8 +8,8 @@ use css::node_util::NodeUtil;
use layout::incremental::RestyleDamage; use layout::incremental::RestyleDamage;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use extra::arc::Arc;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
/// Node mixin providing `style` method that returns a `NodeStyle` /// Node mixin providing `style` method that returns a `NodeStyle`
pub trait StyledNode { pub trait StyledNode {

View file

@ -6,9 +6,9 @@ use layout::incremental::RestyleDamage;
use layout::util::LayoutDataAccess; use layout::util::LayoutDataAccess;
use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode};
use extra::arc::Arc;
use std::cast; use std::cast;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
pub trait NodeUtil { pub trait NodeUtil {
fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>; fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>;

View file

@ -119,7 +119,7 @@ impl HeightConstraintSolution {
(Specified(top), Specified(bottom), Specified(height)) => { (Specified(top), Specified(bottom), Specified(height)) => {
match (top_margin, bottom_margin) { match (top_margin, bottom_margin) {
(Auto, Auto) => { (Auto, Auto) => {
let total_margin_val = (available_height - top - bottom - height); let total_margin_val = available_height - top - bottom - height;
(top, bottom, height, (top, bottom, height,
total_margin_val.scale_by(0.5), total_margin_val.scale_by(0.5),
total_margin_val.scale_by(0.5)) total_margin_val.scale_by(0.5))
@ -226,7 +226,7 @@ impl HeightConstraintSolution {
(Specified(top), Specified(bottom)) => { (Specified(top), Specified(bottom)) => {
match (top_margin, bottom_margin) { match (top_margin, bottom_margin) {
(Auto, Auto) => { (Auto, Auto) => {
let total_margin_val = (available_height - top - bottom - height); let total_margin_val = available_height - top - bottom - height;
(top, bottom, height, (top, bottom, height,
total_margin_val.scale_by(0.5), total_margin_val.scale_by(0.5),
total_margin_val.scale_by(0.5)) total_margin_val.scale_by(0.5))
@ -291,7 +291,9 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignHeightsTraversal<'a> {
return true; return true;
} }
block_flow.calculate_abs_height_and_margins(**self);
let AbsoluteAssignHeightsTraversal(ref ctx) = *self;
block_flow.calculate_abs_height_and_margins(*ctx);
true true
} }
} }
@ -1731,7 +1733,7 @@ trait WidthAndMarginsComputer {
let left = left_margin.specified_or_zero(); let left = left_margin.specified_or_zero();
let right = right_margin.specified_or_zero(); let right = right_margin.specified_or_zero();
if((left + right + width) > available_width) { if (left + right + width) > available_width {
(Specified(left), Specified(right)) (Specified(left), Specified(right))
} else { } else {
(left_margin, right_margin) (left_margin, right_margin)
@ -1838,7 +1840,7 @@ impl WidthAndMarginsComputer for AbsoluteNonReplaced {
(Specified(left), Specified(right), Specified(width)) => { (Specified(left), Specified(right), Specified(width)) => {
match (left_margin, right_margin) { match (left_margin, right_margin) {
(Auto, Auto) => { (Auto, Auto) => {
let total_margin_val = (available_width - left - right - width); let total_margin_val = available_width - left - right - width;
if total_margin_val < Au(0) { if total_margin_val < Au(0) {
// margin-left becomes 0 because direction is 'ltr'. // margin-left becomes 0 because direction is 'ltr'.
// TODO: Handle 'rtl' when it is implemented. // TODO: Handle 'rtl' when it is implemented.
@ -2001,7 +2003,7 @@ impl WidthAndMarginsComputer for AbsoluteReplaced {
(Specified(left), Specified(right)) => { (Specified(left), Specified(right)) => {
match (left_margin, right_margin) { match (left_margin, right_margin) {
(Auto, Auto) => { (Auto, Auto) => {
let total_margin_val = (available_width - left - right - width); let total_margin_val = available_width - left - right - width;
if total_margin_val < Au(0) { if total_margin_val < Au(0) {
// margin-left becomes 0 because direction is 'ltr'. // margin-left becomes 0 because direction is 'ltr'.
(left, right, width, Au(0), total_margin_val) (left, right, width, Au(0), total_margin_val)

View file

@ -5,8 +5,9 @@
//! The `Box` type, which represents the leaves of the layout tree. //! The `Box` type, which represents the leaves of the layout tree.
use extra::url::Url; use extra::url::Url;
use extra::arc::{MutexArc, Arc}; use sync::{MutexArc, Arc};
use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use geom::{Point2D, Rect, Size2D, SideOffsets2D};
use geom::approxeq::ApproxEq;
use gfx::color::rgb; use gfx::color::rgb;
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
use gfx::display_list::{LineDisplayItem, LineDisplayItemClass}; use gfx::display_list::{LineDisplayItem, LineDisplayItemClass};
@ -16,7 +17,7 @@ use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayI
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection}; use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
use gfx::font::FontStyle; use gfx::font::FontStyle;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId}; use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg, PipelineId, SubpageId};
use servo_net::image::holder::ImageHolder; use servo_net::image::holder::ImageHolder;
use servo_net::local_image_cache::LocalImageCache; use servo_net::local_image_cache::LocalImageCache;
use servo_util::geometry::Au; use servo_util::geometry::Au;
@ -27,7 +28,6 @@ use servo_util::str::is_whitespace;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::cmp::ApproxEq;
use std::num::Zero; use std::num::Zero;
use style::{ComputedValues, TElement, TNode}; use style::{ComputedValues, TElement, TNode};
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto, overflow, LPA_Auto}; use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto, overflow, LPA_Auto};
@ -1327,7 +1327,7 @@ impl Box {
UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"),
ScannedTextBox(ref text_box_info) => { ScannedTextBox(ref text_box_info) => {
let mut new_line_pos = self.new_line_pos.clone(); let mut new_line_pos = self.new_line_pos.clone();
let cur_new_line_pos = new_line_pos.shift(); let cur_new_line_pos = new_line_pos.shift().unwrap();
let left_range = Range::new(text_box_info.range.begin(), cur_new_line_pos); let left_range = Range::new(text_box_info.range.begin(), cur_new_line_pos);
let right_range = Range::new(text_box_info.range.begin() + cur_new_line_pos + 1, text_box_info.range.length() - (cur_new_line_pos + 1)); let right_range = Range::new(text_box_info.range.begin() + cur_new_line_pos + 1, text_box_info.range.length() - (cur_new_line_pos + 1));
@ -1442,7 +1442,7 @@ impl Box {
None None
}; };
let right_box = right_range.map_default(None, |range: Range| { let right_box = right_range.map_or(None, |range: Range| {
let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), range); let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), range);
let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&range); let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&range);
new_metrics.bounding_box.size.height = self.border_box.get().size.height; new_metrics.bounding_box.size.height = self.border_box.get().size.height;
@ -1621,10 +1621,10 @@ impl Box {
} }
format!(" {}{},{},{},{}", format!(" {}{},{},{},{}",
name, name,
*value.top, value.top,
*value.right, value.right,
*value.bottom, value.bottom,
*value.left) value.left)
} }
/// Sends the size and position of this iframe box to the constellation. This is out of line to /// Sends the size and position of this iframe box to the constellation. This is out of line to
@ -1648,6 +1648,7 @@ impl Box {
iframe_box.pipeline_id, iframe_box.pipeline_id,
iframe_box.subpage_id); iframe_box.subpage_id);
let msg = FrameRectMsg(iframe_box.pipeline_id, iframe_box.subpage_id, rect); let msg = FrameRectMsg(iframe_box.pipeline_id, iframe_box.subpage_id, rect);
layout_context.constellation_chan.send(msg) let ConstellationChan(ref chan) = layout_context.constellation_chan;
chan.send(msg)
} }
} }

View file

@ -51,8 +51,8 @@ use servo_util::url::is_image_data;
use servo_util::str::is_whitespace; use servo_util::str::is_whitespace;
use extra::url::Url; use extra::url::Url;
use extra::arc::Arc; use sync::Arc;
use std::util; use std::mem;
use std::num::Zero; use std::num::Zero;
/// The results of flow construction for a DOM node. /// The results of flow construction for a DOM node.
@ -319,7 +319,7 @@ impl<'a> FlowConstructor<'a> {
opt_boxes: &mut Option<~[Box]>, opt_boxes: &mut Option<~[Box]>,
flow: &mut ~Flow, flow: &mut ~Flow,
node: &ThreadSafeLayoutNode) { node: &ThreadSafeLayoutNode) {
let opt_boxes = util::replace(opt_boxes, None); let opt_boxes = mem::replace(opt_boxes, None);
if opt_boxes.len() > 0 { if opt_boxes.len() > 0 {
self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node) self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node)
} }
@ -357,7 +357,7 @@ impl<'a> FlowConstructor<'a> {
// {ib} splits. // {ib} splits.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref() opt_boxes_for_inline_flow.as_ref()
.map_default(0, |boxes| boxes.len())); .map_or(0, |boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow, self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow,
&mut flow, &mut flow,
node); node);
@ -397,8 +397,8 @@ impl<'a> FlowConstructor<'a> {
// Flush any inline boxes that we were gathering up. // Flush any inline boxes that we were gathering up.
debug!("flushing {} inline box(es) to flow A", debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref() opt_boxes_for_inline_flow.as_ref()
.map_default(0, .map_or(0,
|boxes| boxes.len())); |boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary( self.flush_inline_boxes_to_flow_if_necessary(
&mut opt_boxes_for_inline_flow, &mut opt_boxes_for_inline_flow,
&mut flow, &mut flow,
@ -486,7 +486,7 @@ impl<'a> FlowConstructor<'a> {
// {ib} split. Flush the accumulator to our new split and make a new // {ib} split. Flush the accumulator to our new split and make a new
// accumulator to hold any subsequent boxes we come across. // accumulator to hold any subsequent boxes we come across.
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessor_boxes: util::replace(&mut opt_box_accumulator, None).to_vec(), predecessor_boxes: mem::replace(&mut opt_box_accumulator, None).to_vec(),
flow: flow, flow: flow,
}; };
opt_inline_block_splits.push(split); opt_inline_block_splits.push(split);
@ -513,7 +513,7 @@ impl<'a> FlowConstructor<'a> {
opt_box_accumulator.push_all_move(boxes); opt_box_accumulator.push_all_move(boxes);
let split = InlineBlockSplit { let split = InlineBlockSplit {
predecessor_boxes: util::replace(&mut opt_box_accumulator, predecessor_boxes: mem::replace(&mut opt_box_accumulator,
None).to_vec(), None).to_vec(),
flow: kid_flow, flow: kid_flow,
}; };
@ -830,7 +830,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
let mut layout_data_ref = self.mutate_layout_data(); let mut layout_data_ref = self.mutate_layout_data();
match *layout_data_ref.get() { match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
} }
None => fail!("no layout data"), None => fail!("no layout data"),
} }
@ -872,7 +872,7 @@ impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
/// Strips ignorable whitespace from the start of a list of boxes. /// Strips ignorable whitespace from the start of a list of boxes.
fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) { fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) {
match util::replace(opt_boxes, None) { match mem::replace(opt_boxes, None) {
None => return, None => return,
Some(boxes) => { Some(boxes) => {
// FIXME(pcwalton): This is slow because vector shift is broken. :( // FIXME(pcwalton): This is slow because vector shift is broken. :(
@ -907,9 +907,9 @@ fn strip_ignorable_whitespace_from_end(opt_boxes: &mut Option<~[Box]>) {
match *opt_boxes { match *opt_boxes {
None => {} None => {}
Some(ref mut boxes) => { Some(ref mut boxes) => {
while boxes.len() > 0 && boxes.last().is_whitespace_only() { while boxes.len() > 0 && boxes.last().get_ref().is_whitespace_only() {
debug!("stripping ignorable whitespace from end"); debug!("stripping ignorable whitespace from end");
let box_ = boxes.pop(); let box_ = boxes.pop().unwrap();
if boxes.len() > 0 { if boxes.len() > 0 {
boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_); boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_);
} }

View file

@ -7,7 +7,6 @@
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use layout::util::OpaqueNode; use layout::util::OpaqueNode;
use extra::arc::{Arc, MutexArc};
use extra::url::Url; use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use gfx::font_context::{FontContext, FontContextInfo}; use gfx::font_context::{FontContext, FontContextInfo};
@ -23,6 +22,7 @@ use std::rt::Runtime;
use std::rt::local::Local; use std::rt::local::Local;
use std::rt::task::Task; use std::rt::task::Task;
use style::{ComputedValues, Stylist}; use style::{ComputedValues, Stylist};
use sync::{Arc, MutexArc};
#[thread_local] #[thread_local]
static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext; static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;

View file

@ -147,7 +147,7 @@ impl Floats {
match self.list.get() { match self.list.get() {
None => None, None => None,
Some(list) => { Some(list) => {
match list.floats.last_opt() { match list.floats.last() {
None => None, None => None,
Some(float) => Some(float.bounds.origin + self.offset), Some(float) => Some(float.bounds.origin + self.offset),
} }
@ -299,11 +299,11 @@ impl Floats {
match info.kind { match info.kind {
FloatLeft => { FloatLeft => {
return Rect(Point2D(Au(0), info.ceiling), return Rect(Point2D(Au(0), info.ceiling),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
FloatRight => { FloatRight => {
return Rect(Point2D(info.max_width - info.size.width, info.ceiling), return Rect(Point2D(info.max_width - info.size.width, info.ceiling),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
} }
} }
@ -320,11 +320,11 @@ impl Floats {
return match info.kind { return match info.kind {
FloatLeft => { FloatLeft => {
Rect(Point2D(Au(0), float_y), Rect(Point2D(Au(0), float_y),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
FloatRight => { FloatRight => {
Rect(Point2D(info.max_width - info.size.width, float_y), Rect(Point2D(info.max_width - info.size.width, float_y),
Size2D(info.max_width, Au(i32::max_value))) Size2D(info.max_width, Au(i32::MAX)))
} }
} }
} }
@ -337,7 +337,7 @@ impl Floats {
let height = self.max_height_for_bounds(rect.origin.x, let height = self.max_height_for_bounds(rect.origin.x,
rect.origin.y, rect.origin.y,
rect.size.width); rect.size.width);
let height = height.unwrap_or(Au(i32::max_value)); let height = height.unwrap_or(Au(i32::MAX));
return match info.kind { return match info.kind {
FloatLeft => { FloatLeft => {
Rect(Point2D(rect.origin.x, float_y), Rect(Point2D(rect.origin.x, float_y),

View file

@ -39,7 +39,7 @@ use layout::parallel;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator}; use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator};
use extra::container::Deque; use collections::Deque;
use geom::point::Point2D; use geom::point::Point2D;
use geom::Size2D; use geom::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
@ -51,7 +51,7 @@ use servo_util::geometry::Au;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::atomics::Relaxed; use std::sync::atomics::Relaxed;
use std::vec::VecMutIterator; use std::vec::MutItems;
use std::iter::Zip; use std::iter::Zip;
use style::ComputedValues; use style::ComputedValues;
use style::computed_values::{text_align, position}; use style::computed_values::{text_align, position};
@ -531,27 +531,34 @@ bitfield!(FlowFlags, override_line_through, set_override_line_through, 0b0000_10
impl FlowFlags { impl FlowFlags {
#[inline] #[inline]
pub fn text_align(self) -> text_align::T { pub fn text_align(self) -> text_align::T {
FromPrimitive::from_u8((*self & TEXT_ALIGN_BITMASK) >> TEXT_ALIGN_SHIFT).unwrap() let FlowFlags(ff) = self;
FromPrimitive::from_u8((ff & TEXT_ALIGN_BITMASK) >> TEXT_ALIGN_SHIFT).unwrap()
} }
#[inline] #[inline]
pub fn set_text_align(&mut self, value: text_align::T) { pub fn set_text_align(&mut self, value: text_align::T) {
*self = FlowFlags((**self & !TEXT_ALIGN_BITMASK) | ((value as u8) << TEXT_ALIGN_SHIFT)) let FlowFlags(ff) = *self;
*self = FlowFlags((ff & !TEXT_ALIGN_BITMASK) | ((value as u8) << TEXT_ALIGN_SHIFT))
} }
#[inline] #[inline]
pub fn set_text_align_override(&mut self, parent: FlowFlags) { pub fn set_text_align_override(&mut self, parent: FlowFlags) {
*self = FlowFlags(**self | (*parent & TEXT_ALIGN_BITMASK)) let FlowFlags(ff) = *self;
let FlowFlags(pff) = parent;
*self = FlowFlags(ff | (pff & TEXT_ALIGN_BITMASK))
} }
#[inline] #[inline]
pub fn set_text_decoration_override(&mut self, parent: FlowFlags) { pub fn set_text_decoration_override(&mut self, parent: FlowFlags) {
*self = FlowFlags(**self | (*parent & TEXT_DECORATION_OVERRIDE_BITMASK)); let FlowFlags(ff) = *self;
let FlowFlags(pff) = parent;
*self = FlowFlags(ff | (pff & TEXT_DECORATION_OVERRIDE_BITMASK));
} }
#[inline] #[inline]
pub fn is_text_decoration_enabled(&self) -> bool { pub fn is_text_decoration_enabled(&self) -> bool {
(**self & TEXT_DECORATION_OVERRIDE_BITMASK) != 0 let FlowFlags(ref ff) = *self;
(*ff & TEXT_DECORATION_OVERRIDE_BITMASK) != 0
} }
} }
@ -606,9 +613,9 @@ impl Descendants {
pub type AbsDescendants = Descendants; pub type AbsDescendants = Descendants;
pub type FixedDescendants = Descendants; pub type FixedDescendants = Descendants;
type DescendantIter<'a> = VecMutIterator<'a, Rawlink>; type DescendantIter<'a> = MutItems<'a, Rawlink>;
type DescendantOffsetIter<'a> = Zip<VecMutIterator<'a, Rawlink>, VecMutIterator<'a, Au>>; type DescendantOffsetIter<'a> = Zip<MutItems<'a, Rawlink>, MutItems<'a, Au>>;
/// Data common to all flows. /// Data common to all flows.
pub struct BaseFlow { pub struct BaseFlow {
@ -1020,7 +1027,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
let result = lists.lists[index].list.mut_rev_iter().position(|item| { let result = lists.lists[index].list.mut_rev_iter().position(|item| {
match *item { match *item {
ClipDisplayItemClass(ref mut item) => { ClipDisplayItemClass(ref mut item) => {
item.child_list.push_all_move(child_lists.lists.shift().list); item.child_list.push_all_move(child_lists.lists.shift().unwrap().list);
true true
}, },
_ => false, _ => false,

View file

@ -6,8 +6,8 @@
//! indirection. //! indirection.
use std::cast; use std::cast;
use std::mem;
use std::ptr; use std::ptr;
use std::util;
use layout::flow::{Flow, base, mut_base}; use layout::flow::{Flow, base, mut_base};
@ -30,7 +30,6 @@ pub struct FlowList {
} }
/// Double-ended FlowList iterator /// Double-ended FlowList iterator
#[deriving(Clone)]
pub struct FlowListIterator<'a> { pub struct FlowListIterator<'a> {
priv head: &'a Link, priv head: &'a Link,
priv tail: Rawlink, priv tail: Rawlink,
@ -156,7 +155,7 @@ impl FlowList {
Some(ref mut head) => { Some(ref mut head) => {
mut_base(new_head).prev_sibling = Rawlink::none(); mut_base(new_head).prev_sibling = Rawlink::none();
mut_base(*head).prev_sibling = Rawlink::some(new_head); mut_base(*head).prev_sibling = Rawlink::some(new_head);
util::swap(head, &mut new_head); mem::swap(head, &mut new_head);
mut_base(*head).next_sibling = Some(new_head); mut_base(*head).next_sibling = Some(new_head);
} }
} }

View file

@ -13,15 +13,14 @@ use layout::flow;
use layout::util::ElementMapping; use layout::util::ElementMapping;
use layout::wrapper::ThreadSafeLayoutNode; use layout::wrapper::ThreadSafeLayoutNode;
use extra::container::Deque; use collections::{Deque, RingBuf};
use extra::ringbuf::RingBuf;
use geom::{Point2D, Rect, Size2D}; use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayListCollection; use gfx::display_list::DisplayListCollection;
use servo_util::geometry::Au; use servo_util::geometry::Au;
use servo_util::range::Range; use servo_util::range::Range;
use std::cell::RefCell; use std::cell::RefCell;
use std::mem;
use std::u16; use std::u16;
use std::util;
use style::computed_values::{text_align, vertical_align, white_space}; use style::computed_values::{text_align, vertical_align, white_space};
/// Lineboxes are represented as offsets into the child list, rather than /// Lineboxes are represented as offsets into the child list, rather than
@ -107,7 +106,7 @@ impl LineboxScanner {
if flow.boxes.is_empty() { if flow.boxes.is_empty() {
break; break;
} }
let box_ = flow.boxes.remove(0); // FIXME: use a linkedlist let box_ = flow.boxes.remove(0).unwrap(); // FIXME: use a linkedlist
debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id()); debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id());
box_ box_
} else { } else {
@ -145,8 +144,8 @@ impl LineboxScanner {
debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow", debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow",
self.lines.len()); self.lines.len());
util::swap(&mut flow.boxes, &mut self.new_boxes); mem::swap(&mut flow.boxes, &mut self.new_boxes);
util::swap(&mut flow.lines, &mut self.lines); mem::swap(&mut flow.lines, &mut self.lines);
} }
fn flush_current_line(&mut self) { fn flush_current_line(&mut self) {
@ -433,7 +432,7 @@ impl LineboxScanner {
debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len()); debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len());
if self.pending_line.range.length() == 0 { if self.pending_line.range.length() == 0 {
assert!(self.new_boxes.len() <= (u16::max_value as uint)); assert!(self.new_boxes.len() <= (u16::MAX as uint));
self.pending_line.range.reset(self.new_boxes.len(), 0); self.pending_line.range.reset(self.new_boxes.len(), 0);
} }
self.pending_line.range.extend_by(1); self.pending_line.range.extend_by(1);
@ -872,7 +871,7 @@ impl Flow for InlineFlow {
self.base.position.size.height = self.base.position.size.height =
if self.lines.len() > 0 { if self.lines.len() > 0 {
self.lines.last().bounds.origin.y + self.lines.last().bounds.size.height self.lines.last().get_ref().bounds.origin.y + self.lines.last().get_ref().bounds.size.height
} else { } else {
Au::new(0) Au::new(0)
}; };

View file

@ -22,7 +22,6 @@ use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper};
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::url::Url; use extra::url::Url;
use extra::arc::{Arc, MutexArc};
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
@ -55,11 +54,12 @@ use std::cast::transmute;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::comm::Port; use std::comm::Port;
use std::mem;
use std::ptr; use std::ptr;
use std::task; use std::task;
use std::util;
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist}; use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist};
use style; use style;
use sync::{Arc, MutexArc};
/// Information needed by the layout task. /// Information needed by the layout task.
pub struct LayoutTask { pub struct LayoutTask {
@ -236,7 +236,8 @@ impl ImageResponder for LayoutImageResponder {
let id = self.id.clone(); let id = self.id.clone();
let script_chan = self.script_chan.clone(); let script_chan = self.script_chan.clone();
let f: proc(ImageResponseMsg) = proc(_) { let f: proc(ImageResponseMsg) = proc(_) {
drop(script_chan.try_send(SendEventMsg(id.clone(), ReflowEvent))) let ScriptChan(chan) = script_chan;
drop(chan.try_send(SendEventMsg(id.clone(), ReflowEvent)))
}; };
f f
} }
@ -255,9 +256,9 @@ impl LayoutTask {
opts: Opts, opts: Opts,
profiler_chan: ProfilerChan, profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) { shutdown_chan: Chan<()>) {
let mut builder = task::task(); let mut builder = task::task().named("LayoutTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(con_chan) = constellation_chan.clone();
builder.name("LayoutTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), con_chan);
builder.spawn(proc() { builder.spawn(proc() {
{ // Ensures layout task is destroyed before we send shutdown message { // Ensures layout task is destroyed before we send shutdown message
let mut layout = LayoutTask::new(id, let mut layout = LayoutTask::new(id,
@ -426,7 +427,7 @@ impl LayoutTask {
let mut layout_data_ref = node.mutate_layout_data(); let mut layout_data_ref = node.mutate_layout_data();
let result = match *layout_data_ref.get() { let result = match *layout_data_ref.get() {
Some(ref mut layout_data) => { Some(ref mut layout_data) => {
util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
} }
None => fail!("no layout data for root node"), None => fail!("no layout data for root node"),
}; };
@ -539,11 +540,9 @@ impl LayoutTask {
debug!("{:?}", node.dump()); debug!("{:?}", node.dump());
// Reset the image cache. // Reset the image cache.
unsafe { self.local_image_cache.access(|local_image_cache| {
self.local_image_cache.unsafe_access(|local_image_cache| { local_image_cache.next_round(self.make_on_image_available_cb())
local_image_cache.next_round(self.make_on_image_available_cb()) });
});
}
// true => Do the reflow with full style damage, because content // true => Do the reflow with full style damage, because content
// changed or the window was resized. // changed or the window was resized.
@ -691,7 +690,8 @@ impl LayoutTask {
// FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without // FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without
// either select or a filtered recv() that only looks for messages of a given type. // either select or a filtered recv() that only looks for messages of a given type.
data.script_join_chan.send(()); data.script_join_chan.send(());
data.script_chan.send(ReflowCompleteMsg(self.id, data.id)); let ScriptChan(ref chan) = data.script_chan;
chan.send(ReflowCompleteMsg(self.id, data.id));
} }
/// Handles a query from the script task. This is the main routine that DOM functions like /// Handles a query from the script task. This is the main routine that DOM functions like
@ -857,6 +857,6 @@ impl LayoutTask {
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) { unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
let mut layout_data_ref = layout_data.borrow_mut(); let mut layout_data_ref = layout_data.borrow_mut();
let _: Option<LayoutDataWrapper> = cast::transmute( let _: Option<LayoutDataWrapper> = cast::transmute(
util::replace(layout_data_ref.get(), None)); mem::replace(layout_data_ref.get(), None));
} }
} }

View file

@ -29,7 +29,7 @@ use style::{Stylist, TNode};
#[allow(dead_code)] #[allow(dead_code)]
fn static_assertion(node: UnsafeLayoutNode) { fn static_assertion(node: UnsafeLayoutNode) {
unsafe { unsafe {
let _: PaddedUnsafeFlow = ::std::unstable::intrinsics::transmute(node); let _: PaddedUnsafeFlow = ::std::intrinsics::transmute(node);
} }
} }
@ -235,7 +235,7 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data()); let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data());
// Get a real layout node. // Get a real layout node.
let node: LayoutNode = ::std::unstable::intrinsics::transmute(unsafe_layout_node); let node: LayoutNode = ::std::intrinsics::transmute(unsafe_layout_node);
// Initialize layout data. // Initialize layout data.
// //

View file

@ -7,13 +7,13 @@
use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox}; use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
use layout::flow::Flow; use layout::flow::Flow;
use extra::arc::Arc;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone}; use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone};
use servo_util::range::Range; use servo_util::range::Range;
use std::vec; use std::vec;
use style::computed_values::white_space; use style::computed_values::white_space;
use sync::Arc;
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es.
pub struct TextRunScanner { pub struct TextRunScanner {

View file

@ -7,7 +7,6 @@ use layout::construct::{ConstructionResult, NoConstructionResult};
use layout::parallel::DomParallelInfo; use layout::parallel::DomParallelInfo;
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
use extra::arc::Arc;
use script::dom::bindings::js::JS; use script::dom::bindings::js::JS;
use script::dom::bindings::utils::Reflectable; use script::dom::bindings::utils::Reflectable;
use script::dom::node::Node; use script::dom::node::Node;
@ -17,8 +16,9 @@ use std::cast;
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::iter::Enumerate; use std::iter::Enumerate;
use std::libc::uintptr_t; use std::libc::uintptr_t;
use std::vec::VecIterator; use std::vec::Items;
use style::ComputedValues; use style::ComputedValues;
use sync::Arc;
/// A range of nodes. /// A range of nodes.
pub struct NodeRange { pub struct NodeRange {
@ -59,7 +59,7 @@ impl ElementMapping {
true true
} }
pub fn eachi<'a>(&'a self) -> Enumerate<VecIterator<'a, NodeRange>> { pub fn eachi<'a>(&'a self) -> Enumerate<Items<'a, NodeRange>> {
self.entries.iter().enumerate() self.entries.iter().enumerate()
} }
@ -113,8 +113,8 @@ impl ElementMapping {
old_i += 1; old_i += 1;
// possibly pop several items // possibly pop several items
while repair_stack.len() > 0 && old_i == entries[repair_stack.last().entry_idx].range.end() { while repair_stack.len() > 0 && old_i == entries[repair_stack.last().get_ref().entry_idx].range.end() {
let item = repair_stack.pop(); let item = repair_stack.pop().unwrap();
debug!("repair_for_box_changes: Set range for {:u} to {}", debug!("repair_for_box_changes: Set range for {:u} to {}",
item.entry_idx, Range::new(item.begin_idx, new_j - item.begin_idx)); item.entry_idx, Range::new(item.begin_idx, new_j - item.begin_idx));
entries[item.entry_idx].range = Range::new(item.begin_idx, new_j - item.begin_idx); entries[item.entry_idx].range = Range::new(item.begin_idx, new_j - item.begin_idx);

View file

@ -139,7 +139,6 @@ pub trait TLayoutNode {
/// A wrapper so that layout can access only the methods that it should have access to. Layout must /// A wrapper so that layout can access only the methods that it should have access to. Layout must
/// only ever see these and must never see instances of `JS`. /// only ever see these and must never see instances of `JS`.
#[deriving(Clone, Eq)]
pub struct LayoutNode<'a> { pub struct LayoutNode<'a> {
/// The wrapped node. /// The wrapped node.
priv node: JS<Node>, priv node: JS<Node>,
@ -148,6 +147,24 @@ pub struct LayoutNode<'a> {
priv chain: &'a (), priv chain: &'a (),
} }
impl<'ln> Clone for LayoutNode<'ln> {
fn clone(&self) -> LayoutNode<'ln> {
LayoutNode {
node: self.node.clone(),
chain: self.chain,
}
}
}
impl<'a> Eq for LayoutNode<'a> {
#[inline]
fn eq(&self, other: &LayoutNode) -> bool {
self.node == other.node &&
self.chain == other.chain
}
}
impl<'ln> TLayoutNode for LayoutNode<'ln> { impl<'ln> TLayoutNode for LayoutNode<'ln> {
unsafe fn new_with_this_lifetime(&self, node: &JS<Node>) -> LayoutNode<'ln> { unsafe fn new_with_this_lifetime(&self, node: &JS<Node>) -> LayoutNode<'ln> {
LayoutNode { LayoutNode {
@ -244,7 +261,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
match attr.namespace { match attr.namespace {
SpecificNamespace(ref ns) => { SpecificNamespace(ref ns) => {
element.get_attr(ns, name) element.get_attr(ns, name)
.map_default(false, |attr| test(attr)) .map_or(false, |attr| test(attr))
}, },
// FIXME: https://github.com/mozilla/servo/issues/1558 // FIXME: https://github.com/mozilla/servo/issues/1558
AnyNamespace => false, AnyNamespace => false,

View file

@ -12,12 +12,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(this) = self;
(this & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(this) = *self;
*self = $bitfieldname((this & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -20,9 +20,7 @@ use servo_net::resource_task::ResourceTask;
use servo_util::opts::Opts; use servo_util::opts::Opts;
use servo_util::time::ProfilerChan; use servo_util::time::ProfilerChan;
use std::cell::RefCell; use std::cell::RefCell;
//FIXME: switch to std::rc when we upgrade Rust use std::rc::Rc;
use layers::temp_rc::Rc;
//use std::rc::Rc;
/// A uniquely-identifiable pipeline of script task, layout task, and render task. /// A uniquely-identifiable pipeline of script task, layout task, and render task.
pub struct Pipeline { pub struct Pipeline {
@ -94,7 +92,8 @@ impl Pipeline {
layout_chan: layout_chan.clone(), layout_chan: layout_chan.clone(),
}; };
script_pipeline.borrow().script_chan.send(AttachLayoutMsg(new_layout_info)); let ScriptChan(ref chan) = script_pipeline.borrow().script_chan;
chan.send(AttachLayoutMsg(new_layout_info));
Pipeline::new(id, Pipeline::new(id,
subpage_id, subpage_id,
@ -190,16 +189,17 @@ impl Pipeline {
pub fn load(&self, url: Url) { pub fn load(&self, url: Url) {
self.url.set(Some(url.clone())); self.url.set(Some(url.clone()));
self.script_chan.send(LoadMsg(self.id, url)); let ScriptChan(ref chan) = self.script_chan;
chan.send(LoadMsg(self.id, url));
} }
pub fn grant_paint_permission(&self) { pub fn grant_paint_permission(&self) {
self.render_chan.try_send(PaintPermissionGranted); self.render_chan.chan.try_send(PaintPermissionGranted);
} }
pub fn revoke_paint_permission(&self) { pub fn revoke_paint_permission(&self) {
debug!("pipeline revoking render channel paint permission"); debug!("pipeline revoking render channel paint permission");
self.render_chan.try_send(PaintPermissionRevoked); self.render_chan.chan.try_send(PaintPermissionRevoked);
} }
pub fn reload(&self) { pub fn reload(&self) {
@ -211,7 +211,8 @@ impl Pipeline {
pub fn exit(&self) { pub fn exit(&self) {
// Script task handles shutting down layout, and layout handles shutting down the renderer. // Script task handles shutting down layout, and layout handles shutting down the renderer.
// For now, if the script task has failed, we give up on clean shutdown. // For now, if the script task has failed, we give up on clean shutdown.
if self.script_chan.try_send(script_task::ExitPipelineMsg(self.id)) { let ScriptChan(ref chan) = self.script_chan;
if chan.try_send(script_task::ExitPipelineMsg(self.id)) {
// Wait until all slave tasks have terminated and run destructors // Wait until all slave tasks have terminated and run destructors
// NOTE: We don't wait for script task as we don't always own it // NOTE: We don't wait for script task as we don't always own it
self.render_shutdown_port.recv_opt(); self.render_shutdown_port.recv_opt();

View file

@ -12,11 +12,10 @@ use windowing::RefreshWindowEvent;
use windowing::{Forward, Back}; use windowing::{Forward, Back};
use alert::{Alert, AlertMethods}; use alert::{Alert, AlertMethods};
use extra::time::Timespec; use time;
use extra::time; use time::Timespec;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::libc::{exit, c_int}; use std::libc::{exit, c_int};
use std::local_data;
use std::rc::Rc; use std::rc::Rc;
use geom::point::Point2D; use geom::point::Point2D;
@ -46,13 +45,6 @@ impl ApplicationMethods for Application {
} }
} }
impl Drop for Application {
fn drop(&mut self) {
drop_local_window();
glfw::terminate();
}
}
macro_rules! glfw_callback( macro_rules! glfw_callback(
( (
$callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
@ -128,64 +120,14 @@ impl WindowMethods<Application> for Window {
}; };
// Register event handlers. // Register event handlers.
window.glfw_window.set_framebuffer_size_callback( window.glfw_window.set_framebuffer_size_polling(true);
glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) { window.glfw_window.set_refresh_polling(true);
let tmp = local_window(); window.glfw_window.set_key_polling(true);
tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint))); window.glfw_window.set_mouse_button_polling(true);
})); window.glfw_window.set_cursor_pos_polling(true);
window.glfw_window.set_refresh_callback( window.glfw_window.set_scroll_polling(true);
glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
}));
window.glfw_window.set_key_callback(
glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
action: glfw::Action, mods: glfw::Modifiers) {
if action == glfw::Press {
let tmp = local_window();
tmp.borrow().handle_key(key, mods)
}
}));
window.glfw_window.set_mouse_button_callback(
glfw_callback!(glfw::MouseButtonCallback(win: &glfw::Window, button: glfw::MouseButton,
action: glfw::Action, _mods: glfw::Modifiers) {
let (x, y) = win.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = win.get_framebuffer_size();
let (window_size, _) = win.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
let tmp = local_window();
tmp.borrow().handle_mouse(button, action, x as i32, y as i32);
}
}));
window.glfw_window.set_cursor_pos_callback(
glfw_callback!(glfw::CursorPosCallback(_win: &glfw::Window, xpos: f64, ypos: f64) {
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
}));
window.glfw_window.set_scroll_callback(
glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
let dx = (xpos as f32) * 30.0;
let dy = (ypos as f32) * 30.0;
let (x, y) = win.get_cursor_pos(); let wrapped_window = Rc::new(window);
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = win.get_framebuffer_size();
let (window_size, _) = win.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
let tmp = local_window();
tmp.borrow().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
}));
let wrapped_window = Rc::from_send(window);
install_local_window(wrapped_window.clone());
wrapped_window wrapped_window
} }
@ -203,14 +145,18 @@ impl WindowMethods<Application> for Window {
fn recv(&self) -> WindowEvent { fn recv(&self) -> WindowEvent {
if !self.event_queue.with_mut(|queue| queue.is_empty()) { if !self.event_queue.with_mut(|queue| queue.is_empty()) {
return self.event_queue.with_mut(|queue| queue.shift()) return self.event_queue.with_mut(|queue| queue.shift().unwrap())
} }
glfw::poll_events(); glfw::poll_events();
for (_, event) in self.glfw_window.flush_events() {
self.handle_window_event(&self.glfw_window, event);
}
if self.glfw_window.should_close() { if self.glfw_window.should_close() {
QuitWindowEvent QuitWindowEvent
} else if !self.event_queue.with_mut(|queue| queue.is_empty()) { } else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
self.event_queue.with_mut(|queue| queue.shift()) self.event_queue.with_mut(|queue| queue.shift().unwrap())
} else { } else {
IdleWindowEvent IdleWindowEvent
} }
@ -243,6 +189,52 @@ impl WindowMethods<Application> for Window {
} }
impl Window { impl Window {
fn handle_window_event(&self, window: &glfw::Window, event: glfw::WindowEvent) {
match event {
glfw::KeyEvent(key, _, action, mods) => {
if action == glfw::Press {
self.handle_key(key, mods)
}
},
glfw::FramebufferSizeEvent(width, height) => {
self.event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
},
glfw::RefreshEvent => {
self.event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
},
glfw::MouseButtonEvent(button, action, _mods) => {
let (x, y) = window.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = window.get_framebuffer_size();
let (window_size, _) = window.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
self.handle_mouse(button, action, x as i32, y as i32);
}
},
glfw::CursorPosEvent(xpos, ypos) => {
self.event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
},
glfw::ScrollEvent(xpos, ypos) => {
let dx = (xpos as f32) * 30.0;
let dy = (ypos as f32) * 30.0;
let (x, y) = window.get_cursor_pos();
//handle hidpi displays, since GLFW returns non-hi-def coordinates.
let (backing_size, _) = window.get_framebuffer_size();
let (window_size, _) = window.get_size();
let hidpi = (backing_size as f32) / (window_size as f32);
let x = x as f32 * hidpi;
let y = y as f32 * hidpi;
self.event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
},
_ => {}
}
}
/// Helper function to set the window title in accordance with the ready state. /// Helper function to set the window title in accordance with the ready state.
fn update_window_title(&self) { fn update_window_title(&self) {
let now = time::get_time(); let now = time::get_time();
@ -340,17 +332,3 @@ impl Window {
} }
} }
} }
static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;
fn install_local_window(window: Rc<Window>) {
local_data::set(TLS_KEY, window);
}
fn drop_local_window() {
local_data::pop(TLS_KEY);
}
fn local_window() -> Rc<Window> {
local_data::get(TLS_KEY, |v| v.unwrap().clone())
}

View file

@ -132,7 +132,7 @@ impl WindowMethods<Application> for Window {
} }
glut::mouse_func(~MouseCallbackState); glut::mouse_func(~MouseCallbackState);
let wrapped_window = Rc::from_send(window); let wrapped_window = Rc::new(window);
install_local_window(wrapped_window.clone()); install_local_window(wrapped_window.clone());
@ -151,11 +151,11 @@ impl WindowMethods<Application> for Window {
fn recv(&self) -> WindowEvent { fn recv(&self) -> WindowEvent {
if !self.event_queue.with_mut(|queue| queue.is_empty()) { if !self.event_queue.with_mut(|queue| queue.is_empty()) {
return self.event_queue.with_mut(|queue| queue.shift()) return self.event_queue.with_mut(|queue| queue.shift().unwrap())
} }
glut::check_loop(); glut::check_loop();
if !self.event_queue.with_mut(|queue| queue.is_empty()) { if !self.event_queue.with_mut(|queue| queue.is_empty()) {
self.event_queue.with_mut(|queue| queue.shift()) self.event_queue.with_mut(|queue| queue.shift().unwrap())
} else { } else {
IdleWindowEvent IdleWindowEvent
} }

View file

@ -8,43 +8,47 @@
#[feature(globs, macro_rules, managed_boxes, thread_local)]; #[feature(globs, macro_rules, managed_boxes, thread_local)];
extern mod alert; extern crate alert;
extern mod azure; extern crate azure;
extern mod geom; extern crate geom;
extern mod gfx; extern crate gfx;
#[cfg(not(target_os="android"))] #[cfg(not(target_os="android"))]
extern mod glfw; extern crate glfw = "glfw-rs";
#[cfg(target_os="android")] #[cfg(target_os="android")]
extern mod glut; extern crate glut;
extern mod js; extern crate js;
extern mod layers; extern crate layers;
extern mod opengles; extern crate opengles;
extern mod png; extern crate png;
#[cfg(target_os="android")] #[cfg(target_os="android")]
extern mod rustuv; extern crate rustuv;
extern mod script; extern crate script;
extern mod servo_net = "net"; extern crate servo_net = "net";
extern mod servo_msg = "msg"; extern crate servo_msg = "msg";
extern mod servo_util = "util"; extern crate servo_util = "util";
extern mod style; extern crate style;
extern mod sharegl; extern crate sharegl;
extern mod stb_image; extern crate stb_image;
extern mod extra; extern crate collections;
extern mod green; extern crate extra;
extern mod native; extern crate green;
extern crate native;
extern crate serialize;
extern crate sync;
extern crate time;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_graphics; extern crate core_graphics;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_text; extern crate core_text;
#[cfg(not(test))] #[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask}; use compositing::{CompositorChan, CompositorTask};
#[cfg(not(test))] #[cfg(not(test))]
use constellation::Constellation; use constellation::Constellation;
#[cfg(not(test))] #[cfg(not(test))]
use servo_msg::constellation_msg::InitLoadUrlMsg; use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
#[cfg(not(test))] #[cfg(not(test))]
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask}; use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
@ -109,9 +113,6 @@ pub mod windowing;
#[path="platform/mod.rs"] #[path="platform/mod.rs"]
pub mod platform; pub mod platform;
#[path = "util/mod.rs"]
pub mod util;
#[cfg(not(test), target_os="linux")] #[cfg(not(test), target_os="linux")]
#[cfg(not(test), target_os="macos")] #[cfg(not(test), target_os="macos")]
#[start] #[start]
@ -175,7 +176,8 @@ fn run(opts: opts::Opts) {
parse_url(*filename, None) parse_url(*filename, None)
}; };
constellation_chan.send(InitLoadUrlMsg(url)); let ConstellationChan(ref chan) = constellation_chan;
chan.send(InitLoadUrlMsg(url));
} }
// Send the constallation Chan as the result // Send the constallation Chan as the result

View file

@ -1,8 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
pub use servo_util::cache;
pub mod task;

View file

@ -1,23 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 servo_util::task::spawn_named;
pub fn spawn_listener<A: Send, S: IntoSendStr>(name: S, f: proc(Port<A>)) -> Chan<A> {
let (setup_po, setup_ch) = Chan::new();
spawn_named(name, proc() {
let (po, ch) = Chan::new();
setup_ch.send(ch);
f(po);
});
setup_po.recv()
}
pub fn spawn_conversation<A: Send, B: Send, S: IntoSendStr>(name: S, f: proc(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
let (from_child, to_parent) = Chan::new();
let to_child = do spawn_listener(name) |from_parent| {
f(from_parent, to_parent)
};
(from_child, to_child)
}

View file

@ -11,7 +11,7 @@ use layers::platform::surface::{NativeSurface, NativeSurfaceMethods};
use constellation_msg::PipelineId; use constellation_msg::PipelineId;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
pub struct LayerBuffer { pub struct LayerBuffer {
/// The native surface which can be shared between threads or processes. On Mac this is an /// The native surface which can be shared between threads or processes. On Mac this is an
@ -71,7 +71,8 @@ pub struct Epoch(uint);
impl Epoch { impl Epoch {
pub fn next(&mut self) { pub fn next(&mut self) {
**self += 1; let Epoch(ref mut u) = *self;
*u += 1;
} }
} }
@ -97,7 +98,7 @@ pub trait ScriptListener : Clone {
fn dup(&self) -> ~ScriptListener; fn dup(&self) -> ~ScriptListener;
} }
impl<S: Encoder> Encodable<S> for @ScriptListener { impl<S: Encoder> Encodable<S> for ~ScriptListener {
fn encode(&self, _s: &mut S) { fn encode(&self, _s: &mut S) {
} }
} }
@ -125,7 +126,7 @@ impl Tile for ~LayerBuffer {
self.screen_pos.size.width * self.screen_pos.size.height self.screen_pos.size.width * self.screen_pos.size.height
} }
fn is_valid(&self, scale: f32) -> bool { fn is_valid(&self, scale: f32) -> bool {
self.resolution.approx_eq(&scale) (self.resolution - scale).abs() < 1.0e-6
} }
fn get_size_2d(&self) -> Size2D<uint> { fn get_size_2d(&self) -> Size2D<uint> {
self.screen_pos.size self.screen_pos.size

View file

@ -8,14 +8,14 @@
use extra::url::Url; use extra::url::Url;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use std::comm::SharedChan; use std::comm::Chan;
#[deriving(Clone)] #[deriving(Clone)]
pub struct ConstellationChan(SharedChan<Msg>); pub struct ConstellationChan(Chan<Msg>);
impl ConstellationChan { impl ConstellationChan {
pub fn new() -> (Port<Msg>, ConstellationChan) { pub fn new() -> (Port<Msg>, ConstellationChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, ConstellationChan(chan)) (port, ConstellationChan(chan))
} }
} }
@ -48,20 +48,20 @@ pub enum Msg {
} }
/// Represents the two different ways to which a page can be navigated /// Represents the two different ways to which a page can be navigated
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, Hash)]
pub enum NavigationType { pub enum NavigationType {
Load, // entered or clicked on a url Load, // entered or clicked on a url
Navigate, // browser forward/back buttons Navigate, // browser forward/back buttons
} }
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, Hash)]
pub enum NavigationDirection { pub enum NavigationDirection {
Forward, Forward,
Back, Back,
} }
#[deriving(Clone, Eq, IterBytes, Encodable)] #[deriving(Clone, Eq, Hash, Encodable)]
pub struct PipelineId(uint); pub struct PipelineId(uint);
#[deriving(Clone, Eq, IterBytes, Encodable)] #[deriving(Clone, Eq, Hash, Encodable)]
pub struct SubpageId(uint); pub struct SubpageId(uint);

View file

@ -7,16 +7,17 @@
#[feature(managed_boxes)]; #[feature(managed_boxes)];
extern mod azure; extern crate azure;
extern mod extra; extern crate extra;
extern mod geom; extern crate geom;
extern mod layers; extern crate layers;
extern mod std; extern crate serialize;
extern crate std;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod core_foundation; extern crate core_foundation;
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
extern mod io_surface; extern crate io_surface;
pub mod compositor_msg; pub mod compositor_msg;
pub mod constellation_msg; pub mod constellation_msg;

View file

@ -5,7 +5,7 @@
use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending}; use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending};
use extra::url::Url; use extra::url::Url;
use extra::base64::FromBase64; use serialize::base64::FromBase64;
use http::headers::test_utils::from_stream_with_str; use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType; use http::headers::content_type::MediaType;

View file

@ -3,22 +3,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending}; use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending};
use servo_util::io::result;
use std::io; use std::io;
use std::io::File; use std::io::File;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
static READ_SIZE: uint = 1024; //FIXME: https://github.com/mozilla/rust/issues/12892
static READ_SIZE: uint = 1;
fn read_all(reader: &mut io::Stream, progress_chan: &SharedChan<ProgressMsg>) fn read_all(reader: &mut io::Stream, progress_chan: &Chan<ProgressMsg>)
-> Result<(), ()> { -> Result<(), ()> {
loop { loop {
match (result(|| { let mut buf = ~[];
let data = reader.read_bytes(READ_SIZE); match reader.push_bytes(&mut buf, READ_SIZE) {
progress_chan.send(Payload(data)); Ok(_) => progress_chan.send(Payload(buf)),
})) {
Ok(()) => (),
Err(e) => match e.kind { Err(e) => match e.kind {
io::EndOfFile => return Ok(()), io::EndOfFile => return Ok(()),
_ => return Err(()), _ => return Err(()),
@ -32,14 +30,12 @@ pub fn factory() -> LoaderTask {
assert!("file" == url.scheme); assert!("file" == url.scheme);
let progress_chan = start_sending(start_chan, Metadata::default(url.clone())); let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
spawn_named("file_loader", proc() { spawn_named("file_loader", proc() {
// ignore_io_error causes us to get None instead of a task failure.
let _guard = io::ignore_io_error();
match File::open_mode(&Path::new(url.path), io::Open, io::Read) { match File::open_mode(&Path::new(url.path), io::Open, io::Read) {
Some(ref mut reader) => { Ok(ref mut reader) => {
let res = read_all(reader as &mut io::Stream, &progress_chan); let res = read_all(reader as &mut io::Stream, &progress_chan);
progress_chan.send(Done(res)); progress_chan.send(Done(res));
} }
None => { Err(_) => {
progress_chan.send(Done(Err(()))); progress_chan.send(Done(Err(())));
} }
}; };

View file

@ -5,12 +5,13 @@
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending}; use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
use std::vec; use std::vec;
use std::hashmap::HashSet; use collections::hashmap::HashSet;
use extra::url::Url; use extra::url::Url;
use http::client::RequestWriter; use http::client::RequestWriter;
use http::method::Get; use http::method::Get;
use http::headers::HeaderEnum; use http::headers::HeaderEnum;
use std::io::Reader; use std::io::Reader;
use std::io::net::tcp::TcpStream;
use servo_util::task::spawn_named; use servo_util::task::spawn_named;
pub fn factory() -> LoaderTask { pub fn factory() -> LoaderTask {
@ -55,8 +56,15 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
info!("requesting {:s}", url.to_str()); info!("requesting {:s}", url.to_str());
let request = ~RequestWriter::new(Get, url.clone()); let request = RequestWriter::<TcpStream>::new(Get, url.clone());
let mut response = match request.read_response() { let writer = match request {
Ok(w) => ~w,
Err(_) => {
send_error(url, start_chan);
return;
}
};
let mut response = match writer.read_response() {
Ok(r) => r, Ok(r) => r,
Err(_) => { Err(_) => {
send_error(url, start_chan); send_error(url, start_chan);
@ -91,11 +99,11 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
unsafe { buf.set_len(1024); } unsafe { buf.set_len(1024); }
match response.read(buf) { match response.read(buf) {
Some(len) => { Ok(len) => {
unsafe { buf.set_len(len); } unsafe { buf.set_len(len); }
progress_chan.send(Payload(buf)); progress_chan.send(Payload(buf));
} }
None => { Err(_) => {
progress_chan.send(Done(Ok(()))); progress_chan.send(Done(Ok(())));
break; break;
} }

View file

@ -61,7 +61,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
Some(Image(image.width as u32, image.height as u32, png::RGBA8, image.data)) Some(Image(image.width as u32, image.height as u32, png::RGBA8, image.data))
} }
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"), stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
stb_image::Error => None stb_image::Error(_) => None
} }
} }
} }

View file

@ -6,10 +6,10 @@ use image::base::Image;
use image_cache_task::{ImageReady, ImageNotReady, ImageFailed}; use image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
use local_image_cache::LocalImageCache; use local_image_cache::LocalImageCache;
use extra::arc::{Arc, MutexArc}; use sync::{Arc, MutexArc};
use extra::url::Url; use extra::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use std::util; use std::mem;
// FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from // FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
// the network stack. This should probably be factored out into an interface and use dependency // the network stack. This should probably be factored out into an interface and use dependency
@ -40,12 +40,10 @@ impl ImageHolder {
// but they are intended to be spread out in time. Ideally prefetch // but they are intended to be spread out in time. Ideally prefetch
// should be done as early as possible and decode only once we // should be done as early as possible and decode only once we
// are sure that the image will be used. // are sure that the image will be used.
unsafe { holder.local_image_cache.access(|local_image_cache| {
holder.local_image_cache.unsafe_access(|local_image_cache| { local_image_cache.prefetch(&holder.url);
local_image_cache.prefetch(&holder.url); local_image_cache.decode(&holder.url);
local_image_cache.decode(&holder.url); });
});
}
holder holder
} }
@ -76,11 +74,10 @@ impl ImageHolder {
// If this is the first time we've called this function, load // If this is the first time we've called this function, load
// the image and store it for the future // the image and store it for the future
if self.image.is_none() { if self.image.is_none() {
let port = unsafe { let port =
self.local_image_cache.unsafe_access(|local_image_cache| { self.local_image_cache.access(|local_image_cache| {
local_image_cache.get_image(&self.url) local_image_cache.get_image(&self.url)
}) });
};
match port.recv() { match port.recv() {
ImageReady(image) => { ImageReady(image) => {
self.image = Some(image); self.image = Some(image);
@ -95,9 +92,9 @@ impl ImageHolder {
} }
// Clone isn't pure so we have to swap out the mutable image option // Clone isn't pure so we have to swap out the mutable image option
let image = util::replace(&mut self.image, None); let image = mem::replace(&mut self.image, None);
let result = image.clone(); let result = image.clone();
util::replace(&mut self.image, image); mem::replace(&mut self.image, image);
return result; return result;
} }

View file

@ -7,14 +7,14 @@ use resource_task;
use resource_task::ResourceTask; use resource_task::ResourceTask;
use servo_util::url::{UrlMap, url_map}; use servo_util::url::{UrlMap, url_map};
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port};
use std::mem::replace;
use std::task::spawn; use std::task::spawn;
use std::to_str::ToStr; use std::to_str::ToStr;
use std::util::replace;
use std::result; use std::result;
use extra::arc::{Arc,MutexArc}; use sync::{Arc,MutexArc};
use extra::url::Url; use extra::url::Url;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
pub enum Msg { pub enum Msg {
/// Tell the cache that we may need a particular image soon. Must be posted /// Tell the cache that we may need a particular image soon. Must be posted
@ -78,7 +78,7 @@ impl Eq for ImageResponseMsg {
#[deriving(Clone)] #[deriving(Clone)]
pub struct ImageCacheTask { pub struct ImageCacheTask {
chan: SharedChan<Msg>, chan: Chan<Msg>,
} }
impl<S: Encoder> Encodable<S> for ImageCacheTask { impl<S: Encoder> Encodable<S> for ImageCacheTask {
@ -89,7 +89,7 @@ impl<S: Encoder> Encodable<S> for ImageCacheTask {
type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>; type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
let chan_clone = chan.clone(); let chan_clone = chan.clone();
spawn(proc() { spawn(proc() {
@ -111,7 +111,7 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
// FIXME: make this priv after visibility rules change // FIXME: make this priv after visibility rules change
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask { pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
spawn(proc() { spawn(proc() {
let inner_cache = ImageCacheTask(resource_task.clone()); let inner_cache = ImageCacheTask(resource_task.clone());
@ -143,7 +143,7 @@ struct ImageCache {
/// The port on which we'll receive client requests /// The port on which we'll receive client requests
port: Port<Msg>, port: Port<Msg>,
/// A copy of the shared chan to give to child tasks /// A copy of the shared chan to give to child tasks
chan: SharedChan<Msg>, chan: Chan<Msg>,
/// The state of processsing an image for a URL /// The state of processsing an image for a URL
state_map: UrlMap<ImageState>, state_map: UrlMap<ImageState>,
/// List of clients waiting on a WaitForImage response /// List of clients waiting on a WaitForImage response
@ -375,13 +375,11 @@ impl ImageCache {
fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) { fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) {
match self.wait_map.pop(&url) { match self.wait_map.pop(&url) {
Some(waiters) => { Some(waiters) => {
unsafe { waiters.access(|waiters| {
waiters.unsafe_access(|waiters| { for response in waiters.iter() {
for response in waiters.iter() { response.send(f());
response.send(f()); }
} });
});
}
} }
None => () None => ()
} }
@ -409,9 +407,7 @@ impl ImageCache {
if self.wait_map.contains_key(&url) { if self.wait_map.contains_key(&url) {
let waiters = self.wait_map.find_mut(&url).unwrap(); let waiters = self.wait_map.find_mut(&url).unwrap();
let mut response = Some(response); let mut response = Some(response);
unsafe { waiters.access(|waiters| waiters.push(response.take().unwrap()));
waiters.unsafe_access(|waiters| waiters.push(response.take().unwrap()))
}
} else { } else {
self.wait_map.insert(url, MutexArc::new(~[response])); self.wait_map.insert(url, MutexArc::new(~[response]));
} }
@ -430,7 +426,7 @@ impl ImageCache {
} }
trait ImageCacheTaskClient { pub trait ImageCacheTaskClient {
fn exit(&self); fn exit(&self);
} }
@ -485,6 +481,18 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
} }
pub fn spawn_listener<A: Send>(f: proc(Port<A>)) -> Chan<A> {
let (setup_port, setup_chan) = Chan::new();
spawn(proc() {
let (port, chan) = Chan::new();
setup_chan.send(chan);
f(port);
});
setup_port.recv()
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -492,11 +500,11 @@ mod tests {
use resource_task; use resource_task;
use resource_task::{ResourceTask, Metadata, start_sending}; use resource_task::{ResourceTask, Metadata, start_sending};
use image::base::test_image_bin; use image::base::test_image_bin;
use util::spawn_listener;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use std::comm::{Empty, Data, Disconnected};
fn mock_resource_task(on_load: proc(resource: SharedChan<resource_task::ProgressMsg>)) -> ResourceTask { fn mock_resource_task(on_load: proc(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
spawn_listener("mock_resource_task", proc(port: Port<resource_task::ControlMsg>) { spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop { loop {
match port.recv() { match port.recv() {
resource_task::Load(_, response) => { resource_task::Load(_, response) => {
@ -568,7 +576,10 @@ mod tests {
url_requested.recv(); url_requested.recv();
image_cache_task.exit(); image_cache_task.exit();
mock_resource_task.send(resource_task::Exit); mock_resource_task.send(resource_task::Exit);
assert!(url_requested.try_recv().is_none()) match url_requested.try_recv() {
Empty | Disconnected => (),
Data(_) => assert!(false),
};
} }
#[test] #[test]
@ -662,7 +673,7 @@ mod tests {
let (resource_task_exited, resource_task_exited_chan) = Chan::new(); let (resource_task_exited, resource_task_exited_chan) = Chan::new();
let mock_resource_task = spawn_listener("should_not...already_available", proc(port: Port<resource_task::ControlMsg>) { let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop { loop {
match port.recv() { match port.recv() {
resource_task::Load(_, response) => { resource_task::Load(_, response) => {
@ -696,7 +707,10 @@ mod tests {
// Our resource task should not have received another request for the image // Our resource task should not have received another request for the image
// because it's already cached // because it's already cached
assert!(image_bin_sent.try_recv().is_none()); match image_bin_sent.try_recv() {
Empty | Disconnected => (),
Data(_) => assert!(false),
}
} }
#[test] #[test]
@ -705,7 +719,7 @@ mod tests {
let (resource_task_exited, resource_task_exited_chan) = Chan::new(); let (resource_task_exited, resource_task_exited_chan) = Chan::new();
let mock_resource_task = spawn_listener("should_not...already_failed", proc(port: Port<resource_task::ControlMsg>) { let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop { loop {
match port.recv() { match port.recv() {
resource_task::Load(_, response) => { resource_task::Load(_, response) => {
@ -741,7 +755,10 @@ mod tests {
// Our resource task should not have received another request for the image // Our resource task should not have received another request for the image
// because it's already cached // because it's already cached
assert!(image_bin_sent.try_recv().is_none()); match image_bin_sent.try_recv() {
Empty | Disconnected => (),
Data(_) => assert!(false),
}
} }
#[test] #[test]

View file

@ -126,11 +126,11 @@ impl LocalImageCache {
assert!(self.on_image_available.is_some()); assert!(self.on_image_available.is_some());
let on_image_available = self.on_image_available.as_ref().unwrap().respond(); let on_image_available = self.on_image_available.as_ref().unwrap().respond();
let url = (*url).clone(); let url = (*url).clone();
do spawn_named("LocalImageCache") { spawn_named("LocalImageCache", proc() {
let (response_port, response_chan) = Chan::new(); let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url.clone(), response_chan)); image_cache_task.send(WaitForImage(url.clone(), response_chan));
on_image_available(response_port.recv()); on_image_available(response_port.recv());
} });
} }
_ => () _ => ()
} }

View file

@ -7,12 +7,15 @@
#[feature(globs, managed_boxes)]; #[feature(globs, managed_boxes)];
extern mod geom; extern crate collections;
extern mod http; extern crate geom;
extern mod servo_util = "util"; extern crate http;
extern mod stb_image; extern crate servo_util = "util";
extern mod extra; extern crate stb_image;
extern mod png; extern crate extra;
extern crate png;
extern crate serialize;
extern crate sync;
/// Image handling. /// Image handling.
/// ///
@ -30,5 +33,4 @@ pub mod data_loader;
pub mod image_cache_task; pub mod image_cache_task;
pub mod local_image_cache; pub mod local_image_cache;
pub mod resource_task; pub mod resource_task;
pub mod util;

View file

@ -8,9 +8,9 @@ use file_loader;
use http_loader; use http_loader;
use data_loader; use data_loader;
use std::comm::{Chan, Port, SharedChan}; use std::comm::{Chan, Port};
use std::task;
use extra::url::Url; use extra::url::Url;
use util::spawn_listener;
use http::headers::content_type::MediaType; use http::headers::content_type::MediaType;
#[cfg(test)] #[cfg(test)]
@ -85,8 +85,8 @@ pub enum ProgressMsg {
/// For use by loaders in responding to a Load message. /// For use by loaders in responding to a Load message.
pub fn start_sending(start_chan: Chan<LoadResponse>, pub fn start_sending(start_chan: Chan<LoadResponse>,
metadata: Metadata) -> SharedChan<ProgressMsg> { metadata: Metadata) -> Chan<ProgressMsg> {
let (progress_port, progress_chan) = SharedChan::new(); let (progress_port, progress_chan) = Chan::new();
start_chan.send(LoadResponse { start_chan.send(LoadResponse {
metadata: metadata, metadata: metadata,
progress_port: progress_port, progress_port: progress_port,
@ -112,7 +112,7 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
} }
/// Handle to a resource task /// Handle to a resource task
pub type ResourceTask = SharedChan<ControlMsg>; pub type ResourceTask = Chan<ControlMsg>;
pub type LoaderTask = proc(url: Url, Chan<LoadResponse>); pub type LoaderTask = proc(url: Url, Chan<LoadResponse>);
@ -135,11 +135,14 @@ pub fn ResourceTask() -> ResourceTask {
} }
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask { fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
let chan = spawn_listener("ResourceManager", proc(from_client) { let (setup_port, setup_chan) = Chan::new();
// TODO: change copy to move once we can move out of closures let builder = task::task().named("ResourceManager");
ResourceManager(from_client, loaders).start() builder.spawn(proc() {
let (port, chan) = Chan::new();
setup_chan.send(chan);
ResourceManager(port, loaders).start();
}); });
chan setup_port.recv()
} }
pub struct ResourceManager { pub struct ResourceManager {

View file

@ -1,16 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 std::comm::{Chan, Port};
use servo_util::task::spawn_named;
pub fn spawn_listener<A: Send, S: IntoSendStr>(name: S, f: proc(Port<A>)) -> SharedChan<A> {
let (setup_port, setup_chan) = Chan::new();
do spawn_named(name) {
let (port, chan) = SharedChan::new();
setup_chan.send(chan);
f(port);
}
setup_port.recv()
}

View file

@ -35,7 +35,7 @@ impl AttrList {
} }
pub fn Item(&self, index: u32) -> Option<JS<Attr>> { pub fn Item(&self, index: u32) -> Option<JS<Attr>> {
self.owner.get().attrs.get_opt(index as uint).map(|x| x.clone()) self.owner.get().attrs.get(index as uint).map(|x| x.clone())
} }
pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> { pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> {

View file

@ -12,17 +12,17 @@ use std::cast;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use extra::serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
pub enum ExceptionHandling { pub enum ExceptionHandling {
// Report any exception and don't throw it to the caller code. // Report any exception and don't throw it to the caller code.
eReportExceptions, ReportExceptions,
// Throw an exception to the caller code if the thrown exception is a // Throw an exception to the caller code if the thrown exception is a
// binding object for a DOMError from the caller's scope, otherwise report // binding object for a DOMError from the caller's scope, otherwise report
// it. // it.
eRethrowContentExceptions, RethrowContentExceptions,
// Throw any exception to the caller code. // Throw any exception to the caller code.
eRethrowExceptions RethrowExceptions
} }
#[deriving(Clone,Eq)] #[deriving(Clone,Eq)]

View file

@ -184,7 +184,7 @@ class CGMethodCall(CGThing):
if requiredArgs > 0: if requiredArgs > 0:
code = ( code = (
"if (argc < %d) {\n" "if argc < %d {\n"
" return 0; //XXXjdm throw exception\n" " return 0; //XXXjdm throw exception\n"
" //return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n" " //return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n"
"}" % (requiredArgs, methodName)) "}" % (requiredArgs, methodName))
@ -370,7 +370,7 @@ class CGMethodCall(CGThing):
overloadCGThings = [] overloadCGThings = []
overloadCGThings.append( overloadCGThings.append(
CGGeneric("let argcount = argc.min(&%d);" % CGGeneric("let argcount = cmp::min(argc, %d);" %
maxArgCount)) maxArgCount))
overloadCGThings.append( overloadCGThings.append(
CGSwitch("argcount", CGSwitch("argcount",
@ -389,7 +389,7 @@ class CGMethodCall(CGThing):
class FakeCastableDescriptor(): class FakeCastableDescriptor():
def __init__(self, descriptor): def __init__(self, descriptor):
self.castable = True self.castable = True
self.nativeType = "*Box<%s>" % descriptor.concreteType self.nativeType = "*%s" % descriptor.concreteType
self.name = descriptor.name self.name = descriptor.name
class FakeInterface: class FakeInterface:
def inheritanceDepth(self): def inheritanceDepth(self):
@ -720,7 +720,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
return handleDefault(conversionCode, return handleDefault(conversionCode,
"${declName}.SetNull()") "${declName}.SetNull()")
value = "str::from_utf8(data).to_owned()" value = "str::from_utf8(data).unwrap().to_owned()"
if type.nullable(): if type.nullable():
value = "Some(%s)" % value value = "Some(%s)" % value
@ -993,7 +993,7 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
conversion = CGList( conversion = CGList(
[CGGeneric( [CGGeneric(
string.Template("if (${index} < ${argc}) {").substitute( string.Template("if ${index} < ${argc} {").substitute(
argcAndIndex argcAndIndex
)), )),
declConstruct, declConstruct,
@ -1132,7 +1132,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
raise TypeError("We don't support nullable enumerated return types " raise TypeError("We don't support nullable enumerated return types "
"yet") "yet")
return ("""assert!((%(result)s as uint) < %(strings)s.len()); return ("""assert!((%(result)s as uint) < %(strings)s.len());
let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, ptr::to_unsafe_ptr(&%(strings)s[%(result)s as u32].value[0]) as *i8, %(strings)s[%(result)s as u32].length as libc::size_t); let %(resultStr)s: *JSString = JS_NewStringCopyN(cx, &%(strings)s[%(result)s as u32].value[0] as *i8, %(strings)s[%(result)s as u32].length as libc::size_t);
if %(resultStr)s.is_null() { if %(resultStr)s.is_null() {
return 0; return 0;
} }
@ -1641,7 +1641,9 @@ class CGImports(CGWrapper):
# sometimes produces two 'break's in a row. See for example # sometimes produces two 'break's in a row. See for example
# CallbackMember.getArgConversions. # CallbackMember.getArgConversions.
'unreachable_code', 'unreachable_code',
'non_camel_case_types',
'non_uppercase_statics', 'non_uppercase_statics',
'unnecessary_parens',
'unused_imports', 'unused_imports',
'unused_variable', 'unused_variable',
'unused_unsafe', 'unused_unsafe',
@ -1688,11 +1690,11 @@ class CGNamespace(CGWrapper):
def DOMClass(descriptor): def DOMClass(descriptor):
protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain] protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain]
# Pad out the list to the right length with _ID_Count so we # Pad out the list to the right length with IDCount so we
# guarantee that all the lists are the same length. _ID_Count # guarantee that all the lists are the same length. IDCount
# is never the ID of any prototype, so it's safe to use as # is never the ID of any prototype, so it's safe to use as
# padding. # padding.
protoList.extend(['PrototypeList::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList))) protoList.extend(['PrototypeList::id::IDCount'] * (descriptor.config.maxProtoChainLength - len(protoList)))
prototypeChainString = ', '.join(protoList) prototypeChainString = ', '.join(protoList)
return """DOMClass { return """DOMClass {
interface_chain: [ %s ], interface_chain: [ %s ],
@ -2066,7 +2068,7 @@ def CreateBindingJSObject(descriptor, parent=None):
let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
""" % descriptor.name """ % descriptor.name
create += handler + """ let obj = NewProxyObject(aCx, *handler, create += handler + """ let obj = NewProxyObject(aCx, *handler,
ptr::to_unsafe_ptr(&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void)), &PrivateValue(squirrel_away_unboxed(aObject) as *libc::c_void),
proto, %s, proto, %s,
ptr::null(), ptr::null()); ptr::null(), ptr::null());
if obj.is_null() { if obj.is_null() {
@ -2084,7 +2086,7 @@ def CreateBindingJSObject(descriptor, parent=None):
} }
JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32, JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32,
PrivateValue(squirrel_away_unique(aObject) as *libc::c_void)); PrivateValue(squirrel_away_unboxed(aObject) as *libc::c_void));
""" """
return create return create
@ -2230,7 +2232,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
val = ('%(' + name + ')s') % self.properties.variableNames(False) val = ('%(' + name + ')s') % self.properties.variableNames(False)
if val == "ptr::null()": if val == "ptr::null()":
return val return val
return "ptr::to_unsafe_ptr(&%s[0])" % val return "&%s[0]" % val
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
%s, %s, %d, %s, %s, %d,
@ -2376,7 +2378,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
trace: %s trace: %s
}; };
js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint, js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint,
CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void)); CreateProxyHandler(&traps, cast::transmute(&Class)));
""" % (FINALIZE_HOOK_NAME, """ % (FINALIZE_HOOK_NAME,
('Some(%s)' % TRACE_HOOK_NAME), ('Some(%s)' % TRACE_HOOK_NAME),
@ -2388,7 +2390,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
body = "" #XXXjdm xray stuff isn't necessary yet body = "" #XXXjdm xray stuff isn't necessary yet
return (body + """ let cx = js_info.js_context.borrow().ptr; return (body + """ let cx = js_info.js_context.borrow().ptr;
let receiver = js_info.js_compartment.borrow().global_obj.borrow().ptr; let receiver = js_info.js_compartment.borrow().global_obj;
let global: *JSObject = JS_GetGlobalForObject(cx, receiver); let global: *JSObject = JS_GetGlobalForObject(cx, receiver);
return %s(cx, global, receiver).is_not_null();""" % (getter)) return %s(cx, global, receiver).is_not_null();""" % (getter))
@ -2469,7 +2471,7 @@ class CGCallGenerator(CGThing):
self.cgRoot.append(call) self.cgRoot.append(call)
if isFallible: if isFallible:
self.cgRoot.append(CGGeneric("if (result_fallible.is_err()) {")) self.cgRoot.append(CGGeneric("if result_fallible.is_err() {"))
self.cgRoot.append(CGIndenter(errorReport)) self.cgRoot.append(CGIndenter(errorReport))
self.cgRoot.append(CGGeneric("}")) self.cgRoot.append(CGGeneric("}"))
if result is not None: if result is not None:
@ -2693,7 +2695,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
" return false as JSBool;\n" " return false as JSBool;\n"
"}\n" "}\n"
"\n" "\n"
"let this: *Box<%s>;" % self.descriptor.concreteType)) "let this: *%s;" % self.descriptor.concreteType))
def generate_code(self): def generate_code(self):
assert(False) # Override me assert(False) # Override me
@ -2721,7 +2723,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
self.method = method self.method = method
name = method.identifier.name name = method.identifier.name
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'), args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'),
Argument('*mut Box<%s>' % descriptor.concreteType, 'this'), Argument('*mut %s' % descriptor.concreteType, 'this'),
Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')] Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args) CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
@ -2732,13 +2734,13 @@ class CGSpecializedMethod(CGAbstractExternMethod):
argsPre = [] argsPre = []
if name in self.descriptor.needsAbstract: if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this'] argsPre = ['&mut abstract_this']
return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(), return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(),
self.descriptor, self.method), self.descriptor, self.method),
pre=extraPre + pre=extraPre +
" let obj = (*obj.unnamed);\n" + " let obj = *obj.unnamed;\n" +
" let this = &mut (*this).data;\n").define() " let this = &mut *this;\n").define()
class CGGenericGetter(CGAbstractBindingMethod): class CGGenericGetter(CGAbstractBindingMethod):
""" """
@ -2776,7 +2778,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
name = 'get_' + attr.identifier.name name = 'get_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'), args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'), Argument('JSHandleObject', 'obj'),
Argument('*mut Box<%s>' % descriptor.concreteType, 'this'), Argument('*mut %s' % descriptor.concreteType, 'this'),
Argument('*mut JSVal', 'vp') ] Argument('*mut JSVal', 'vp') ]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -2790,15 +2792,15 @@ class CGSpecializedGetter(CGAbstractExternMethod):
getter=True)) getter=True))
if name in self.descriptor.needsAbstract: if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this'] argsPre = ['&mut abstract_this']
if self.attr.type.nullable() or not infallible: if self.attr.type.nullable() or not infallible:
nativeName = "Get" + nativeName nativeName = "Get" + nativeName
return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName, return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName,
self.descriptor, self.attr)), self.descriptor, self.attr)),
pre=extraPre + pre=extraPre +
" let obj = (*obj.unnamed);\n" + " let obj = *obj.unnamed;\n" +
" let this = &mut (*this).data;\n").define() " let this = &mut *this;\n").define()
class CGGenericSetter(CGAbstractBindingMethod): class CGGenericSetter(CGAbstractBindingMethod):
""" """
@ -2842,7 +2844,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
name = 'set_' + attr.identifier.name name = 'set_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'), args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'), Argument('JSHandleObject', 'obj'),
Argument('*mut Box<%s>' % descriptor.concreteType, 'this'), Argument('*mut %s' % descriptor.concreteType, 'this'),
Argument('*mut JSVal', 'argv')] Argument('*mut JSVal', 'argv')]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -2853,13 +2855,13 @@ class CGSpecializedSetter(CGAbstractExternMethod):
extraPre = '' extraPre = ''
if name in self.descriptor.needsAbstract: if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_box(this);\n' % abstractName extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this'] argsPre = ['&mut abstract_this']
return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName, return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName,
self.descriptor, self.attr)), self.descriptor, self.attr)),
pre=extraPre + pre=extraPre +
" let obj = (*obj.unnamed);\n" + " let obj = *obj.unnamed;\n" +
" let this = &mut (*this).data;\n").define() " let this = &mut *this;\n").define()
def infallibleForMember(member, type, descriptorProvider): def infallibleForMember(member, type, descriptorProvider):
""" """
@ -3891,8 +3893,8 @@ class CGProxyUnwrap(CGAbstractMethod):
obj = js::UnwrapObject(obj); obj = js::UnwrapObject(obj);
}*/ }*/
//MOZ_ASSERT(IsProxy(obj)); //MOZ_ASSERT(IsProxy(obj));
let box_: *Box<%s> = cast::transmute(GetProxyPrivate(obj).to_private()); let box_: *%s = cast::transmute(GetProxyPrivate(obj).to_private());
return ptr::to_unsafe_ptr(&(*box_).data);""" % (self.descriptor.concreteType) return box_;""" % (self.descriptor.concreteType)
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor): def __init__(self, descriptor):
@ -3913,7 +3915,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if indexedGetter: if indexedGetter:
readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None) readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_mut_unsafe_ptr(&mut (*desc).value)', templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut (*desc).value',
'obj': 'proxy', 'successCode': fillDescriptor} 'obj': 'proxy', 'successCode': fillDescriptor}
get = ("if index.is_some() {\n" + get = ("if index.is_some() {\n" +
" let index = index.unwrap();\n" + " let index = index.unwrap();\n" +
@ -3955,7 +3957,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if namedGetter: if namedGetter:
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None) readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_unsafe_ptr(&(*desc).value)', templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut(*desc).value',
'obj': 'proxy', 'successCode': fillDescriptor} 'obj': 'proxy', 'successCode': fillDescriptor}
# Once we start supporting OverrideBuiltins we need to make # Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named # ResolveOwnProperty or EnumerateOwnProperties filter out named
@ -4101,7 +4103,7 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
getFromExpando = """let expando = GetExpandoObject(proxy); getFromExpando = """let expando = GetExpandoObject(proxy);
if expando.is_not_null() { if expando.is_not_null() {
let hasProp = 0; let hasProp = 0;
if JS_HasPropertyById(cx, expando, id, ptr::to_unsafe_ptr(&hasProp)) == 0 { if JS_HasPropertyById(cx, expando, id, &hasProp) == 0 {
return 0; return 0;
} }
@ -4201,7 +4203,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def definition_body_prologue(self): def definition_body_prologue(self):
return """ return """
let this: *%s = &(*unwrap::<*Box<%s>>(obj)).data; let this: *%s = unwrap::<*%s>(obj);
""" % (self.descriptor.concreteType, self.descriptor.concreteType) """ % (self.descriptor.concreteType, self.descriptor.concreteType)
def definition_body(self): def definition_body(self):
@ -4407,7 +4409,7 @@ class CGNamespacedEnum(CGThing):
entries.append(entry) entries.append(entry)
# Append a Count. # Append a Count.
entries.append('_' + enumName + '_Count = ' + str(len(entries))) entries.append(enumName + 'Count = ' + str(len(entries)))
# Indent. # Indent.
entries = [' ' + e for e in entries] entries = [' ' + e for e in entries]
@ -4537,7 +4539,7 @@ class CGDictionary(CGThing):
"\n" "\n"
" pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n" " pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n"
" unsafe {\n" " unsafe {\n"
" if (!initedIds && !self.InitIds(cx)) {\n" " if !initedIds && !self.InitIds(cx) {\n"
" return 0;\n" " return 0;\n"
" }\n" " }\n"
"${initParent}" "${initParent}"
@ -4604,15 +4606,15 @@ class CGDictionary(CGThing):
if True: #XXXjdm hack until 'static mut' exists for global jsids if True: #XXXjdm hack until 'static mut' exists for global jsids
propName = member.identifier.name propName = member.identifier.name
propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&found)) })' % propCheck = ('"%s".to_c_str().with_ref(|s| { JS_HasProperty(cx, val.to_object(), s, &found) })' %
propName) propName)
propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, val.to_object(), s, ptr::to_unsafe_ptr(&temp)) })' % propGet = ('"%s".to_c_str().with_ref(|s| { JS_GetProperty(cx, val.to_object(), s, &temp) })' %
propName) propName)
else: else:
propId = self.makeIdName(member.identifier.name); propId = self.makeIdName(member.identifier.name);
propCheck = ("JS_HasPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&found))" % propCheck = ("JS_HasPropertyById(cx, val.to_object(), %s, &found)" %
propId) propId)
propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&temp))" % propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, &temp)" %
propId) propId)
conversionReplacements = { conversionReplacements = {
@ -4796,7 +4798,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{NativePropertyHooks}', 'dom::bindings::utils::{NativePropertyHooks}',
'dom::bindings::utils::global_object_for_js_object', 'dom::bindings::utils::global_object_for_js_object',
'dom::bindings::utils::{Reflectable}', 'dom::bindings::utils::{Reflectable}',
'dom::bindings::utils::{squirrel_away_unique}', 'dom::bindings::utils::{squirrel_away_unboxed}',
'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
'dom::bindings::utils::{unwrap_object, VoidVal, with_gc_disabled}', 'dom::bindings::utils::{unwrap_object, VoidVal, with_gc_disabled}',
'dom::bindings::utils::{with_gc_enabled, XrayResolveProperty}', 'dom::bindings::utils::{with_gc_enabled, XrayResolveProperty}',
@ -4818,12 +4820,13 @@ class CGBindingRoot(CGThing):
'servo_util::str::DOMString', 'servo_util::str::DOMString',
'servo_util::vec::zip_copies', 'servo_util::vec::zip_copies',
'std::cast', 'std::cast',
'std::cmp',
'std::libc', 'std::libc',
'std::ptr', 'std::ptr',
'std::vec', 'std::vec',
'std::str', 'std::str',
'std::num', 'std::num',
'std::unstable::raw::Box', 'std::intrinsics::uninit',
]) ])
# Add the auto-generated comment. # Add the auto-generated comment.
@ -5223,7 +5226,7 @@ class CGCallback(CGClass):
# method, insert our optional argument for deciding whether the # method, insert our optional argument for deciding whether the
# CallSetup should re-throw exceptions on aRv. # CallSetup should re-throw exceptions on aRv.
args.append(Argument("ExceptionHandling", "aExceptionHandling", args.append(Argument("ExceptionHandling", "aExceptionHandling",
"eReportExceptions")) "ReportExceptions"))
args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default) args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default)
method.args[2] = args[0] method.args[2] = args[0]
@ -5515,7 +5518,7 @@ class CallbackMember(CGNativeMember):
args.append(Argument("JSCompartment*", "aCompartment", "nullptr")) args.append(Argument("JSCompartment*", "aCompartment", "nullptr"))
else: else:
args.append(Argument("ExceptionHandling", "aExceptionHandling", args.append(Argument("ExceptionHandling", "aExceptionHandling",
"eReportExceptions")) "ReportExceptions"))
return args return args
# We want to allow the caller to pass in a "this" object, as # We want to allow the caller to pass in a "this" object, as
# well as a JSContext. # well as a JSContext.
@ -5530,7 +5533,7 @@ class CallbackMember(CGNativeMember):
if self.rethrowContentException: if self.rethrowContentException:
# getArgs doesn't add the aExceptionHandling argument but does add # getArgs doesn't add the aExceptionHandling argument but does add
# aCompartment for us. # aCompartment for us.
callSetup += ", eRethrowContentExceptions, aCompartment" callSetup += ", RethrowContentExceptions, aCompartment"
else: else:
callSetup += ", aExceptionHandling" callSetup += ", aExceptionHandling"
callSetup += ");" callSetup += ");"
@ -5767,7 +5770,7 @@ class GlobalGenRoots():
CGGeneric("use dom::types::*;\n"), CGGeneric("use dom::types::*;\n"),
CGGeneric("use dom::bindings::js::JS;\n"), CGGeneric("use dom::bindings::js::JS;\n"),
CGGeneric("use dom::bindings::trace::Traceable;\n"), CGGeneric("use dom::bindings::trace::Traceable;\n"),
CGGeneric("use extra::serialize::{Encodable, Encoder};\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n")] CGGeneric("use js::jsapi::JSTracer;\n\n")]
for descriptor in descriptors: for descriptor in descriptors:
name = descriptor.name name = descriptor.name

View file

@ -7,7 +7,7 @@ use js::jsapi::{JS_IsExceptionPending};
use js::glue::{ReportError}; use js::glue::{ReportError};
#[deriving(ToStr)] #[deriving(Show)]
pub enum Error { pub enum Error {
FailureUnknown, FailureUnknown,
NotFound, NotFound,

View file

@ -9,7 +9,6 @@ use layout_interface::TrustedNodeAddress;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::unstable::raw::Box;
pub struct JS<T> { pub struct JS<T> {
priv ptr: RefCell<*mut T> priv ptr: RefCell<*mut T>
@ -50,13 +49,6 @@ impl<T: Reflectable> JS<T> {
} }
pub unsafe fn from_box(box_: *mut Box<T>) -> JS<T> {
let raw: *mut T = &mut (*box_).data;
JS {
ptr: RefCell::new(raw)
}
}
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> { pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
JS { JS {
ptr: RefCell::new(inner as *mut T) ptr: RefCell::new(inner as *mut T)

View file

@ -19,12 +19,10 @@ use std::ptr;
use std::str; use std::str;
use std::mem::size_of; use std::mem::size_of;
type c_bool = libc::c_int;
static JSPROXYSLOT_EXPANDO: u32 = 0; static JSPROXYSLOT_EXPANDO: u32 = 0;
pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid, pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool { set: libc::c_int, desc: *mut JSPropertyDescriptor) -> libc::c_int {
unsafe { unsafe {
let handler = GetProxyHandler(proxy); let handler = GetProxyHandler(proxy);
if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) == 0 { if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) == 0 {

View file

@ -11,7 +11,7 @@ use std::cast;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use std::ptr::null; use std::ptr::null;
use extra::serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
// IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using // IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using
// any encoder but JSTracer. Since we derive trace hooks automatically, // any encoder but JSTracer. Since we derive trace hooks automatically,

View file

@ -8,16 +8,15 @@ use dom::bindings::js::JS;
use dom::window; use dom::window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use collections::hashmap::HashMap;
use std::libc::c_uint; use std::libc::c_uint;
use std::cast; use std::cast;
use std::cmp::Eq; use std::cmp::Eq;
use std::hashmap::HashMap;
use std::libc; use std::libc;
use std::ptr; use std::ptr;
use std::ptr::null; use std::ptr::null;
use std::str; use std::str;
use std::vec; use std::vec;
use std::unstable::raw::Box;
use js::glue::*; use js::glue::*;
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily}; use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction}; use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
@ -121,10 +120,10 @@ pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_d
pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject, pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject,
proto_id: PrototypeList::id::ID, proto_id: PrototypeList::id::ID,
proto_depth: uint) -> Result<JS<T>, ()> { proto_depth: uint) -> Result<JS<T>, ()> {
let result: Result<*mut Box<T>, ()> = unwrap_object(obj, proto_id, proto_depth); let result: Result<*mut T, ()> = unwrap_object(obj, proto_id, proto_depth);
result.map(|unwrapped| { result.map(|unwrapped| {
unsafe { unsafe {
JS::from_box(unwrapped) JS::from_raw(unwrapped)
} }
}) })
} }
@ -136,10 +135,6 @@ pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth
} }
} }
pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *Box<T> {
cast::transmute(x)
}
pub unsafe fn squirrel_away_unboxed<T>(x: ~T) -> *T { pub unsafe fn squirrel_away_unboxed<T>(x: ~T) -> *T {
cast::transmute(x) cast::transmute(x)
} }
@ -149,7 +144,7 @@ pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString {
let length = 0; let length = 0;
let chars = JS_GetStringCharsAndLength(cx, s, &length); let chars = JS_GetStringCharsAndLength(cx, s, &length);
vec::raw::buf_as_slice(chars, length as uint, |char_vec| { vec::raw::buf_as_slice(chars, length as uint, |char_vec| {
str::from_utf16(char_vec) str::from_utf16(char_vec).unwrap()
}) })
} }
} }
@ -412,7 +407,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: c_uint, _vp: *mut JSVa
} }
pub fn initialize_global(global: *JSObject) { pub fn initialize_global(global: *JSObject) {
let protoArray = ~([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]); let protoArray = ~([0 as *JSObject, ..PrototypeList::id::IDCount as uint]);
unsafe { unsafe {
let box_ = squirrel_away_unboxed(protoArray); let box_ = squirrel_away_unboxed(protoArray);
JS_SetReservedSlot(global, JS_SetReservedSlot(global,
@ -437,7 +432,6 @@ pub fn reflect_dom_object<T: Reflectable>
#[deriving(Eq)] #[deriving(Eq)]
pub struct Reflector { pub struct Reflector {
object: *JSObject, object: *JSObject,
force_box_layout: @int,
} }
impl Reflector { impl Reflector {
@ -455,7 +449,6 @@ impl Reflector {
pub fn new() -> Reflector { pub fn new() -> Reflector {
Reflector { Reflector {
object: ptr::null(), object: ptr::null(),
force_box_layout: @1,
} }
} }
} }
@ -470,7 +463,7 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
return true; return true;
} }
let hasProp = 0; let hasProp = 0;
if JS_HasPropertyById(cx, proto, id, ptr::to_unsafe_ptr(&hasProp)) == 0 { if JS_HasPropertyById(cx, proto, id, &hasProp) == 0 {
return false; return false;
} }
*found = hasProp != 0; *found = hasProp != 0;
@ -651,8 +644,8 @@ pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
let clasp = JS_GetClass(global); let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
// FIXME(jdm): Either don't hardcode or sanity assert prototype stuff. // FIXME(jdm): Either don't hardcode or sanity assert prototype stuff.
match unwrap_object::<*mut Box<window::Window>>(global, PrototypeList::id::Window, 1) { match unwrap_object::<*mut window::Window>(global, PrototypeList::id::Window, 1) {
Ok(win) => JS::from_box(win), Ok(win) => JS::from_raw(win),
Err(_) => fail!("found DOM global that doesn't unwrap to Window"), Err(_) => fail!("found DOM global that doesn't unwrap to Window"),
} }
} }

View file

@ -38,12 +38,12 @@ use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
use servo_util::namespace::{Namespace, Null}; use servo_util::namespace::{Namespace, Null};
use servo_util::str::DOMString; use servo_util::str::DOMString;
use collections::hashmap::HashMap;
use extra::url::{Url, from_str}; use extra::url::{Url, from_str};
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::hashmap::HashMap;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Eq,Encodable)] #[deriving(Eq,Encodable)]
pub enum IsHTMLDocument { pub enum IsHTMLDocument {
@ -341,17 +341,17 @@ impl Document {
match title_node { match title_node {
Some(ref mut title_node) => { Some(ref mut title_node) => {
for mut title_child in title_node.children() { for mut title_child in title_node.children() {
title_node.RemoveChild(&mut title_child); assert!(title_node.RemoveChild(&mut title_child).is_ok());
} }
let new_text = self.CreateTextNode(abstract_self, title.clone()); let new_text = self.CreateTextNode(abstract_self, title.clone());
title_node.AppendChild(&mut NodeCast::from(&new_text)); assert!(title_node.AppendChild(&mut NodeCast::from(&new_text)).is_ok());
}, },
None => { None => {
let mut new_title: JS<Node> = let mut new_title: JS<Node> =
NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self)); NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self));
let new_text = self.CreateTextNode(abstract_self, title.clone()); let new_text = self.CreateTextNode(abstract_self, title.clone());
new_title.AppendChild(&mut NodeCast::from(&new_text)); assert!(new_title.AppendChild(&mut NodeCast::from(&new_text)).is_ok());
head.AppendChild(&mut new_title); assert!(head.AppendChild(&mut new_title).is_ok());
}, },
} }
}); });
@ -418,9 +418,9 @@ impl Document {
match old_body { match old_body {
Some(child) => { Some(child) => {
let mut child: JS<Node> = NodeCast::from(&child); let mut child: JS<Node> = NodeCast::from(&child);
root.ReplaceChild(&mut new_body, &mut child) assert!(root.ReplaceChild(&mut new_body, &mut child).is_ok())
} }
None => root.AppendChild(&mut new_body) None => assert!(root.AppendChild(&mut new_body).is_ok())
}; };
} }
} }
@ -435,7 +435,7 @@ impl Document {
} }
let element: JS<Element> = ElementCast::to(node); let element: JS<Element> = ElementCast::to(node);
element.get().get_attribute(Null, "name").map_default(false, |attr| { element.get().get_attribute(Null, "name").map_or(false, |attr| {
attr.get().value_ref() == name attr.get().value_ref() == name
}) })
}) })

View file

@ -10,7 +10,7 @@ use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
#[repr(uint)] #[repr(uint)]
#[deriving(ToStr, Encodable)] #[deriving(Show, Encodable)]
enum DOMErrorName { enum DOMErrorName {
IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR, IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR,
HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR, HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR,

View file

@ -72,18 +72,18 @@ impl DOMImplementation {
{ {
// Step 3. // Step 3.
let doc_type = DocumentType::new(~"html", None, None, &doc); let doc_type = DocumentType::new(~"html", None, None, &doc);
doc_node.AppendChild(&mut NodeCast::from(&doc_type)); assert!(doc_node.AppendChild(&mut NodeCast::from(&doc_type)).is_ok());
} }
{ {
// Step 4. // Step 4.
let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc)); let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc));
doc_node.AppendChild(&mut doc_html); assert!(doc_node.AppendChild(&mut doc_html).is_ok());
{ {
// Step 5. // Step 5.
let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc)); let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc));
doc_html.AppendChild(&mut doc_head); assert!(doc_html.AppendChild(&mut doc_head).is_ok());
// Step 6. // Step 6.
match title { match title {
@ -91,18 +91,18 @@ impl DOMImplementation {
Some(title_str) => { Some(title_str) => {
// Step 6.1. // Step 6.1.
let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc)); let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc));
doc_head.AppendChild(&mut doc_title); assert!(doc_head.AppendChild(&mut doc_title).is_ok());
// Step 6.2. // Step 6.2.
let title_text = Text::new(title_str, &doc); let title_text = Text::new(title_str, &doc);
doc_title.AppendChild(&mut NodeCast::from(&title_text)); assert!(doc_title.AppendChild(&mut NodeCast::from(&title_text)).is_ok());
} }
} }
} }
// Step 7. // Step 7.
let doc_body = HTMLBodyElement::new(~"body", &doc); let doc_body = HTMLBodyElement::new(~"body", &doc);
doc_html.AppendChild(&mut NodeCast::from(&doc_body)); assert!(doc_html.AppendChild(&mut NodeCast::from(&doc_body)).is_ok());
} }
// Step 8. // Step 8.

View file

@ -203,9 +203,9 @@ impl Element {
let (prefix, local_name) = get_attribute_parts(name.clone()); let (prefix, local_name) = get_attribute_parts(name.clone());
match prefix { match prefix {
Some(ref prefix_str) => { Some(ref prefix_str) => {
if (namespace == namespace::Null || if namespace == namespace::Null ||
("xml" == prefix_str.as_slice() && namespace != namespace::XML) || ("xml" == prefix_str.as_slice() && namespace != namespace::XML) ||
("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS)) { ("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS) {
return Err(NamespaceError); return Err(NamespaceError);
} }
}, },
@ -410,7 +410,7 @@ impl Element {
pub fn set_string_attribute(&mut self, abstract_self: &JS<Element>, pub fn set_string_attribute(&mut self, abstract_self: &JS<Element>,
name: &str, value: DOMString) { name: &str, value: DOMString) {
assert!(name == name.to_ascii_lower()); assert!(name == name.to_ascii_lower());
self.set_attribute(abstract_self, Null, name.to_owned(), value); assert!(self.set_attribute(abstract_self, Null, name.to_owned(), value).is_ok());
} }
} }

View file

@ -6,7 +6,7 @@ use dom::bindings::codegen::EventBinding;
use dom::bindings::codegen::EventBinding::EventConstants; use dom::bindings::codegen::EventBinding::EventConstants;
use dom::bindings::js::JS; use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::error::Fallible;
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
@ -24,10 +24,10 @@ pub enum Event_ {
#[deriving(Encodable)] #[deriving(Encodable)]
pub enum EventPhase { pub enum EventPhase {
Phase_None = EventConstants::NONE, PhaseNone = EventConstants::NONE,
Phase_Capturing = EventConstants::CAPTURING_PHASE, PhaseCapturing = EventConstants::CAPTURING_PHASE,
Phase_At_Target = EventConstants::AT_TARGET, PhaseAtTarget = EventConstants::AT_TARGET,
Phase_Bubbling = EventConstants::BUBBLING_PHASE, PhaseBubbling = EventConstants::BUBBLING_PHASE,
} }
#[deriving(Eq, Encodable)] #[deriving(Eq, Encodable)]
@ -63,7 +63,7 @@ impl Event {
reflector_: Reflector::new(), reflector_: Reflector::new(),
current_target: None, current_target: None,
target: None, target: None,
phase: Phase_None, phase: PhaseNone,
type_: ~"", type_: ~"",
default_prevented: false, default_prevented: false,
cancelable: true, cancelable: true,
@ -132,12 +132,11 @@ impl Event {
pub fn InitEvent(&mut self, pub fn InitEvent(&mut self,
type_: DOMString, type_: DOMString,
bubbles: bool, bubbles: bool,
cancelable: bool) -> ErrorResult { cancelable: bool) {
self.type_ = type_; self.type_ = type_;
self.cancelable = cancelable; self.cancelable = cancelable;
self.bubbles = bubbles; self.bubbles = bubbles;
self.initialized = true; self.initialized = true;
Ok(())
} }
pub fn IsTrusted(&self) -> bool { pub fn IsTrusted(&self) -> bool {

View file

@ -2,11 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::callback::eReportExceptions; use dom::bindings::callback::ReportExceptions;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
use dom::bindings::js::JS; use dom::bindings::js::JS;
use dom::eventtarget::{Capturing, Bubbling, EventTarget}; use dom::eventtarget::{Capturing, Bubbling, EventTarget};
use dom::event::{Event, Phase_At_Target, Phase_None, Phase_Bubbling, Phase_Capturing}; use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing};
use dom::node::{Node, NodeHelpers}; use dom::node::{Node, NodeHelpers};
// See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm // See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
@ -35,7 +35,7 @@ pub fn dispatch_event(target: &JS<EventTarget>,
} }
} }
event.get_mut().phase = Phase_Capturing; event.get_mut().phase = PhaseCapturing;
//FIXME: The "callback this value" should be currentTarget //FIXME: The "callback this value" should be currentTarget
@ -45,7 +45,9 @@ pub fn dispatch_event(target: &JS<EventTarget>,
Some(listeners) => { Some(listeners) => {
event.get_mut().current_target = Some(cur_target.clone()); event.get_mut().current_target = Some(cur_target.clone());
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); //FIXME: this should have proper error handling, or explicitly
// drop the exception on the floor
assert!(listener.HandleEvent__(event, ReportExceptions).is_ok());
if event.get().stop_immediate { if event.get().stop_immediate {
break; break;
@ -66,14 +68,16 @@ pub fn dispatch_event(target: &JS<EventTarget>,
if !event.get().stop_propagation { if !event.get().stop_propagation {
{ {
let event = event.get_mut(); let event = event.get_mut();
event.phase = Phase_At_Target; event.phase = PhaseAtTarget;
event.current_target = Some(target.clone()); event.current_target = Some(target.clone());
} }
let opt_listeners = target.get().get_listeners(type_); let opt_listeners = target.get().get_listeners(type_);
for listeners in opt_listeners.iter() { for listeners in opt_listeners.iter() {
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); //FIXME: this should have proper error handling, or explicitly drop the
// exception on the floor.
assert!(listener.HandleEvent__(event, ReportExceptions).is_ok());
if event.get().stop_immediate { if event.get().stop_immediate {
break; break;
} }
@ -83,14 +87,16 @@ pub fn dispatch_event(target: &JS<EventTarget>,
/* bubbling */ /* bubbling */
if event.get().bubbles && !event.get().stop_propagation { if event.get().bubbles && !event.get().stop_propagation {
event.get_mut().phase = Phase_Bubbling; event.get_mut().phase = PhaseBubbling;
for cur_target in chain.iter() { for cur_target in chain.iter() {
let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) { let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) {
Some(listeners) => { Some(listeners) => {
event.get_mut().current_target = Some(cur_target.clone()); event.get_mut().current_target = Some(cur_target.clone());
for listener in listeners.iter() { for listener in listeners.iter() {
listener.HandleEvent__(event, eReportExceptions); //FIXME: this should have proper error handling or explicitly
// drop exceptions on the floor.
assert!(listener.HandleEvent__(event, ReportExceptions).is_ok());
if event.get().stop_immediate { if event.get().stop_immediate {
break; break;
@ -109,7 +115,7 @@ pub fn dispatch_event(target: &JS<EventTarget>,
let event = event.get_mut(); let event = event.get_mut();
event.dispatching = false; event.dispatching = false;
event.phase = Phase_None; event.phase = PhaseNone;
event.current_target = None; event.current_target = None;
!event.DefaultPrevented() !event.DefaultPrevented()

View file

@ -11,7 +11,7 @@ use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId; use dom::node::NodeTypeId;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::hashmap::HashMap; use collections::hashmap::HashMap;
#[deriving(Eq,Encodable)] #[deriving(Eq,Encodable)]
pub enum ListenerPhase { pub enum ListenerPhase {

View file

@ -11,7 +11,7 @@ use dom::htmlformelement::HTMLFormElement;
use dom::window::Window; use dom::window::Window;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use std::hashmap::HashMap; use collections::hashmap::HashMap;
#[deriving(Encodable)] #[deriving(Encodable)]
enum FormDatum { enum FormDatum {

View file

@ -15,9 +15,9 @@ use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::url::Url; use extra::url::Url;
use serialize::{Encoder, Encodable};
use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_msg::constellation_msg::{PipelineId, SubpageId};
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use extra::serialize::{Encoder, Encodable};
enum SandboxAllowance { enum SandboxAllowance {
AllowNothing = 0x00, AllowNothing = 0x00,

View file

@ -19,7 +19,7 @@ use servo_net::image_cache_task;
use servo_util::url::parse_url; use servo_util::url::parse_url;
use servo_util::str::DOMString; use servo_util::str::DOMString;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Encodable)] #[deriving(Encodable)]
pub struct HTMLImageElement { pub struct HTMLImageElement {
@ -120,8 +120,7 @@ impl HTMLImageElement {
pub fn SetSrc(&mut self, abstract_self: &JS<HTMLImageElement>, src: DOMString) -> ErrorResult { pub fn SetSrc(&mut self, abstract_self: &JS<HTMLImageElement>, src: DOMString) -> ErrorResult {
let node = &mut self.htmlelement.element; let node = &mut self.htmlelement.element;
node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone()); node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone())
Ok(())
} }
pub fn CrossOrigin(&self) -> DOMString { pub fn CrossOrigin(&self) -> DOMString {
@ -164,8 +163,7 @@ impl HTMLImageElement {
pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult { pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult {
let mut elem: JS<Element> = ElementCast::from(abstract_self); let mut elem: JS<Element> = ElementCast::from(abstract_self);
let mut elem_clone = elem.clone(); let mut elem_clone = elem.clone();
elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str()); elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str())
Ok(())
} }
pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 {
@ -184,8 +182,7 @@ impl HTMLImageElement {
pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) -> ErrorResult { pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) -> ErrorResult {
let node = &mut self.htmlelement.element; let node = &mut self.htmlelement.element;
node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str()); node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str())
Ok(())
} }
pub fn NaturalWidth(&self) -> u32 { pub fn NaturalWidth(&self) -> u32 {

View file

@ -25,7 +25,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
for node in *iterator { for node in *iterator {
while open_elements.len() > iterator.depth { while open_elements.len() > iterator.depth {
html.push_str(~"</" + open_elements.pop() + ">"); html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
} }
html.push_str( html.push_str(
match node.type_id() { match node.type_id() {
@ -59,7 +59,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
); );
} }
while open_elements.len() > 0 { while open_elements.len() > 0 {
html.push_str(~"</" + open_elements.pop() + ">"); html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
} }
html html
} }

View file

@ -12,7 +12,7 @@ use servo_util::str::DOMString;
use script_task::{Page}; use script_task::{Page};
use std::rc::Rc; use std::rc::Rc;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
#[deriving(Encodable)] #[deriving(Encodable)]

View file

@ -5,7 +5,7 @@
use dom::bindings::codegen::MouseEventBinding; use dom::bindings::codegen::MouseEventBinding;
use dom::bindings::codegen::InheritTypes::MouseEventDerived; use dom::bindings::codegen::InheritTypes::MouseEventDerived;
use dom::bindings::js::JS; use dom::bindings::js::JS;
use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Fallible;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, MouseEventTypeId}; use dom::event::{Event, MouseEventTypeId};
use dom::eventtarget::EventTarget; use dom::eventtarget::EventTarget;
@ -135,7 +135,7 @@ impl MouseEvent {
shiftKeyArg: bool, shiftKeyArg: bool,
metaKeyArg: bool, metaKeyArg: bool,
buttonArg: u16, buttonArg: u16,
relatedTargetArg: Option<JS<EventTarget>>) -> ErrorResult { relatedTargetArg: Option<JS<EventTarget>>) {
self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
self.screen_x = screenXArg; self.screen_x = screenXArg;
self.screen_y = screenYArg; self.screen_y = screenYArg;
@ -147,7 +147,6 @@ impl MouseEvent {
self.meta_key = metaKeyArg; self.meta_key = metaKeyArg;
self.button = buttonArg; self.button = buttonArg;
self.related_target = relatedTargetArg; self.related_target = relatedTargetArg;
Ok(())
} }
} }

View file

@ -37,11 +37,9 @@ use std::cast;
use std::cell::{RefCell, Ref, RefMut}; use std::cell::{RefCell, Ref, RefMut};
use std::iter::{Map, Filter}; use std::iter::{Map, Filter};
use std::libc::uintptr_t; use std::libc::uintptr_t;
use std::ptr; use std::mem;
use std::unstable::raw::Box;
use std::util;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
// //
// The basic Node structure // The basic Node structure
@ -562,8 +560,8 @@ impl NodeHelpers for JS<Node> {
if object.is_null() { if object.is_null() {
fail!("Attempted to create a `JS<Node>` from an invalid pointer!") fail!("Attempted to create a `JS<Node>` from an invalid pointer!")
} }
let boxed_node: *mut Box<Node> = utils::unwrap(object); let boxed_node: *mut Node = utils::unwrap(object);
JS::from_box(boxed_node) JS::from_raw(boxed_node)
} }
} }
@ -734,6 +732,8 @@ enum CloneChildrenFlag {
DoNotCloneChildren DoNotCloneChildren
} }
fn as_uintptr<T>(t: &T) -> uintptr_t { t as *T as uintptr_t }
impl Node { impl Node {
pub fn ancestors(&self) -> AncestorIterator { pub fn ancestors(&self) -> AncestorIterator {
AncestorIterator { AncestorIterator {
@ -806,11 +806,14 @@ impl Node {
/// Sends layout data, if any, back to the script task to be destroyed. /// Sends layout data, if any, back to the script task to be destroyed.
pub unsafe fn reap_layout_data(&mut self) { pub unsafe fn reap_layout_data(&mut self) {
if self.layout_data.is_present() { if self.layout_data.is_present() {
let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::new()); let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new());
let layout_chan = layout_data.take_chan(); let layout_chan = layout_data.take_chan();
match layout_chan { match layout_chan {
None => {} None => {}
Some(chan) => chan.send(ReapLayoutDataMsg(layout_data)), Some(chan) => {
let LayoutChan(chan) = chan;
chan.send(ReapLayoutDataMsg(layout_data))
},
} }
} }
} }
@ -943,11 +946,10 @@ impl Node {
CommentNodeTypeId | CommentNodeTypeId |
TextNodeTypeId | TextNodeTypeId |
ProcessingInstructionNodeTypeId => { ProcessingInstructionNodeTypeId => {
self.SetTextContent(abstract_self, val); self.SetTextContent(abstract_self, val)
} }
_ => {} _ => Ok(())
} }
Ok(())
} }
// http://dom.spec.whatwg.org/#dom-node-textcontent // http://dom.spec.whatwg.org/#dom-node-textcontent
@ -1268,7 +1270,7 @@ impl Node {
// http://dom.spec.whatwg.org/#concept-node-remove // http://dom.spec.whatwg.org/#concept-node-remove
fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) { fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) {
assert!(node.parent_node().map_default(false, |ref node_parent| node_parent == parent)); assert!(node.parent_node().map_or(false, |ref node_parent| node_parent == parent));
// Step 1-5: ranges. // Step 1-5: ranges.
// Step 6-7: mutation observers. // Step 6-7: mutation observers.
@ -1564,7 +1566,7 @@ impl Node {
match prev_text { match prev_text {
Some(ref text_node) => { Some(ref text_node) => {
let mut prev_characterdata: JS<CharacterData> = CharacterDataCast::to(text_node); let mut prev_characterdata: JS<CharacterData> = CharacterDataCast::to(text_node);
prev_characterdata.get_mut().AppendData(characterdata.get().Data()); let _ = prev_characterdata.get_mut().AppendData(characterdata.get().Data());
abstract_self.remove_child(&mut child); abstract_self.remove_child(&mut child);
}, },
None => prev_text = Some(child) None => prev_text = Some(child)
@ -1685,15 +1687,18 @@ impl Node {
} }
if lastself != lastother { if lastself != lastother {
let random = if ptr::to_unsafe_ptr(abstract_self.get()) < ptr::to_unsafe_ptr(other.get()) { let abstract_uint: uintptr_t = as_uintptr(&abstract_self.get());
let other_uint: uintptr_t = as_uintptr(&other.get());
let random = if abstract_uint < other_uint {
NodeConstants::DOCUMENT_POSITION_FOLLOWING NodeConstants::DOCUMENT_POSITION_FOLLOWING
} else { } else {
NodeConstants::DOCUMENT_POSITION_PRECEDING NodeConstants::DOCUMENT_POSITION_PRECEDING
}; };
// step 3. // step 3.
return random + return random +
NodeConstants::DOCUMENT_POSITION_DISCONNECTED + NodeConstants::DOCUMENT_POSITION_DISCONNECTED +
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
} }
for child in lastself.traverse_preorder() { for child in lastself.traverse_preorder() {

View file

@ -44,6 +44,7 @@ interface Document : Node {
partial interface Document { partial interface Document {
[SetterThrows] [SetterThrows]
attribute DOMString title; attribute DOMString title;
[SetterThrows]
attribute HTMLElement? body; attribute HTMLElement? body;
readonly attribute HTMLHeadElement? head; readonly attribute HTMLHeadElement? head;
NodeList getElementsByName(DOMString elementName); NodeList getElementsByName(DOMString elementName);

View file

@ -33,7 +33,6 @@ interface Event {
readonly attribute boolean isTrusted; readonly attribute boolean isTrusted;
readonly attribute DOMTimeStamp timeStamp; readonly attribute DOMTimeStamp timeStamp;
[Throws]
void initEvent(DOMString type, boolean bubbles, boolean cancelable); void initEvent(DOMString type, boolean bubbles, boolean cancelable);
}; };

View file

@ -23,7 +23,6 @@ interface MouseEvent : UIEvent {
readonly attribute unsigned short buttons; readonly attribute unsigned short buttons;
readonly attribute EventTarget? relatedTarget; readonly attribute EventTarget? relatedTarget;
// Deprecated in DOM Level 3: // Deprecated in DOM Level 3:
[Throws]
void initMouseEvent(DOMString typeArg, void initMouseEvent(DOMString typeArg,
boolean canBubbleArg, boolean canBubbleArg,
boolean cancelableArg, boolean cancelableArg,

View file

@ -25,22 +25,22 @@ use js::jsval::JSVal;
use js::jsval::{NullValue, ObjectValue}; use js::jsval::{NullValue, ObjectValue};
use js::JSPROP_ENUMERATE; use js::JSPROP_ENUMERATE;
use collections::hashmap::HashSet;
use std::cast; use std::cast;
use std::comm::SharedChan; use std::cmp;
use std::comm::Chan;
use std::comm::Select; use std::comm::Select;
use std::hashmap::HashSet; use std::hash::{Hash, sip};
use std::io::timer::Timer; use std::io::timer::Timer;
use std::num;
use std::rc::Rc; use std::rc::Rc;
use std::to_bytes::Cb;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
use extra::url::{Url}; use extra::url::{Url};
pub enum TimerControlMsg { pub enum TimerControlMsg {
TimerMessage_Fire(~TimerData), TimerMessageFire(~TimerData),
TimerMessage_Close, TimerMessageClose,
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the script task TimerMessageTriggerExit //XXXjdm this is just a quick hack to talk to the script task
} }
pub struct TimerHandle { pub struct TimerHandle {
@ -53,9 +53,9 @@ impl<S: Encoder> Encodable<S> for TimerHandle {
} }
} }
impl IterBytes for TimerHandle { impl Hash for TimerHandle {
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { fn hash(&self, state: &mut sip::SipState) {
self.handle.iter_bytes(lsb0, f) self.handle.hash(state);
} }
} }
@ -87,7 +87,7 @@ pub struct Window {
struct Untraceable { struct Untraceable {
page: Rc<Page>, page: Rc<Page>,
compositor: ~ScriptListener, compositor: ~ScriptListener,
timer_chan: SharedChan<TimerControlMsg>, timer_chan: Chan<TimerControlMsg>,
} }
impl<S: Encoder> Encodable<S> for Untraceable { impl<S: Encoder> Encodable<S> for Untraceable {
@ -115,7 +115,7 @@ impl Window {
#[unsafe_destructor] #[unsafe_destructor]
impl Drop for Window { impl Drop for Window {
fn drop(&mut self) { fn drop(&mut self) {
self.extra.timer_chan.send(TimerMessage_Close); self.extra.timer_chan.send(TimerMessageClose);
for handle in self.active_timers.iter() { for handle in self.active_timers.iter() {
handle.cancel(); handle.cancel();
} }
@ -134,11 +134,11 @@ pub struct TimerData {
impl Window { impl Window {
pub fn Alert(&self, s: DOMString) { pub fn Alert(&self, s: DOMString) {
// Right now, just print to the console // Right now, just print to the console
println(format!("ALERT: {:s}", s)); println!("ALERT: {:s}", s);
} }
pub fn Close(&self) { pub fn Close(&self) {
self.extra.timer_chan.send(TimerMessage_TriggerExit); self.extra.timer_chan.send(TimerMessageTriggerExit);
} }
pub fn Document(&self) -> JS<Document> { pub fn Document(&self) -> JS<Document> {
@ -226,7 +226,7 @@ impl Reflectable for Window {
impl Window { impl Window {
pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 {
let timeout = num::max(0, timeout) as u64; let timeout = cmp::max(0, timeout) as u64;
let handle = self.next_timer_handle; let handle = self.next_timer_handle;
self.next_timer_handle += 1; self.next_timer_handle += 1;
@ -237,15 +237,17 @@ impl Window {
let chan = self.extra.timer_chan.clone(); let chan = self.extra.timer_chan.clone();
spawn_named("Window:SetTimeout", proc() { spawn_named("Window:SetTimeout", proc() {
let mut tm = tm; let mut tm = tm;
let mut timeout_port = tm.oneshot(timeout); let timeout_port = tm.oneshot(timeout);
let mut cancel_port = cancel_port; let cancel_port = cancel_port;
let select = Select::new(); let select = Select::new();
let timeout_handle = select.add(&mut timeout_port); let mut timeout_handle = select.handle(&timeout_port);
let _cancel_handle = select.add(&mut cancel_port); unsafe { timeout_handle.add() };
let mut cancel_handle = select.handle(&cancel_port);
unsafe { cancel_handle.add() };
let id = select.wait(); let id = select.wait();
if id == timeout_handle.id { if id == timeout_handle.id() {
chan.send(TimerMessage_Fire(~TimerData { chan.send(TimerMessageFire(~TimerData {
handle: handle, handle: handle,
funval: callback, funval: callback,
args: ~[], args: ~[],
@ -290,14 +292,15 @@ impl Window {
compositor: compositor, compositor: compositor,
page: page.clone(), page: page.clone(),
timer_chan: { timer_chan: {
let (timer_port, timer_chan): (Port<TimerControlMsg>, SharedChan<TimerControlMsg>) = SharedChan::new(); let (timer_port, timer_chan): (Port<TimerControlMsg>, Chan<TimerControlMsg>) = Chan::new();
let id = page.borrow().id.clone(); let id = page.borrow().id.clone();
spawn_named("timer controller", proc() { spawn_named("timer controller", proc() {
let ScriptChan(script_chan) = script_chan;
loop { loop {
match timer_port.recv() { match timer_port.recv() {
TimerMessage_Close => break, TimerMessageClose => break,
TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)), TimerMessageFire(td) => script_chan.send(FireTimerMsg(id, td)),
TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)), TimerMessageTriggerExit => script_chan.send(ExitWindowMsg(id)),
} }
} }
}); });

View file

@ -34,10 +34,11 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
resource_task.send(Load(url, input_chan)); resource_task.send(Load(url, input_chan));
let LoadResponse { metadata: metadata, progress_port: progress_port } let LoadResponse { metadata: metadata, progress_port: progress_port }
= input_port.recv(); = input_port.recv();
let final_url = &metadata.final_url;
let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice());
let iter = ProgressMsgPortIterator { progress_port: progress_port }; let iter = ProgressMsgPortIterator { progress_port: progress_port };
Stylesheet::from_bytes_iter( Stylesheet::from_bytes_iter(
iter, metadata.final_url, iter, final_url.clone(),
protocol_encoding_label, Some(environment_encoding)) protocol_encoding_label, Some(environment_encoding))
} }
InlineProvenance(base_url, data) => { InlineProvenance(base_url, data) => {

View file

@ -28,7 +28,7 @@ use servo_util::url::parse_url;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::cast; use std::cast;
use std::cell::RefCell; use std::cell::RefCell;
use std::comm::{Port, SharedChan}; use std::comm::{Port, Chan};
use std::str; use std::str;
use style::Stylesheet; use style::Stylesheet;
@ -103,7 +103,7 @@ spawned, collates them, and sends them to the given result channel.
* `from_parent` - A port on which to receive new links. * `from_parent` - A port on which to receive new links.
*/ */
fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, fn css_link_listener(to_parent: Chan<HtmlDiscoveryMessage>,
from_parent: Port<CSSMessage>, from_parent: Port<CSSMessage>,
resource_task: ResourceTask) { resource_task: ResourceTask) {
let mut result_vec = ~[]; let mut result_vec = ~[];
@ -126,7 +126,7 @@ fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
} }
} }
fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, fn js_script_listener(to_parent: Chan<HtmlDiscoveryMessage>,
from_parent: Port<JSMessage>, from_parent: Port<JSMessage>,
resource_task: ResourceTask) { resource_task: ResourceTask) {
let mut result_vec = ~[]; let mut result_vec = ~[];
@ -140,7 +140,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
} }
Ok((metadata, bytes)) => { Ok((metadata, bytes)) => {
result_vec.push(JSFile { result_vec.push(JSFile {
data: str::from_utf8(bytes).to_owned(), data: str::from_utf8(bytes).unwrap().to_owned(),
url: metadata.final_url, url: metadata.final_url,
}); });
} }
@ -256,9 +256,9 @@ pub fn parse_html(page: &Page,
// Spawn a CSS parser to receive links to CSS style sheets. // Spawn a CSS parser to receive links to CSS style sheets.
let resource_task2 = resource_task.clone(); let resource_task2 = resource_task.clone();
let (discovery_port, discovery_chan) = SharedChan::new(); let (discovery_port, discovery_chan) = Chan::new();
let stylesheet_chan = discovery_chan.clone(); let stylesheet_chan = discovery_chan.clone();
let (css_msg_port, css_chan) = SharedChan::new(); let (css_msg_port, css_chan) = Chan::new();
spawn_named("parse_html:css", proc() { spawn_named("parse_html:css", proc() {
css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone()); css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone());
}); });
@ -266,7 +266,7 @@ pub fn parse_html(page: &Page,
// Spawn a JS parser to receive JavaScript. // Spawn a JS parser to receive JavaScript.
let resource_task2 = resource_task.clone(); let resource_task2 = resource_task.clone();
let js_result_chan = discovery_chan.clone(); let js_result_chan = discovery_chan.clone();
let (js_msg_port, js_chan) = SharedChan::new(); let (js_msg_port, js_chan) = Chan::new();
spawn_named("parse_html:js", proc() { spawn_named("parse_html:js", proc() {
js_script_listener(js_result_chan, js_msg_port, resource_task2.clone()); js_script_listener(js_result_chan, js_msg_port, resource_task2.clone());
}); });
@ -303,11 +303,16 @@ pub fn parse_html(page: &Page,
let next_subpage_id = RefCell::new(next_subpage_id); let next_subpage_id = RefCell::new(next_subpage_id);
let doc_cell = RefCell::new(document);
let tree_handler = hubbub::TreeHandler { let tree_handler = hubbub::TreeHandler {
create_comment: |data: ~str| { create_comment: |data: ~str| {
debug!("create comment"); debug!("create comment");
let comment: JS<Node> = NodeCast::from(&Comment::new(data, document)); // NOTE: tmp vars are workaround for lifetime issues. Both required.
unsafe { comment.to_hubbub_node() } let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
unsafe { comment.to_hubbub_node() }
}, },
create_doctype: |doctype: ~hubbub::Doctype| { create_doctype: |doctype: ~hubbub::Doctype| {
debug!("create doctype"); debug!("create doctype");
@ -315,21 +320,29 @@ pub fn parse_html(page: &Page,
public_id: public_id, public_id: public_id,
system_id: system_id, system_id: system_id,
force_quirks: _ } = doctype; force_quirks: _ } = doctype;
let doctype_node = DocumentType::new(name, public_id, system_id, document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
unsafe { unsafe {
doctype_node.to_hubbub_node() doctype_node.to_hubbub_node()
} }
}, },
create_element: |tag: ~hubbub::Tag| { create_element: |tag: ~hubbub::Tag| {
debug!("create element"); debug!("create element");
let mut element = build_element_from_tag(tag.name.clone(), document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let mut element = build_element_from_tag(tag.name.clone(), *tmp);
debug!("-- attach attrs"); debug!("-- attach attrs");
for attr in tag.attributes.iter() { for attr in tag.attributes.iter() {
let elem = element.clone(); let elem = element.clone();
element.get_mut().set_attr(&elem, //FIXME: this should have proper error handling or explicitly drop
attr.name.clone(), // exceptions on the ground
attr.value.clone()); assert!(element.get_mut().set_attr(&elem,
attr.name.clone(),
attr.value.clone()).is_ok());
} }
// Spawn additional parsing, network loads, etc. from tag and attrs // Spawn additional parsing, network loads, etc. from tag and attrs
@ -366,7 +379,8 @@ pub fn parse_html(page: &Page,
// Subpage Id // Subpage Id
let subpage_id = next_subpage_id.get(); let subpage_id = next_subpage_id.get();
next_subpage_id.set(SubpageId(*subpage_id + 1)); let SubpageId(id_num) = subpage_id;
next_subpage_id.set(SubpageId(id_num + 1));
iframe_element.get_mut().size = Some(IFrameSize { iframe_element.get_mut().size = Some(IFrameSize {
pipeline_id: pipeline_id, pipeline_id: pipeline_id,
@ -384,7 +398,10 @@ pub fn parse_html(page: &Page,
}, },
create_text: |data: ~str| { create_text: |data: ~str| {
debug!("create text"); debug!("create text");
let text = Text::new(data, document); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = tmp_borrow.get();
let text = Text::new(data, *tmp);
unsafe { text.to_hubbub_node() } unsafe { text.to_hubbub_node() }
}, },
ref_node: |_| {}, ref_node: |_| {},
@ -394,7 +411,7 @@ pub fn parse_html(page: &Page,
debug!("append child {:x} {:x}", parent, child); debug!("append child {:x} {:x}", parent, child);
let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent); let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent);
let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child); let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child);
parent.AppendChild(&mut child); assert!(parent.AppendChild(&mut child).is_ok());
} }
child child
}, },
@ -431,11 +448,17 @@ pub fn parse_html(page: &Page,
}, },
set_quirks_mode: |mode| { set_quirks_mode: |mode| {
debug!("set quirks mode"); debug!("set quirks mode");
document.get_mut().set_quirks_mode(mode); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let tmp = tmp_borrow.get();
tmp.get_mut().set_quirks_mode(mode);
}, },
encoding_change: |encname| { encoding_change: |encname| {
debug!("encoding change"); debug!("encoding change");
document.get_mut().set_encoding_name(encname); // NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let tmp = tmp_borrow.get();
tmp.get_mut().set_encoding_name(encname);
}, },
complete_script: |script| { complete_script: |script| {
unsafe { unsafe {
@ -500,6 +523,7 @@ pub fn parse_html(page: &Page,
} }
} }
debug!("finished parsing");
css_chan.send(CSSTaskExit); css_chan.send(CSSTaskExit);
js_chan.send(JSTaskExit); js_chan.send(JSTaskExit);

View file

@ -15,7 +15,7 @@ use geom::size::Size2D;
use script_task::{ScriptChan}; use script_task::{ScriptChan};
use servo_util::geometry::Au; use servo_util::geometry::Au;
use std::cmp; use std::cmp;
use std::comm::{Chan, SharedChan}; use std::comm::Chan;
use std::libc::c_void; use std::libc::c_void;
use style::Stylesheet; use style::Stylesheet;
@ -132,11 +132,11 @@ pub struct Reflow {
/// Encapsulates a channel to the layout task. /// Encapsulates a channel to the layout task.
#[deriving(Clone)] #[deriving(Clone)]
pub struct LayoutChan(SharedChan<Msg>); pub struct LayoutChan(Chan<Msg>);
impl LayoutChan { impl LayoutChan {
pub fn new() -> (Port<Msg>, LayoutChan) { pub fn new() -> (Port<Msg>, LayoutChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, LayoutChan(chan)) (port, LayoutChan(chan))
} }
} }

View file

@ -9,12 +9,14 @@ macro_rules! bitfield(
impl $bitfieldname { impl $bitfieldname {
#[inline] #[inline]
pub fn $getter(self) -> bool { pub fn $getter(self) -> bool {
(*self & $value) != 0 let $bitfieldname(s) = self;
(s & $value) != 0
} }
#[inline] #[inline]
pub fn $setter(&mut self, value: bool) { pub fn $setter(&mut self, value: bool) {
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 })) let $bitfieldname(s) = *self;
*self = $bitfieldname((s & !$value) | (if value { $value } else { 0 }))
} }
} }
) )

View file

@ -10,16 +10,18 @@
#[feature(globs, macro_rules, struct_variant, managed_boxes)]; #[feature(globs, macro_rules, struct_variant, managed_boxes)];
extern mod geom; extern crate collections;
extern mod hubbub; extern crate geom;
extern mod encoding; extern crate hubbub;
extern mod js; extern crate encoding;
extern mod servo_net = "net"; extern crate js;
extern mod servo_util = "util"; extern crate serialize;
extern mod style; extern crate servo_net = "net";
extern mod servo_msg = "msg"; extern crate servo_util = "util";
extern mod extra; extern crate style;
extern mod native; extern crate servo_msg = "msg";
extern crate extra;
extern crate native;
// Macros // Macros
mod macros; mod macros;

View file

@ -50,13 +50,13 @@ use servo_util::task::send_on_failure;
use servo_util::namespace::Null; use servo_util::namespace::Null;
use std::cast; use std::cast;
use std::cell::{RefCell, Ref, RefMut}; use std::cell::{RefCell, Ref, RefMut};
use std::comm::{Port, SharedChan}; use std::comm::{Port, Chan, Empty, Disconnected, Data};
use std::mem::replace;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::task; use std::task;
use std::util::replace;
use extra::serialize::{Encoder, Encodable}; use serialize::{Encoder, Encodable};
/// Messages used to control the script task. /// Messages used to control the script task.
pub enum ScriptMsg { pub enum ScriptMsg {
@ -90,7 +90,7 @@ pub struct NewLayoutInfo {
/// Encapsulates external communication with the script task. /// Encapsulates external communication with the script task.
#[deriving(Clone)] #[deriving(Clone)]
pub struct ScriptChan(SharedChan<ScriptMsg>); pub struct ScriptChan(Chan<ScriptMsg>);
impl<S: Encoder> Encodable<S> for ScriptChan { impl<S: Encoder> Encodable<S> for ScriptChan {
fn encode(&self, _s: &mut S) { fn encode(&self, _s: &mut S) {
@ -100,7 +100,7 @@ impl<S: Encoder> Encodable<S> for ScriptChan {
impl ScriptChan { impl ScriptChan {
/// Creates a new script chan. /// Creates a new script chan.
pub fn new() -> (Port<ScriptMsg>, ScriptChan) { pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
let (port, chan) = SharedChan::new(); let (port, chan) = Chan::new();
(port, ScriptChan(chan)) (port, ScriptChan(chan))
} }
} }
@ -164,7 +164,7 @@ pub struct PageTreeIterator<'a> {
impl PageTree { impl PageTree {
fn new(id: PipelineId, layout_chan: LayoutChan, window_size: Size2D<uint>) -> PageTree { fn new(id: PipelineId, layout_chan: LayoutChan, window_size: Size2D<uint>) -> PageTree {
PageTree { PageTree {
page: unsafe { Rc::new_unchecked(Page { page: Rc::new(Page {
id: id, id: id,
frame: RefCell::new(None), frame: RefCell::new(None),
layout_chan: layout_chan, layout_chan: layout_chan,
@ -177,7 +177,7 @@ impl PageTree {
resize_event: RefCell::new(None), resize_event: RefCell::new(None),
fragment_node: RefCell::new(None), fragment_node: RefCell::new(None),
last_reflow_id: RefCell::new(0) last_reflow_id: RefCell::new(0)
}) }, }),
inner: ~[], inner: ~[],
} }
} }
@ -220,7 +220,7 @@ impl PageTree {
.map(|(idx, _)| idx) .map(|(idx, _)| idx)
}; };
match remove_idx { match remove_idx {
Some(idx) => return Some(self.inner.remove(idx)), Some(idx) => return Some(self.inner.remove(idx).unwrap()),
None => { None => {
for page_tree in self.inner.mut_iter() { for page_tree in self.inner.mut_iter() {
match page_tree.remove(id) { match page_tree.remove(id) {
@ -237,11 +237,9 @@ impl PageTree {
impl<'a> Iterator<Rc<Page>> for PageTreeIterator<'a> { impl<'a> Iterator<Rc<Page>> for PageTreeIterator<'a> {
fn next(&mut self) -> Option<Rc<Page>> { fn next(&mut self) -> Option<Rc<Page>> {
if !self.stack.is_empty() { if !self.stack.is_empty() {
let next = self.stack.pop(); let next = self.stack.pop().unwrap();
{ for child in next.inner.mut_iter() {
for child in next.inner.mut_iter() { self.stack.push(child);
self.stack.push(child);
}
} }
Some(next.page.clone()) Some(next.page.clone())
} else { } else {
@ -307,7 +305,7 @@ impl Page {
pub fn get_url(&self) -> Url { pub fn get_url(&self) -> Url {
let url = self.url(); let url = self.url();
url.get().get_ref().first().clone() url.get().get_ref().ref0().clone()
} }
/// Sends a ping to layout and waits for the response. The response will arrive when the /// Sends a ping to layout and waits for the response. The response will arrive when the
@ -319,11 +317,14 @@ impl Page {
match join_port { match join_port {
Some(ref join_port) => { Some(ref join_port) => {
match join_port.try_recv() { match join_port.try_recv() {
None => { Empty => {
info!("script: waiting on layout"); info!("script: waiting on layout");
join_port.recv(); join_port.recv();
} }
Some(_) => {} Data(_) => {}
Disconnected => {
fail!("Layout task failed while script was waiting for a result.");
}
} }
debug!("script: layout joined") debug!("script: layout joined")
@ -339,7 +340,8 @@ impl Page {
response_port: Port<T>) response_port: Port<T>)
-> T { -> T {
self.join_layout(); self.join_layout();
self.layout_chan.send(QueryMsg(query)); let LayoutChan(ref chan) = self.layout_chan;
chan.send(QueryMsg(query));
response_port.recv() response_port.recv()
} }
@ -397,7 +399,8 @@ impl Page {
id: *last_reflow_id.get(), id: *last_reflow_id.get(),
}; };
self.layout_chan.send(ReflowMsg(reflow)); let LayoutChan(ref chan) = self.layout_chan;
chan.send(ReflowMsg(reflow));
debug!("script: layout forked") debug!("script: layout forked")
} }
@ -493,8 +496,7 @@ impl ScriptTask {
-> Rc<ScriptTask> { -> Rc<ScriptTask> {
let js_runtime = js::rust::rt(); let js_runtime = js::rust::rt();
unsafe { Rc::new(ScriptTask {
Rc::new_unchecked(ScriptTask {
page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)), page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)),
image_cache_task: img_cache_task, image_cache_task: img_cache_task,
@ -507,8 +509,7 @@ impl ScriptTask {
js_runtime: js_runtime, js_runtime: js_runtime,
mouse_over_targets: RefCell::new(None) mouse_over_targets: RefCell::new(None)
}) })
}
} }
/// Starts the script task. After calling this method, the script task will loop receiving /// Starts the script task. After calling this method, the script task will loop receiving
@ -530,9 +531,9 @@ impl ScriptTask {
resource_task: ResourceTask, resource_task: ResourceTask,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
window_size: Size2D<uint>) { window_size: Size2D<uint>) {
let mut builder = task::task(); let mut builder = task::task().named("ScriptTask");
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone()); let ConstellationChan(const_chan) = constellation_chan.clone();
builder.name("ScriptTask"); send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
builder.spawn(proc() { builder.spawn(proc() {
let script_task = ScriptTask::new(id, let script_task = ScriptTask::new(id,
compositor as ~ScriptListener, compositor as ~ScriptListener,
@ -593,8 +594,8 @@ impl ScriptTask {
} }
match self.port.try_recv() { match self.port.try_recv() {
None => break, Empty | Disconnected => break,
Some(ev) => event = ev, Data(ev) => event = ev,
} }
} }
@ -652,7 +653,7 @@ impl ScriptTask {
let this_value = if timer_data.args.len() > 0 { let this_value = if timer_data.args.len() > 0 {
fail!("NYI") fail!("NYI")
} else { } else {
js_info.get().get_ref().js_compartment.borrow().global_obj.borrow().ptr js_info.get().get_ref().js_compartment.borrow().global_obj
}; };
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
@ -683,7 +684,8 @@ impl ScriptTask {
/// Handles a navigate forward or backward message. /// Handles a navigate forward or backward message.
/// TODO(tkuehn): is it ever possible to navigate only on a subframe? /// TODO(tkuehn): is it ever possible to navigate only on a subframe?
fn handle_navigate_msg(&self, direction: NavigationDirection) { fn handle_navigate_msg(&self, direction: NavigationDirection) {
self.constellation_chan.send(constellation_msg::NavigateMsg(direction)); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(constellation_msg::NavigateMsg(direction));
} }
/// Window was resized, but this script was not active, so don't reflow yet /// Window was resized, but this script was not active, so don't reflow yet
@ -696,7 +698,7 @@ impl ScriptTask {
let mut page_url = page.mut_url(); let mut page_url = page.mut_url();
let last_loaded_url = replace(page_url.get(), None); let last_loaded_url = replace(page_url.get(), None);
for url in last_loaded_url.iter() { for url in last_loaded_url.iter() {
*page_url.get() = Some((url.first(), true)); *page_url.get() = Some((url.ref0().clone(), true));
} }
} }
@ -823,19 +825,22 @@ impl ScriptTask {
js_scripts = Some(scripts); js_scripts = Some(scripts);
} }
Some(HtmlDiscoveredStyle(sheet)) => { Some(HtmlDiscoveredStyle(sheet)) => {
page.layout_chan.send(AddStylesheetMsg(sheet)); let LayoutChan(ref chan) = page.layout_chan;
chan.send(AddStylesheetMsg(sheet));
} }
Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, sandboxed))) => { Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, sandboxed))) => {
page.next_subpage_id.set(SubpageId(*subpage_id + 1)); let SubpageId(num) = subpage_id;
page.next_subpage_id.set(SubpageId(num + 1));
let sandboxed = if sandboxed { let sandboxed = if sandboxed {
IFrameSandboxed IFrameSandboxed
} else { } else {
IFrameUnsandboxed IFrameUnsandboxed
}; };
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url, let ConstellationChan(ref chan) = self.constellation_chan;
pipeline_id, chan.send(LoadIframeUrlMsg(iframe_url,
subpage_id, pipeline_id,
sandboxed)); subpage_id,
sandboxed));
} }
None => break None => break
} }
@ -862,7 +867,7 @@ impl ScriptTask {
let js_info = page.js_info(); let js_info = page.js_info();
let js_info = js_info.get().get_ref(); let js_info = js_info.get().get_ref();
let compartment = js_info.js_compartment.borrow(); let compartment = js_info.js_compartment.borrow();
compartment.define_functions(DEBUG_FNS); assert!(compartment.define_functions(DEBUG_FNS).is_ok());
js_info.js_context.borrow().ptr js_info.js_context.borrow().ptr
}; };
@ -873,12 +878,14 @@ impl ScriptTask {
let (cx, global_obj) = { let (cx, global_obj) = {
let js_info = page.js_info(); let js_info = page.js_info();
(js_info.get().get_ref().js_context.clone(), (js_info.get().get_ref().js_context.clone(),
js_info.get().get_ref().js_compartment.borrow().global_obj.clone()) js_info.get().get_ref().js_compartment.borrow().global_obj)
}; };
cx.borrow().evaluate_script(global_obj, //FIXME: this should have some kind of error handling, or explicitly
file.data.clone(), // drop an exception on the floor.
file.url.to_str(), assert!(cx.borrow().evaluate_script(global_obj,
1); file.data.clone(),
file.url.to_str(),
1).is_ok());
}); });
} }
@ -890,12 +897,13 @@ impl ScriptTask {
let doctarget = EventTargetCast::from(&document); let doctarget = EventTargetCast::from(&document);
let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window); let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window);
let winclone = wintarget.clone(); let winclone = wintarget.clone();
wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event);
let mut fragment_node = page.fragment_node.borrow_mut(); let mut fragment_node = page.fragment_node.borrow_mut();
*fragment_node.get() = fragment.map_default(None, |fragid| self.find_fragment_node(page, fragid)); *fragment_node.get() = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
self.constellation_chan.send(LoadCompleteMsg(page.id, url)); let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(LoadCompleteMsg(page.id, url));
} }
fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> { fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> {
@ -908,7 +916,7 @@ impl ScriptTask {
let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element()); let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element());
anchors.find(|node| { anchors.find(|node| {
let elem: JS<Element> = ElementCast::to(node); let elem: JS<Element> = ElementCast::to(node);
elem.get().get_attribute(Null, "name").map_default(false, |attr| { elem.get().get_attribute(Null, "name").map_or(false, |attr| {
attr.get().value_ref() == fragid attr.get().value_ref() == fragid
}) })
}).map(|node| ElementCast::to(&node)) }).map(|node| ElementCast::to(&node))
@ -973,7 +981,7 @@ impl ScriptTask {
// FIXME: this event should be dispatch on WindowProxy. See #1715 // FIXME: this event should be dispatch on WindowProxy. See #1715
let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window); let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window);
let winclone = wintarget.clone(); let winclone = wintarget.clone();
wintarget.get_mut().dispatch_event_with_target(&winclone, None, event); let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, None, event);
} }
None =>() None =>()
} }
@ -1121,8 +1129,9 @@ impl ScriptTask {
None => {} None => {}
} }
} else { } else {
self.constellation_chan.send(LoadUrlMsg(page.id, url)); let ConstellationChan(ref chan) = self.constellation_chan;
} chan.send(LoadUrlMsg(page.id, url));
}
} }
} }
} }
@ -1133,7 +1142,8 @@ fn shut_down_layout(page: &Page) {
// Tell the layout task to begin shutting down. // Tell the layout task to begin shutting down.
let (response_port, response_chan) = Chan::new(); let (response_port, response_chan) = Chan::new();
page.layout_chan.send(layout_interface::PrepareToExitMsg(response_chan)); let LayoutChan(ref chan) = page.layout_chan;
chan.send(layout_interface::PrepareToExitMsg(response_chan));
response_port.recv(); response_port.recv();
// Destroy all nodes. Setting frame and js_info to None will trigger our // Destroy all nodes. Setting frame and js_info to None will trigger our
@ -1149,5 +1159,5 @@ fn shut_down_layout(page: &Page) {
*js_info.get() = None; *js_info.get() = None;
// Destroy the layout task. If there were node leaks, layout will now crash safely. // Destroy the layout task. If there were node leaks, layout will now crash safely.
page.layout_chan.send(layout_interface::ExitNowMsg); chan.send(layout_interface::ExitNowMsg);
} }

View file

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[allow(non_camel_case_types)];
pub use servo_util::geometry::Au; pub use servo_util::geometry::Au;
pub type CSSFloat = f64; pub type CSSFloat = f64;

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