mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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:
commit
f7aa6e3d9b
148 changed files with 1405 additions and 1227 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -69,7 +69,7 @@
|
|||
url = https://github.com/mozilla-servo/skia.git
|
||||
[submodule "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"]
|
||||
path = src/support/alert/rust-alert
|
||||
url = https://github.com/mozilla-servo/rust-alert.git
|
||||
|
|
21
Makefile.in
21
Makefile.in
|
@ -35,18 +35,13 @@ ifdef CFG_DISABLE_OPTIMIZE
|
|||
$(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE))
|
||||
CFG_RUSTC_FLAGS +=
|
||||
else
|
||||
CFG_RUSTC_FLAGS += -O -Z no-debug-borrows
|
||||
CFG_RUSTC_FLAGS += -O
|
||||
endif
|
||||
|
||||
CFG_RUSTC_FLAGS += -g
|
||||
ifdef CFG_ENABLE_DEBUG
|
||||
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
|
||||
CFG_RUSTC_FLAGS += -Z extra-debug-info
|
||||
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
|
||||
$(info cfg: enabling more debugging in RUSTC (CFG_ENABLE_DEBUG))
|
||||
CFG_RUSTC_SELF_FLAGS += -g
|
||||
endif
|
||||
|
||||
export CFG_RUSTC
|
||||
|
@ -135,8 +130,6 @@ endif
|
|||
# their name already, while others don't.
|
||||
DONE_$(1) = $$(B)src/$$(PATH_$(1))/lib*.dummy
|
||||
DEPS_SUBMODULES += $$(PATH_$(1))
|
||||
DEPS_SUBMODULES += $$(PATH_$(1))/.libs
|
||||
DEPS_SUBMODULES += $$(PATH_$(1))/src/.libs
|
||||
endef
|
||||
|
||||
# these will get populated.
|
||||
|
@ -163,7 +156,7 @@ endef
|
|||
define DEF_SUBMODULE_RULES
|
||||
|
||||
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!
|
||||
ENV_CFLAGS_$(1) = CFLAGS="$$(CFLAGS_$(1))"
|
||||
|
@ -329,11 +322,11 @@ $(BINDINGS_SRC)/ParserResults.pkl: $(globalgen_dependencies) \
|
|||
ifneq ($(CFG_OSTYPE),linux-androideabi)
|
||||
servo: $(DEPS_servo)
|
||||
@$(call E, compile: $@)
|
||||
$(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $< --bin
|
||||
$(Q)$(RUSTC) $(RFLAGS_servo) -o $@ $<
|
||||
else
|
||||
servo: $(DEPS_servo)
|
||||
@$(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
|
||||
|
||||
# Darwin app packaging
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -385,7 +385,7 @@ case ${TARGET_OSTYPE} in
|
|||
probe CFG_RANLIB arm-linux-androideabi-ranlib
|
||||
|
||||
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
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d3b3c66a3a54a0455b068ede8fe2f48ed99ca908
|
||||
Subproject commit 68a4f7d9babb0c638f3425ced08e13f9fbfdcf56
|
|
@ -1,4 +1,4 @@
|
|||
# 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
|
||||
# build bots then the contents should be changed so git updates the mtime.
|
||||
2014-01-08
|
||||
2014-02-24
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
* 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 collections::hashmap::HashMap;
|
||||
use geom::size::Size2D;
|
||||
use layers::platform::surface::NativePaintingGraphicsContext;
|
||||
use servo_msg::compositor_msg::Tile;
|
||||
use std::hashmap::HashMap;
|
||||
use std::to_bytes::Cb;
|
||||
use std::util;
|
||||
use std::hash::Hash;
|
||||
use std::hash::sip::SipState;
|
||||
use std::mem;
|
||||
|
||||
/// 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
|
||||
|
@ -27,16 +28,18 @@ pub struct BufferMap<T> {
|
|||
/// A key with which to store buffers. It is based on the size of the buffer.
|
||||
struct BufferKey([uint, ..2]);
|
||||
|
||||
impl IterBytes for BufferKey {
|
||||
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
|
||||
let i = if lsb0 {0} else {1};
|
||||
self[i].iter_bytes(lsb0, |x| f(x)) && self[1 - i].iter_bytes(lsb0, |x| f(x))
|
||||
impl Hash for BufferKey {
|
||||
fn hash(&self, state: &mut SipState) {
|
||||
let BufferKey(ref bytes) = *self;
|
||||
bytes.as_slice().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for BufferKey {
|
||||
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();
|
||||
// use lazy insertion function to prevent unnecessary allocation
|
||||
let counter = &self.counter;
|
||||
self.map.find_or_insert_with(new_key, |_| BufferValue {
|
||||
buffers: ~[],
|
||||
last_action: self.counter
|
||||
last_action: *counter
|
||||
}).buffers.push(new_buffer);
|
||||
|
||||
let mut opt_key: Option<BufferKey> = None;
|
||||
|
@ -97,7 +101,7 @@ impl<T: Tile> BufferMap<T> {
|
|||
};
|
||||
if {
|
||||
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();
|
||||
condemned_buffer.destroy(graphics_context);
|
||||
list.is_empty()
|
||||
|
@ -120,7 +124,7 @@ impl<T: Tile> BufferMap<T> {
|
|||
buffer_val.last_action = self.counter;
|
||||
self.counter += 1;
|
||||
|
||||
let buffer = buffer_val.buffers.pop();
|
||||
let buffer = buffer_val.buffers.pop().take_unwrap();
|
||||
self.mem -= buffer.get_mem();
|
||||
if buffer_val.buffers.is_empty() {
|
||||
flag = true;
|
||||
|
@ -139,7 +143,7 @@ impl<T: Tile> BufferMap<T> {
|
|||
|
||||
/// Destroys all buffers.
|
||||
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 tile in value.buffers.move_iter() {
|
||||
tile.destroy(graphics_context)
|
||||
|
|
|
@ -18,14 +18,14 @@ use color::Color;
|
|||
use render_context::RenderContext;
|
||||
use text::TextRun;
|
||||
|
||||
use extra::arc::Arc;
|
||||
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
|
||||
use servo_net::image::base::Image;
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use std::cast::transmute_region;
|
||||
use std::vec::VecIterator;
|
||||
use std::vec::Items;
|
||||
use style::computed_values::border_style;
|
||||
use sync::Arc;
|
||||
|
||||
pub struct DisplayListCollection<E> {
|
||||
lists: ~[DisplayList<E>]
|
||||
|
@ -70,7 +70,7 @@ pub struct DisplayList<E> {
|
|||
|
||||
pub enum DisplayListIterator<'a,E> {
|
||||
EmptyDisplayListIterator,
|
||||
ParentDisplayListIterator(VecIterator<'a,DisplayList<E>>),
|
||||
ParentDisplayListIterator(Items<'a,DisplayList<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> {
|
||||
EmptyDisplayItemIterator,
|
||||
ParentDisplayItemIterator(VecIterator<'a,DisplayItem<E>>),
|
||||
ParentDisplayItemIterator(Items<'a,DisplayItem<E>>),
|
||||
}
|
||||
|
||||
impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
use azure::{AzFloat, AzScaledFontRef};
|
||||
use azure::azure_hl::{BackendType, ColorPattern};
|
||||
use azure::scaled_font::ScaledFont;
|
||||
use extra::arc::Arc;
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use std::cast;
|
||||
use std::ptr;
|
||||
|
@ -15,6 +14,7 @@ use std::cell::RefCell;
|
|||
use servo_util::cache::{Cache, HashCache};
|
||||
use servo_util::range::Range;
|
||||
use style::computed_values::{text_decoration, font_weight, font_style};
|
||||
use sync::Arc;
|
||||
|
||||
use color::Color;
|
||||
use font_context::FontContext;
|
||||
|
@ -230,7 +230,7 @@ impl<'a> Font {
|
|||
|
||||
let metrics = handle.get_metrics();
|
||||
|
||||
return Ok(Rc::from_mut(RefCell::new(Font {
|
||||
return Ok(Rc::new(RefCell::new(Font {
|
||||
handle: handle,
|
||||
azure_font: None,
|
||||
shaper: None,
|
||||
|
@ -269,7 +269,7 @@ impl<'a> Font {
|
|||
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 {
|
||||
|
@ -394,9 +394,9 @@ impl Font {
|
|||
// TODO(Issue #64): this call needs to move into azure_hl.rs
|
||||
AzDrawTargetFillGlyphs(target.azure_draw_target,
|
||||
azfontref,
|
||||
ptr::to_unsafe_ptr(&glyphbuf),
|
||||
&glyphbuf,
|
||||
azure_pattern,
|
||||
ptr::to_unsafe_ptr(&options),
|
||||
&options,
|
||||
ptr::null());
|
||||
}
|
||||
}
|
||||
|
@ -428,9 +428,10 @@ impl Font {
|
|||
|
||||
//FIXME (ksh8281)
|
||||
self.make_shaper();
|
||||
let shaper = &self.shaper;
|
||||
self.shape_cache.find_or_create(&text, |txt| {
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
@ -444,8 +445,9 @@ impl Font {
|
|||
}
|
||||
|
||||
pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel {
|
||||
let handle = &self.handle;
|
||||
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,
|
||||
None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ use platform::font::FontHandle;
|
|||
use platform::font_context::FontContextHandle;
|
||||
|
||||
use azure::azure_hl::BackendType;
|
||||
use collections::hashmap::HashMap;
|
||||
use servo_util::cache::{Cache, LRUCache};
|
||||
use servo_util::time::ProfilerChan;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
@ -148,7 +148,7 @@ impl FontContext {
|
|||
Some(ref result) => {
|
||||
found = true;
|
||||
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 {
|
||||
Some(ref 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 => { }
|
||||
};
|
||||
|
@ -198,11 +198,9 @@ impl FontContext {
|
|||
|
||||
debug!("(create font group) --- finished ---");
|
||||
|
||||
unsafe {
|
||||
Rc::new_unchecked(
|
||||
RefCell::new(
|
||||
FontGroup::new(style.families.to_owned(), &used_style, fonts)))
|
||||
}
|
||||
Rc::new(
|
||||
RefCell::new(
|
||||
FontGroup::new(style.families.to_owned(), &used_style, fonts)))
|
||||
}
|
||||
|
||||
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> {
|
||||
|
@ -213,7 +211,7 @@ impl FontContext {
|
|||
desc.style.clone());
|
||||
result_handle.and_then(|handle| {
|
||||
Ok(
|
||||
Rc::from_mut(
|
||||
Rc::new(
|
||||
RefCell::new(
|
||||
Font::new_from_adopted_handle(self,
|
||||
handle,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
use font::SpecifiedFontStyle;
|
||||
use gfx_font::FontHandleMethods;
|
||||
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;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
pub type FontFamilyMap = HashMap<~str, FontFamily>;
|
||||
|
||||
|
|
|
@ -7,29 +7,31 @@
|
|||
|
||||
#[feature(globs, managed_boxes, macro_rules)];
|
||||
|
||||
extern mod azure;
|
||||
extern mod extra;
|
||||
extern mod geom;
|
||||
extern mod layers;
|
||||
extern mod stb_image;
|
||||
extern mod png;
|
||||
extern mod servo_net = "net";
|
||||
extern mod servo_util = "util";
|
||||
extern mod style;
|
||||
extern mod servo_msg = "msg";
|
||||
extern crate azure;
|
||||
extern crate collections;
|
||||
extern crate extra;
|
||||
extern crate geom;
|
||||
extern crate layers;
|
||||
extern crate stb_image;
|
||||
extern crate png;
|
||||
extern crate servo_net = "net";
|
||||
extern crate servo_util = "util";
|
||||
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
|
||||
// shapers. For now, however, this is a hard dependency.
|
||||
extern mod harfbuzz;
|
||||
extern crate harfbuzz;
|
||||
|
||||
// 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 mod freetype;
|
||||
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate fontconfig;
|
||||
#[cfg(target_os="linux")] #[cfg(target_os="android")] extern crate freetype;
|
||||
|
||||
// Mac OS-specific library dependencies
|
||||
#[cfg(target_os="macos")] extern mod core_foundation;
|
||||
#[cfg(target_os="macos")] extern mod core_graphics;
|
||||
#[cfg(target_os="macos")] extern mod core_text;
|
||||
#[cfg(target_os="macos")] extern crate core_foundation;
|
||||
#[cfg(target_os="macos")] extern crate core_graphics;
|
||||
#[cfg(target_os="macos")] extern crate core_text;
|
||||
|
||||
pub use gfx_font = font;
|
||||
pub use gfx_font_context = font_context;
|
||||
|
|
|
@ -9,12 +9,14 @@ macro_rules! bitfield(
|
|||
impl $bitfieldname {
|
||||
#[inline]
|
||||
pub fn $getter(self) -> bool {
|
||||
(*self & $value) != 0
|
||||
let $bitfieldname(this) = self;
|
||||
(this & $value) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 }))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
extern mod freetype;
|
||||
extern crate freetype;
|
||||
|
||||
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
||||
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};
|
||||
|
@ -102,8 +102,8 @@ impl FontHandleMethods for FontHandle {
|
|||
let mut face: FT_Face = ptr::null();
|
||||
let face_index = 0 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() {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ impl<'a> FontHandle {
|
|||
let face_index = 0 as FT_Long;
|
||||
file.to_c_str().with_ref(|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() {
|
||||
return Err(());
|
||||
|
@ -313,7 +313,7 @@ impl<'a> FontHandle {
|
|||
let face_index = 0 as FT_Long;
|
||||
file.to_c_str().with_ref(|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() {
|
||||
return Err(());
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::ptr;
|
|||
use std::rc::Rc;
|
||||
|
||||
#[deriving(Clone)]
|
||||
struct FreeTypeLibraryHandle {
|
||||
pub struct FreeTypeLibraryHandle {
|
||||
ctx: FT_Library,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* 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/. */
|
||||
|
||||
extern mod freetype;
|
||||
extern mod fontconfig;
|
||||
extern crate freetype;
|
||||
extern crate fontconfig;
|
||||
|
||||
use fontconfig::fontconfig::{
|
||||
FcChar8, FcResultMatch, FcSetSystem, FcPattern,
|
||||
|
@ -25,7 +25,7 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
|||
use platform::font::FontHandle;
|
||||
use platform::font_context::FontContextHandle;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use collections::hashmap::HashMap;
|
||||
use std::libc;
|
||||
use std::libc::{c_int, c_char};
|
||||
use std::ptr;
|
||||
|
@ -68,7 +68,7 @@ impl FontListHandle {
|
|||
unsafe {
|
||||
let config = FcConfigGetCurrent();
|
||||
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();
|
||||
assert!(pattern.is_not_null());
|
||||
"family".to_c_str().with_ref(|FC_FAMILY| {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
extern mod freetype;
|
||||
extern crate freetype;
|
||||
|
||||
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
||||
use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle};
|
||||
|
@ -102,8 +102,8 @@ impl FontHandleMethods for FontHandle {
|
|||
let mut face: FT_Face = ptr::null();
|
||||
let face_index = 0 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() {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ impl<'a> FontHandle {
|
|||
let face_index = 0 as FT_Long;
|
||||
file.to_c_str().with_ref(|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() {
|
||||
return Err(());
|
||||
|
@ -313,7 +313,7 @@ impl<'a> FontHandle {
|
|||
let face_index = 0 as FT_Long;
|
||||
file.to_c_str().with_ref(|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() {
|
||||
return Err(());
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::ptr;
|
|||
use std::rc::Rc;
|
||||
|
||||
#[deriving(Clone)]
|
||||
struct FreeTypeLibraryHandle {
|
||||
pub struct FreeTypeLibraryHandle {
|
||||
ctx: FT_Library,
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* 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/. */
|
||||
|
||||
extern mod freetype;
|
||||
extern mod fontconfig;
|
||||
extern crate freetype;
|
||||
extern crate fontconfig;
|
||||
|
||||
use fontconfig::fontconfig::{
|
||||
FcChar8, FcResultMatch, FcSetSystem, FcPattern,
|
||||
|
@ -25,7 +25,7 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
|||
use platform::font::FontHandle;
|
||||
use platform::font_context::FontContextHandle;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use collections::HashMap;
|
||||
use std::libc;
|
||||
use std::libc::{c_int, c_char};
|
||||
use std::ptr;
|
||||
|
@ -68,7 +68,7 @@ impl FontListHandle {
|
|||
unsafe {
|
||||
let config = FcConfigGetCurrent();
|
||||
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();
|
||||
assert!(pattern.is_not_null());
|
||||
"family".to_c_str().with_ref(|FC_FAMILY| {
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
/// Implementation of Quartz (CoreGraphics) fonts.
|
||||
|
||||
extern mod core_foundation;
|
||||
extern mod core_graphics;
|
||||
extern mod core_text;
|
||||
extern crate core_foundation;
|
||||
extern crate core_graphics;
|
||||
extern crate core_text;
|
||||
|
||||
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
||||
use font::FontTableTag;
|
||||
|
@ -130,8 +130,8 @@ impl FontHandleMethods for FontHandle {
|
|||
let glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
|
||||
let count: CFIndex = 1;
|
||||
|
||||
let result = self.ctfont.get_glyphs_for_characters(ptr::to_unsafe_ptr(&characters[0]),
|
||||
ptr::to_unsafe_ptr(&glyphs[0]),
|
||||
let result = self.ctfont.get_glyphs_for_characters(&characters[0],
|
||||
&glyphs[0],
|
||||
count);
|
||||
|
||||
if !result {
|
||||
|
|
|
@ -7,12 +7,12 @@ use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
|||
use platform::macos::font::FontHandle;
|
||||
use platform::macos::font_context::FontContextHandle;
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
use core_foundation::base::TCFType;
|
||||
use core_foundation::string::{CFString, CFStringRef};
|
||||
use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef};
|
||||
use core_text;
|
||||
use std::cast;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
pub struct FontListHandle {
|
||||
fctx: FontContextHandle,
|
||||
|
|
|
@ -9,7 +9,6 @@ use azure::azure_hl::{B8G8R8A8, Color, ColorPattern, DrawOptions};
|
|||
use azure::azure_hl::{DrawSurfaceOptions, DrawTarget, Linear, StrokeOptions};
|
||||
use azure::AZ_CAP_BUTT;
|
||||
use azure::AzFloat;
|
||||
use extra::arc::Arc;
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
|
@ -20,6 +19,7 @@ use servo_util::geometry::Au;
|
|||
use servo_util::opts::Opts;
|
||||
use std::libc::types::common::c99::uint16_t;
|
||||
use std::libc::size_t;
|
||||
use sync::Arc;
|
||||
|
||||
pub struct RenderContext<'a> {
|
||||
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 {
|
||||
fn to_azure_rect(&self) -> Rect<AzFloat>;
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ use servo_util::time::{ProfilerChan, profile};
|
|||
use servo_util::time;
|
||||
use servo_util::task::send_on_failure;
|
||||
|
||||
use std::comm::{Chan, Port, SharedChan};
|
||||
use std::comm::{Chan, Port};
|
||||
use std::task;
|
||||
use extra::arc::Arc;
|
||||
use sync::Arc;
|
||||
|
||||
use buffer_map::BufferMap;
|
||||
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
|
||||
// generic newtypes ICE when compiled cross-crate
|
||||
pub struct RenderChan<T> {
|
||||
chan: SharedChan<Msg<T>>,
|
||||
chan: Chan<Msg<T>>,
|
||||
}
|
||||
|
||||
impl<T: Send> Clone for RenderChan<T> {
|
||||
|
@ -79,7 +79,7 @@ impl<T: Send> Clone for RenderChan<T> {
|
|||
|
||||
impl<T: Send> RenderChan<T> {
|
||||
pub fn new() -> (Port<Msg<T>>, RenderChan<T>) {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
let render_chan = RenderChan {
|
||||
chan: chan,
|
||||
};
|
||||
|
@ -149,9 +149,9 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
|||
opts: Opts,
|
||||
profiler_chan: ProfilerChan,
|
||||
shutdown_chan: Chan<()>) {
|
||||
let mut builder = task::task();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||
builder.name("RenderTask");
|
||||
let mut builder = task::task().named("RenderTask");
|
||||
let ConstellationChan(c) = constellation_chan.clone();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), c);
|
||||
builder.spawn(proc() {
|
||||
|
||||
{ // 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();
|
||||
|
||||
// Destroy all the buffers.
|
||||
render_task.native_graphics_context.as_ref().map(
|
||||
|ctx| render_task.buffer_map.clear(ctx));
|
||||
match render_task.native_graphics_context.as_ref() {
|
||||
Some(ctx) => render_task.buffer_map.clear(ctx),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
@ -251,12 +254,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
|||
}
|
||||
|
||||
fn render(&mut self, tiles: ~[BufferRequest], scale: f32) {
|
||||
let render_layer;
|
||||
match self.render_layer {
|
||||
Some(ref r_layer) => {
|
||||
render_layer = r_layer;
|
||||
}
|
||||
_ => return, // nothing to do
|
||||
if self.render_layer.is_none() {
|
||||
return
|
||||
}
|
||||
|
||||
self.compositor.set_render_state(RenderingRenderState);
|
||||
|
@ -311,6 +310,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
|||
|
||||
// Draw the display list.
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
})
|
||||
|
|
|
@ -9,9 +9,9 @@ use servo_util::geometry;
|
|||
|
||||
use std::cmp::{Ord, Eq};
|
||||
use std::num::NumCast;
|
||||
use std::mem;
|
||||
use std::u16;
|
||||
use std::vec;
|
||||
use std::util;
|
||||
use std::iter;
|
||||
use geom::point::Point2D;
|
||||
|
||||
|
@ -45,7 +45,8 @@ impl GlyphEntry {
|
|||
assert!(is_simple_advance(advance));
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -53,7 +54,7 @@ impl GlyphEntry {
|
|||
// Create a GlyphEntry for uncommon case; should be accompanied by
|
||||
// initialization of the actual DetailedGlyph data in DetailedGlyphStore
|
||||
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={}, \
|
||||
glyph_count={}",
|
||||
|
@ -77,7 +78,7 @@ impl GlyphEntry {
|
|||
/// Create a GlyphEntry for the case where glyphs couldn't be found for the specified
|
||||
/// character.
|
||||
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)
|
||||
}
|
||||
|
@ -404,7 +405,7 @@ impl<'a> DetailedGlyphStore {
|
|||
|
||||
// Thar be dragons here. You have been warned. (Tips accepted.)
|
||||
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;
|
||||
mut_records.sort_by(|a, b| {
|
||||
if a < b {
|
||||
|
@ -414,7 +415,7 @@ impl<'a> DetailedGlyphStore {
|
|||
}
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
extern mod harfbuzz;
|
||||
extern crate harfbuzz;
|
||||
|
||||
use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag};
|
||||
use platform::font::FontTable;
|
||||
|
@ -39,10 +39,9 @@ use servo_util::geometry::Au;
|
|||
use servo_util::range::Range;
|
||||
use std::cast::transmute;
|
||||
use std::char;
|
||||
use std::cmp;
|
||||
use std::libc::{c_uint, c_int, c_void, c_char};
|
||||
use std::num;
|
||||
use std::ptr::null;
|
||||
use std::ptr;
|
||||
use std::vec;
|
||||
|
||||
static NO_GLYPH: i32 = -1;
|
||||
|
@ -86,7 +85,7 @@ impl ShapedGlyphData {
|
|||
assert!(i < self.count);
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -100,8 +99,8 @@ impl ShapedGlyphData {
|
|||
assert!(i < self.count);
|
||||
|
||||
unsafe {
|
||||
let glyph_info_i = ptr::offset(self.glyph_infos, i as int);
|
||||
let pos_info_i = ptr::offset(self.pos_infos, i as int);
|
||||
let glyph_info_i = self.glyph_infos.offset(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 y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset);
|
||||
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();
|
||||
for i in char_byte_span.eachi() {
|
||||
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..)
|
||||
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.
|
||||
if glyph_span.length() == 1 {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
* 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 extra::arc::Arc;
|
||||
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use std::vec::VecIterator;
|
||||
use std::vec::Items;
|
||||
use style::computed_values::text_decoration;
|
||||
use sync::Arc;
|
||||
use text::glyph::GlyphStore;
|
||||
|
||||
/// A text run.
|
||||
|
@ -22,7 +22,7 @@ pub struct TextRun {
|
|||
}
|
||||
|
||||
pub struct SliceIterator<'a> {
|
||||
priv glyph_iter: VecIterator<'a, Arc<GlyphStore>>,
|
||||
priv glyph_iter: Items<'a, Arc<GlyphStore>>,
|
||||
priv range: Range,
|
||||
priv offset: uint,
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ use windowing::{WindowEvent, WindowMethods,
|
|||
|
||||
use azure::azure_hl::{SourceSurfaceMethods, Color};
|
||||
use azure::azure_hl;
|
||||
use extra::time::precise_time_s;
|
||||
use geom::matrix::identity;
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
|
@ -36,19 +35,16 @@ use servo_msg::constellation_msg;
|
|||
use servo_util::opts::Opts;
|
||||
use servo_util::time::{profile, ProfilerChan, Timer};
|
||||
use servo_util::{time, url};
|
||||
use std::comm::Port;
|
||||
use std::num::Orderable;
|
||||
use std::cmp;
|
||||
use std::comm::{Empty, Disconnected, Data, Port};
|
||||
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 {
|
||||
/// The application window.
|
||||
window: rc::Rc<Window>,
|
||||
window: Rc<Window>,
|
||||
|
||||
/// The port on which we receive messages.
|
||||
port: Port<Msg>,
|
||||
|
@ -120,7 +116,7 @@ impl IOCompositor {
|
|||
port: Port<Msg>,
|
||||
constellation_chan: ConstellationChan,
|
||||
profiler_chan: ProfilerChan) -> IOCompositor {
|
||||
let window: rc::Rc<Window> = WindowMethods::new(app);
|
||||
let window: Rc<Window> = WindowMethods::new(app);
|
||||
|
||||
// Create an initial layer tree.
|
||||
//
|
||||
|
@ -171,14 +167,17 @@ impl IOCompositor {
|
|||
|
||||
fn run (&mut self) {
|
||||
// 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.
|
||||
while !self.done {
|
||||
// Check for new messages coming from the rendering task.
|
||||
self.handle_message();
|
||||
|
||||
if (self.done) {
|
||||
if self.done {
|
||||
// We have exited the compositor and passing window
|
||||
// messages to script may crash.
|
||||
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
|
||||
// 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.
|
||||
self.profiler_chan.send(time::ExitMsg);
|
||||
let ProfilerChan(ref chan) = self.profiler_chan;
|
||||
chan.send(time::ExitMsg);
|
||||
}
|
||||
|
||||
fn handle_message(&mut self) {
|
||||
loop {
|
||||
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");
|
||||
self.constellation_chan.send(ExitMsg);
|
||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
||||
con_chan.send(ExitMsg);
|
||||
chan.send(());
|
||||
self.shutting_down = true;
|
||||
}
|
||||
|
||||
(Some(ShutdownComplete), _) => {
|
||||
(Data(ShutdownComplete), _) => {
|
||||
debug!("constellation completed shutdown");
|
||||
self.done = true;
|
||||
}
|
||||
|
||||
(Some(ChangeReadyState(ready_state)), false) => {
|
||||
(Data(ChangeReadyState(ready_state)), false) => {
|
||||
self.window.borrow().set_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);
|
||||
}
|
||||
|
||||
(Some(SetUnRenderedColor(_id, color)), false) => {
|
||||
(Data(SetUnRenderedColor(_id, color)), false) => {
|
||||
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);
|
||||
}
|
||||
|
||||
(Some(GetGraphicsMetadata(chan)), false) => {
|
||||
(Data(GetGraphicsMetadata(chan)), false) => {
|
||||
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);
|
||||
}
|
||||
|
||||
(Some(SetLayerPageSize(id, new_size, epoch)), false) => {
|
||||
(Data(SetLayerPageSize(id, new_size, epoch)), false) => {
|
||||
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);
|
||||
}
|
||||
|
||||
(Some(DeleteLayer(id)), _) => {
|
||||
(Data(DeleteLayer(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);
|
||||
}
|
||||
|
||||
(Some(InvalidateRect(id, rect)), false) => {
|
||||
(Data(InvalidateRect(id, rect)), false) => {
|
||||
self.invalidate_rect(id, rect);
|
||||
}
|
||||
|
||||
(Some(ScrollFragmentPoint(id, point)), false) => {
|
||||
(Data(ScrollFragmentPoint(id, point)), false) => {
|
||||
self.scroll_fragment_to_point(id, point);
|
||||
}
|
||||
|
||||
(Some(LoadComplete(..)), false) => {
|
||||
(Data(LoadComplete(..)), false) => {
|
||||
self.load_complete = true;
|
||||
}
|
||||
|
||||
|
@ -350,7 +358,10 @@ impl IOCompositor {
|
|||
let window_size = self.window.borrow().size();
|
||||
let window_size = Size2D(window_size.width 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;
|
||||
}
|
||||
|
@ -397,7 +408,7 @@ impl IOCompositor {
|
|||
let page_window = Size2D(window_size.width as f32 / world_zoom,
|
||||
window_size.height as f32 / world_zoom);
|
||||
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)
|
||||
}
|
||||
|
@ -551,14 +562,16 @@ impl IOCompositor {
|
|||
let exit = self.opts.exit_after_load;
|
||||
if exit {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -569,7 +582,8 @@ impl IOCompositor {
|
|||
if self.window_size != new_size {
|
||||
debug!("osmain: window resized to {:u}x{:u}", width, height);
|
||||
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 {
|
||||
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));
|
||||
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) {
|
||||
|
@ -628,7 +643,7 @@ impl IOCompositor {
|
|||
let window_size = &self.window_size;
|
||||
|
||||
// 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;
|
||||
|
||||
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::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.
|
||||
|
@ -721,7 +737,8 @@ impl IOCompositor {
|
|||
assert!(res.is_ok());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -730,7 +747,8 @@ impl IOCompositor {
|
|||
let exit = self.opts.exit_after_load;
|
||||
if exit {
|
||||
debug!("shutting down the constellation for exit_after_load");
|
||||
self.constellation_chan.send(ExitMsg);
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ExitMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,11 @@ use layers::texturegl::{Texture, TextureTarget};
|
|||
#[cfg(target_os="macos")] use layers::texturegl::TextureTargetRectangle;
|
||||
use pipeline::CompositionPipeline;
|
||||
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::constellation_msg::PipelineId;
|
||||
//FIXME: switch to std::rc when we upgrade Rust
|
||||
use layers::temp_rc::Rc;
|
||||
//use std::rc::Rc;
|
||||
use std::cmp;
|
||||
use std::rc::Rc;
|
||||
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
|
||||
use windowing::{MouseWindowMouseUpEvent};
|
||||
use azure::azure_hl::Color;
|
||||
|
@ -105,6 +104,25 @@ enum ScrollBehavior {
|
|||
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 {
|
||||
/// 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.
|
||||
|
@ -207,9 +225,9 @@ impl CompositorLayer {
|
|||
Some(size) => size,
|
||||
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);
|
||||
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);
|
||||
|
||||
// check to see if we scrolled
|
||||
|
@ -253,13 +271,15 @@ impl CompositorLayer {
|
|||
MouseWindowClickEvent(button, _) => ClickEvent(button, cursor),
|
||||
MouseWindowMouseDownEvent(button, _) => MouseDownEvent(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>) {
|
||||
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
|
||||
|
@ -410,9 +430,9 @@ impl CompositorLayer {
|
|||
Some(size) => size,
|
||||
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);
|
||||
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);
|
||||
|
||||
// check to see if we scrolled
|
||||
|
@ -674,7 +694,7 @@ impl CompositorLayer {
|
|||
NoTree(..) => {} // Nothing to do
|
||||
Tree(ref mut quadtree) => {
|
||||
// NOTE: work around borrowchk
|
||||
let tmp = child.container.borrow().scissor.borrow();
|
||||
let tmp = child.get_ref().container.borrow().scissor.borrow();
|
||||
match *tmp.get() {
|
||||
Some(rect) => {
|
||||
quadtree.set_status_page(rect, Normal, false); // Unhide this rect
|
||||
|
@ -685,7 +705,7 @@ impl CompositorLayer {
|
|||
}
|
||||
|
||||
// Send back all tiles to renderer.
|
||||
child.child.clear();
|
||||
child.get_mut_ref().child.clear();
|
||||
|
||||
self.build_layer_tree(graphics_context);
|
||||
true
|
||||
|
|
|
@ -14,12 +14,11 @@ use geom::rect::Rect;
|
|||
use geom::size::Size2D;
|
||||
use layers::platform::surface::{NativeCompositingGraphicsContext, NativeGraphicsMetadata};
|
||||
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_util::opts::Opts;
|
||||
use servo_util::time::ProfilerChan;
|
||||
use std::comm::{Chan, SharedChan, Port};
|
||||
use std::num::Orderable;
|
||||
use std::comm::{Chan, Port};
|
||||
|
||||
use extra::url::Url;
|
||||
|
||||
|
@ -36,7 +35,7 @@ mod headless;
|
|||
#[deriving(Clone)]
|
||||
pub struct CompositorChan {
|
||||
/// A channel on which messages can be sent to the compositor.
|
||||
chan: SharedChan<Msg>,
|
||||
chan: Chan<Msg>,
|
||||
}
|
||||
|
||||
/// Implementation of the abstract `ScriptListener` interface.
|
||||
|
@ -106,7 +105,7 @@ impl RenderListener for CompositorChan {
|
|||
|
||||
impl CompositorChan {
|
||||
pub fn new() -> (Port<Msg>, CompositorChan) {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
let compositor_chan = CompositorChan {
|
||||
chan: chan,
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ use compositing::*;
|
|||
|
||||
use geom::size::Size2D;
|
||||
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;
|
||||
|
||||
|
@ -32,12 +32,20 @@ impl NullCompositor {
|
|||
let compositor = NullCompositor::new(port);
|
||||
|
||||
// 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);
|
||||
|
||||
// Drain compositor port, sometimes messages contain channels that are blocking
|
||||
// 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);
|
||||
}
|
||||
|
@ -47,7 +55,8 @@ impl NullCompositor {
|
|||
match self.port.recv() {
|
||||
Exit(chan) => {
|
||||
debug!("shutting down the constellation");
|
||||
constellation_chan.send(ExitMsg);
|
||||
let ConstellationChan(ref con_chan) = constellation_chan;
|
||||
con_chan.send(ExitMsg);
|
||||
chan.send(());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,10 @@ use geom::point::Point2D;
|
|||
use geom::size::Size2D;
|
||||
use geom::rect::Rect;
|
||||
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::util::replace;
|
||||
use std::mem::replace;
|
||||
use std::vec::build;
|
||||
use servo_msg::compositor_msg::Tile;
|
||||
|
||||
|
@ -72,6 +73,12 @@ enum Quadrant {
|
|||
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> {
|
||||
/// Public method to create a new Quadtree
|
||||
/// 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.
|
||||
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
|
||||
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 power_of_two = next_power_of_two(num_tiles);
|
||||
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.
|
||||
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
|
||||
let longer = width.max(&height);
|
||||
let longer = cmp::max(width, height);
|
||||
let num_tiles = div_ceil(longer, self.max_tile_size);
|
||||
let power_of_two = next_power_of_two(num_tiles);
|
||||
let size = power_of_two * self.max_tile_size;
|
||||
|
@ -176,7 +183,7 @@ impl<T: Tile> Quadtree<T> {
|
|||
#[cfg(test)]
|
||||
pub fn bad_resize(&mut self, width: uint, height: uint) {
|
||||
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_size = next_power_of_two(new_num_tiles);
|
||||
// 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 {
|
||||
let pix_x = (self.origin.x * 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_height = (clip_y - self.origin.y).min(&self.size);
|
||||
let page_width = cmp::min(clip_x - self.origin.x, 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_height = (page_height * scale).ceil() as uint;
|
||||
self.status = Rendering;
|
||||
|
@ -472,8 +479,8 @@ impl<T: Tile> QuadtreeNode<T> {
|
|||
}
|
||||
|
||||
// clip window to visible region
|
||||
let w_width = (clip.width - w_x).min(&w_width);
|
||||
let w_height = (clip.height - w_y).min(&w_height);
|
||||
let w_width = cmp::min(clip.width - w_x, w_width);
|
||||
let w_height = cmp::min(clip.height - w_y, w_height);
|
||||
|
||||
if s_size <= tile_size { // We are the child
|
||||
return match self.tile {
|
||||
|
@ -545,20 +552,20 @@ impl<T: Tile> QuadtreeNode<T> {
|
|||
// Recurse into child
|
||||
let new_window = match *quad {
|
||||
TL => Rect(window.origin,
|
||||
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)),
|
||||
w_height.min(&(s_y + s_size / 2.0 - w_y)))),
|
||||
TR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)),
|
||||
Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
|
||||
cmp::min(w_height, (s_y + s_size / 2.0 - w_y)))),
|
||||
TR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
|
||||
w_y),
|
||||
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))),
|
||||
w_height.min(&(s_y + s_size / 2.0 - w_y)))),
|
||||
Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
|
||||
cmp::min(w_height, s_y + s_size / 2.0 - w_y))),
|
||||
BL => Rect(Point2D(w_x,
|
||||
w_y.max(&(s_y + s_size / 2.0))),
|
||||
Size2D(w_width.min(&(s_x + s_size / 2.0 - w_x)),
|
||||
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))),
|
||||
BR => Rect(Point2D(w_x.max(&(s_x + s_size / 2.0)),
|
||||
w_y.max(&(s_y + s_size / 2.0))),
|
||||
Size2D(w_width.min(&(w_x + w_width - (s_x + s_size / 2.0))),
|
||||
w_height.min(&(w_y + w_height - (s_y + s_size / 2.0))))),
|
||||
cmp::max(w_y, s_y + s_size / 2.0)),
|
||||
Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
|
||||
cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
|
||||
BR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
|
||||
cmp::max(w_y, s_y + s_size / 2.0)),
|
||||
Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
|
||||
cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
|
||||
|
||||
use collections::hashmap::{HashMap, HashSet};
|
||||
use extra::url::Url;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
|
@ -11,6 +12,8 @@ use gfx::render_task;
|
|||
use pipeline::{Pipeline, CompositionPipeline};
|
||||
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExitPipelineMsg};
|
||||
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::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
|
||||
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::task::spawn_named;
|
||||
use std::cell::RefCell;
|
||||
use std::hashmap::{HashMap, HashSet};
|
||||
//FIXME: switch to std::rc when we upgrade Rust
|
||||
use layers::temp_rc::Rc;
|
||||
//use std::rc::Rc;
|
||||
use std::util::replace;
|
||||
use std::mem::replace;
|
||||
use std::io;
|
||||
use std::libc;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Maintains the pipelines and navigation context and grants permission to composite
|
||||
pub struct Constellation {
|
||||
|
@ -199,12 +199,12 @@ impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
|
|||
let next = self.stack.pop();
|
||||
{
|
||||
// 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() {
|
||||
self.stack.push(cft.frame_tree.clone());
|
||||
}
|
||||
}
|
||||
Some(next)
|
||||
Some(next.unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -239,14 +239,14 @@ impl NavigationContext {
|
|||
|
||||
pub fn back(&mut self) -> Rc<FrameTree> {
|
||||
self.next.push(self.current.take_unwrap());
|
||||
let prev = self.previous.pop();
|
||||
let prev = self.previous.pop().unwrap();
|
||||
self.current = Some(prev.clone());
|
||||
prev
|
||||
}
|
||||
|
||||
pub fn forward(&mut self) -> Rc<FrameTree> {
|
||||
self.previous.push(self.current.take_unwrap());
|
||||
let next = self.next.pop();
|
||||
let next = self.next.pop().unwrap();
|
||||
self.current = Some(next.clone());
|
||||
next
|
||||
}
|
||||
|
@ -335,7 +335,8 @@ impl Constellation {
|
|||
/// Helper function for getting a unique pipeline Id
|
||||
fn get_next_pipeline_id(&mut self) -> PipelineId {
|
||||
let id = self.next_pipeline_id;
|
||||
*self.next_pipeline_id += 1;
|
||||
let PipelineId(ref mut i) = self.next_pipeline_id;
|
||||
*i += 1;
|
||||
id
|
||||
}
|
||||
|
||||
|
@ -427,8 +428,8 @@ impl Constellation {
|
|||
// 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.
|
||||
let mut stderr = io::stderr();
|
||||
stderr.write_str("Pipeline failed in hard-fail mode. Crashing!\n");
|
||||
stderr.flush();
|
||||
stderr.write_str("Pipeline failed in hard-fail mode. Crashing!\n").unwrap();
|
||||
stderr.flush().unwrap();
|
||||
unsafe { libc::exit(1); }
|
||||
}
|
||||
|
||||
|
@ -437,9 +438,11 @@ impl Constellation {
|
|||
Some(id) => id.clone()
|
||||
};
|
||||
|
||||
old_pipeline.borrow().script_chan.try_send(ExitPipelineMsg(pipeline_id));
|
||||
old_pipeline.borrow().render_chan.try_send(render_task::ExitMsg(None));
|
||||
old_pipeline.borrow().layout_chan.try_send(layout_interface::ExitNowMsg);
|
||||
let ScriptChan(ref old_script) = old_pipeline.borrow().script_chan;
|
||||
old_script.try_send(ExitPipelineMsg(pipeline_id));
|
||||
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);
|
||||
|
||||
let new_id = self.get_next_pipeline_id();
|
||||
|
@ -508,51 +511,56 @@ impl Constellation {
|
|||
== 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
|
||||
// resize happens immediately.
|
||||
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
||||
child_frame_tree.rect = Some(rect.clone());
|
||||
// NOTE: work around borrowchk issues
|
||||
let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow();
|
||||
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() {
|
||||
{
|
||||
// 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
|
||||
// resize happens immediately.
|
||||
let compositor_chan = self.compositor_chan.clone();
|
||||
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
||||
child_frame_tree.rect = Some(rect.clone());
|
||||
// NOTE: work around borrowchk issues
|
||||
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));
|
||||
}
|
||||
}
|
||||
let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow();
|
||||
if !already_sent.contains(&pipeline.get().borrow().id) {
|
||||
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
|
||||
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));
|
||||
// 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
|
||||
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
|
||||
|
@ -871,7 +879,8 @@ impl Constellation {
|
|||
// NOTE: work around borrowchk issues
|
||||
let tmp = frame_tree.borrow().pipeline.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);
|
||||
}
|
||||
for frame_tree in self.navigation_context.previous.iter()
|
||||
|
@ -881,7 +890,8 @@ impl Constellation {
|
|||
let pipeline = &tmp.get().borrow();
|
||||
if !already_seen.contains(&pipeline.id) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -897,7 +907,8 @@ impl Constellation {
|
|||
// NOTE: work around borrowchk issues
|
||||
let tmp = frame_tree.pipeline.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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,16 @@ use layout::extra::LayoutAuxMethods;
|
|||
use layout::util::{LayoutDataAccess, LayoutDataWrapper};
|
||||
use layout::wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode};
|
||||
|
||||
use extra::arc::Arc;
|
||||
use gfx::font_context::FontContext;
|
||||
use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
|
||||
use servo_util::namespace::Null;
|
||||
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16};
|
||||
use servo_util::str::DOMString;
|
||||
use std::cast;
|
||||
use std::to_bytes;
|
||||
use std::vec::VecIterator;
|
||||
use std::hash::{Hash, sip};
|
||||
use std::vec::Items;
|
||||
use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade};
|
||||
use sync::Arc;
|
||||
|
||||
pub struct ApplicableDeclarations {
|
||||
normal: SmallVec16<MatchedProperty>,
|
||||
|
@ -73,9 +73,10 @@ impl Eq for ApplicableDeclarationsCacheEntry {
|
|||
}
|
||||
}
|
||||
|
||||
impl IterBytes for ApplicableDeclarationsCacheEntry {
|
||||
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
|
||||
ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()).iter_bytes(lsb0, f)
|
||||
impl Hash for ApplicableDeclarationsCacheEntry {
|
||||
fn hash(&self, state: &mut sip::SipState) {
|
||||
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 {
|
||||
let mut result = true;
|
||||
|
||||
impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn hash(&self, state: &mut sip::SipState) {
|
||||
for declaration in self.declarations.iter() {
|
||||
let ptr: uint = unsafe {
|
||||
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)]
|
||||
struct StyleSharingCandidate {
|
||||
priv style: Arc<ComputedValues>,
|
||||
priv parent_style: Arc<ComputedValues>,
|
||||
style: Arc<ComputedValues>,
|
||||
parent_style: Arc<ComputedValues>,
|
||||
|
||||
// TODO(pcwalton): Intern.
|
||||
priv local_name: DOMString,
|
||||
local_name: DOMString,
|
||||
|
||||
priv class: Option<DOMString>,
|
||||
class: Option<DOMString>,
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ use css::node_util::NodeUtil;
|
|||
use layout::incremental::RestyleDamage;
|
||||
use layout::wrapper::ThreadSafeLayoutNode;
|
||||
|
||||
use extra::arc::Arc;
|
||||
use style::ComputedValues;
|
||||
use sync::Arc;
|
||||
|
||||
/// Node mixin providing `style` method that returns a `NodeStyle`
|
||||
pub trait StyledNode {
|
||||
|
|
|
@ -6,9 +6,9 @@ use layout::incremental::RestyleDamage;
|
|||
use layout::util::LayoutDataAccess;
|
||||
use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode};
|
||||
|
||||
use extra::arc::Arc;
|
||||
use std::cast;
|
||||
use style::ComputedValues;
|
||||
use sync::Arc;
|
||||
|
||||
pub trait NodeUtil {
|
||||
fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>;
|
||||
|
|
|
@ -119,7 +119,7 @@ impl HeightConstraintSolution {
|
|||
(Specified(top), Specified(bottom), Specified(height)) => {
|
||||
match (top_margin, bottom_margin) {
|
||||
(Auto, Auto) => {
|
||||
let total_margin_val = (available_height - top - bottom - height);
|
||||
let total_margin_val = available_height - top - bottom - height;
|
||||
(top, bottom, height,
|
||||
total_margin_val.scale_by(0.5),
|
||||
total_margin_val.scale_by(0.5))
|
||||
|
@ -226,7 +226,7 @@ impl HeightConstraintSolution {
|
|||
(Specified(top), Specified(bottom)) => {
|
||||
match (top_margin, bottom_margin) {
|
||||
(Auto, Auto) => {
|
||||
let total_margin_val = (available_height - top - bottom - height);
|
||||
let total_margin_val = available_height - top - bottom - height;
|
||||
(top, bottom, height,
|
||||
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;
|
||||
}
|
||||
|
||||
block_flow.calculate_abs_height_and_margins(**self);
|
||||
|
||||
let AbsoluteAssignHeightsTraversal(ref ctx) = *self;
|
||||
block_flow.calculate_abs_height_and_margins(*ctx);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -1731,7 +1733,7 @@ trait WidthAndMarginsComputer {
|
|||
let left = left_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))
|
||||
} else {
|
||||
(left_margin, right_margin)
|
||||
|
@ -1838,7 +1840,7 @@ impl WidthAndMarginsComputer for AbsoluteNonReplaced {
|
|||
(Specified(left), Specified(right), Specified(width)) => {
|
||||
match (left_margin, right_margin) {
|
||||
(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) {
|
||||
// margin-left becomes 0 because direction is 'ltr'.
|
||||
// TODO: Handle 'rtl' when it is implemented.
|
||||
|
@ -2001,7 +2003,7 @@ impl WidthAndMarginsComputer for AbsoluteReplaced {
|
|||
(Specified(left), Specified(right)) => {
|
||||
match (left_margin, right_margin) {
|
||||
(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) {
|
||||
// margin-left becomes 0 because direction is 'ltr'.
|
||||
(left, right, width, Au(0), total_margin_val)
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
//! The `Box` type, which represents the leaves of the layout tree.
|
||||
|
||||
use extra::url::Url;
|
||||
use extra::arc::{MutexArc, Arc};
|
||||
use sync::{MutexArc, Arc};
|
||||
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
|
||||
use geom::approxeq::ApproxEq;
|
||||
use gfx::color::rgb;
|
||||
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
|
||||
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::font::FontStyle;
|
||||
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::local_image_cache::LocalImageCache;
|
||||
use servo_util::geometry::Au;
|
||||
|
@ -27,7 +28,6 @@ use servo_util::str::is_whitespace;
|
|||
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::ApproxEq;
|
||||
use std::num::Zero;
|
||||
use style::{ComputedValues, TElement, TNode};
|
||||
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!"),
|
||||
ScannedTextBox(ref text_box_info) => {
|
||||
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 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
|
||||
};
|
||||
|
||||
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 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;
|
||||
|
@ -1621,10 +1621,10 @@ impl Box {
|
|||
}
|
||||
format!(" {}{},{},{},{}",
|
||||
name,
|
||||
*value.top,
|
||||
*value.right,
|
||||
*value.bottom,
|
||||
*value.left)
|
||||
value.top,
|
||||
value.right,
|
||||
value.bottom,
|
||||
value.left)
|
||||
}
|
||||
|
||||
/// 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.subpage_id);
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@ use servo_util::url::is_image_data;
|
|||
use servo_util::str::is_whitespace;
|
||||
|
||||
use extra::url::Url;
|
||||
use extra::arc::Arc;
|
||||
use std::util;
|
||||
use sync::Arc;
|
||||
use std::mem;
|
||||
use std::num::Zero;
|
||||
|
||||
/// The results of flow construction for a DOM node.
|
||||
|
@ -319,7 +319,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
opt_boxes: &mut Option<~[Box]>,
|
||||
flow: &mut ~Flow,
|
||||
node: &ThreadSafeLayoutNode) {
|
||||
let opt_boxes = util::replace(opt_boxes, None);
|
||||
let opt_boxes = mem::replace(opt_boxes, None);
|
||||
if opt_boxes.len() > 0 {
|
||||
self.flush_inline_boxes_to_flow(opt_boxes.to_vec(), flow, node)
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
// {ib} splits.
|
||||
debug!("flushing {} inline box(es) to flow A",
|
||||
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,
|
||||
&mut flow,
|
||||
node);
|
||||
|
@ -397,8 +397,8 @@ impl<'a> FlowConstructor<'a> {
|
|||
// Flush any inline boxes that we were gathering up.
|
||||
debug!("flushing {} inline box(es) to flow A",
|
||||
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,
|
||||
&mut flow,
|
||||
|
@ -486,7 +486,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
// {ib} split. Flush the accumulator to our new split and make a new
|
||||
// accumulator to hold any subsequent boxes we come across.
|
||||
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,
|
||||
};
|
||||
opt_inline_block_splits.push(split);
|
||||
|
@ -513,7 +513,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
opt_box_accumulator.push_all_move(boxes);
|
||||
|
||||
let split = InlineBlockSplit {
|
||||
predecessor_boxes: util::replace(&mut opt_box_accumulator,
|
||||
predecessor_boxes: mem::replace(&mut opt_box_accumulator,
|
||||
None).to_vec(),
|
||||
flow: kid_flow,
|
||||
};
|
||||
|
@ -830,7 +830,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
|||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match *layout_data_ref.get() {
|
||||
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"),
|
||||
}
|
||||
|
@ -872,7 +872,7 @@ impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
|
|||
|
||||
/// Strips ignorable whitespace from the start of a list of boxes.
|
||||
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,
|
||||
Some(boxes) => {
|
||||
// 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 {
|
||||
None => {}
|
||||
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");
|
||||
let box_ = boxes.pop();
|
||||
let box_ = boxes.pop().unwrap();
|
||||
if boxes.len() > 0 {
|
||||
boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
|
||||
use layout::util::OpaqueNode;
|
||||
|
||||
use extra::arc::{Arc, MutexArc};
|
||||
use extra::url::Url;
|
||||
use geom::size::Size2D;
|
||||
use gfx::font_context::{FontContext, FontContextInfo};
|
||||
|
@ -23,6 +22,7 @@ use std::rt::Runtime;
|
|||
use std::rt::local::Local;
|
||||
use std::rt::task::Task;
|
||||
use style::{ComputedValues, Stylist};
|
||||
use sync::{Arc, MutexArc};
|
||||
|
||||
#[thread_local]
|
||||
static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;
|
||||
|
|
|
@ -147,7 +147,7 @@ impl Floats {
|
|||
match self.list.get() {
|
||||
None => None,
|
||||
Some(list) => {
|
||||
match list.floats.last_opt() {
|
||||
match list.floats.last() {
|
||||
None => None,
|
||||
Some(float) => Some(float.bounds.origin + self.offset),
|
||||
}
|
||||
|
@ -299,11 +299,11 @@ impl Floats {
|
|||
match info.kind {
|
||||
FloatLeft => {
|
||||
return Rect(Point2D(Au(0), info.ceiling),
|
||||
Size2D(info.max_width, Au(i32::max_value)))
|
||||
Size2D(info.max_width, Au(i32::MAX)))
|
||||
}
|
||||
FloatRight => {
|
||||
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 {
|
||||
FloatLeft => {
|
||||
Rect(Point2D(Au(0), float_y),
|
||||
Size2D(info.max_width, Au(i32::max_value)))
|
||||
Size2D(info.max_width, Au(i32::MAX)))
|
||||
}
|
||||
FloatRight => {
|
||||
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,
|
||||
rect.origin.y,
|
||||
rect.size.width);
|
||||
let height = height.unwrap_or(Au(i32::max_value));
|
||||
let height = height.unwrap_or(Au(i32::MAX));
|
||||
return match info.kind {
|
||||
FloatLeft => {
|
||||
Rect(Point2D(rect.origin.x, float_y),
|
||||
|
|
|
@ -39,7 +39,7 @@ use layout::parallel;
|
|||
use layout::wrapper::ThreadSafeLayoutNode;
|
||||
use layout::flow_list::{FlowList, Link, Rawlink, FlowListIterator, MutFlowListIterator};
|
||||
|
||||
use extra::container::Deque;
|
||||
use collections::Deque;
|
||||
use geom::point::Point2D;
|
||||
use geom::Size2D;
|
||||
use geom::rect::Rect;
|
||||
|
@ -51,7 +51,7 @@ use servo_util::geometry::Au;
|
|||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomics::Relaxed;
|
||||
use std::vec::VecMutIterator;
|
||||
use std::vec::MutItems;
|
||||
use std::iter::Zip;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{text_align, position};
|
||||
|
@ -531,27 +531,34 @@ bitfield!(FlowFlags, override_line_through, set_override_line_through, 0b0000_10
|
|||
impl FlowFlags {
|
||||
#[inline]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
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 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.
|
||||
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| {
|
||||
match *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
|
||||
},
|
||||
_ => false,
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//! indirection.
|
||||
|
||||
use std::cast;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::util;
|
||||
|
||||
use layout::flow::{Flow, base, mut_base};
|
||||
|
||||
|
@ -30,7 +30,6 @@ pub struct FlowList {
|
|||
}
|
||||
|
||||
/// Double-ended FlowList iterator
|
||||
#[deriving(Clone)]
|
||||
pub struct FlowListIterator<'a> {
|
||||
priv head: &'a Link,
|
||||
priv tail: Rawlink,
|
||||
|
@ -156,7 +155,7 @@ impl FlowList {
|
|||
Some(ref mut head) => {
|
||||
mut_base(new_head).prev_sibling = Rawlink::none();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,15 +13,14 @@ use layout::flow;
|
|||
use layout::util::ElementMapping;
|
||||
use layout::wrapper::ThreadSafeLayoutNode;
|
||||
|
||||
use extra::container::Deque;
|
||||
use extra::ringbuf::RingBuf;
|
||||
use collections::{Deque, RingBuf};
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use gfx::display_list::DisplayListCollection;
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::u16;
|
||||
use std::util;
|
||||
use style::computed_values::{text_align, vertical_align, white_space};
|
||||
|
||||
/// Lineboxes are represented as offsets into the child list, rather than
|
||||
|
@ -107,7 +106,7 @@ impl LineboxScanner {
|
|||
if flow.boxes.is_empty() {
|
||||
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());
|
||||
box_
|
||||
} else {
|
||||
|
@ -145,8 +144,8 @@ impl LineboxScanner {
|
|||
debug!("LineboxScanner: Propagating scanned lines[n={:u}] to inline flow",
|
||||
self.lines.len());
|
||||
|
||||
util::swap(&mut flow.boxes, &mut self.new_boxes);
|
||||
util::swap(&mut flow.lines, &mut self.lines);
|
||||
mem::swap(&mut flow.boxes, &mut self.new_boxes);
|
||||
mem::swap(&mut flow.lines, &mut self.lines);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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.extend_by(1);
|
||||
|
@ -872,7 +871,7 @@ impl Flow for InlineFlow {
|
|||
|
||||
self.base.position.size.height =
|
||||
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 {
|
||||
Au::new(0)
|
||||
};
|
||||
|
|
|
@ -22,7 +22,6 @@ use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper};
|
|||
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
|
||||
|
||||
use extra::url::Url;
|
||||
use extra::arc::{Arc, MutexArc};
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
|
@ -55,11 +54,12 @@ use std::cast::transmute;
|
|||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::comm::Port;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::task;
|
||||
use std::util;
|
||||
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist};
|
||||
use style;
|
||||
use sync::{Arc, MutexArc};
|
||||
|
||||
/// Information needed by the layout task.
|
||||
pub struct LayoutTask {
|
||||
|
@ -236,7 +236,8 @@ impl ImageResponder for LayoutImageResponder {
|
|||
let id = self.id.clone();
|
||||
let script_chan = self.script_chan.clone();
|
||||
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
|
||||
}
|
||||
|
@ -255,9 +256,9 @@ impl LayoutTask {
|
|||
opts: Opts,
|
||||
profiler_chan: ProfilerChan,
|
||||
shutdown_chan: Chan<()>) {
|
||||
let mut builder = task::task();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||
builder.name("LayoutTask");
|
||||
let mut builder = task::task().named("LayoutTask");
|
||||
let ConstellationChan(con_chan) = constellation_chan.clone();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), con_chan);
|
||||
builder.spawn(proc() {
|
||||
{ // Ensures layout task is destroyed before we send shutdown message
|
||||
let mut layout = LayoutTask::new(id,
|
||||
|
@ -426,7 +427,7 @@ impl LayoutTask {
|
|||
let mut layout_data_ref = node.mutate_layout_data();
|
||||
let result = match *layout_data_ref.get() {
|
||||
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"),
|
||||
};
|
||||
|
@ -539,11 +540,9 @@ impl LayoutTask {
|
|||
debug!("{:?}", node.dump());
|
||||
|
||||
// Reset the image cache.
|
||||
unsafe {
|
||||
self.local_image_cache.unsafe_access(|local_image_cache| {
|
||||
local_image_cache.next_round(self.make_on_image_available_cb())
|
||||
});
|
||||
}
|
||||
self.local_image_cache.access(|local_image_cache| {
|
||||
local_image_cache.next_round(self.make_on_image_available_cb())
|
||||
});
|
||||
|
||||
// true => Do the reflow with full style damage, because content
|
||||
// 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
|
||||
// either select or a filtered recv() that only looks for messages of a given type.
|
||||
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
|
||||
|
@ -857,6 +857,6 @@ impl LayoutTask {
|
|||
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
|
||||
let mut layout_data_ref = layout_data.borrow_mut();
|
||||
let _: Option<LayoutDataWrapper> = cast::transmute(
|
||||
util::replace(layout_data_ref.get(), None));
|
||||
mem::replace(layout_data_ref.get(), None));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ use style::{Stylist, TNode};
|
|||
#[allow(dead_code)]
|
||||
fn static_assertion(node: UnsafeLayoutNode) {
|
||||
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());
|
||||
|
||||
// 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.
|
||||
//
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
|
||||
use layout::flow::Flow;
|
||||
|
||||
use extra::arc::Arc;
|
||||
use gfx::font_context::FontContext;
|
||||
use gfx::text::text_run::TextRun;
|
||||
use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone};
|
||||
use servo_util::range::Range;
|
||||
use std::vec;
|
||||
use style::computed_values::white_space;
|
||||
use sync::Arc;
|
||||
|
||||
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es.
|
||||
pub struct TextRunScanner {
|
||||
|
|
|
@ -7,7 +7,6 @@ use layout::construct::{ConstructionResult, NoConstructionResult};
|
|||
use layout::parallel::DomParallelInfo;
|
||||
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
|
||||
|
||||
use extra::arc::Arc;
|
||||
use script::dom::bindings::js::JS;
|
||||
use script::dom::bindings::utils::Reflectable;
|
||||
use script::dom::node::Node;
|
||||
|
@ -17,8 +16,9 @@ use std::cast;
|
|||
use std::cell::{Ref, RefMut};
|
||||
use std::iter::Enumerate;
|
||||
use std::libc::uintptr_t;
|
||||
use std::vec::VecIterator;
|
||||
use std::vec::Items;
|
||||
use style::ComputedValues;
|
||||
use sync::Arc;
|
||||
|
||||
/// A range of nodes.
|
||||
pub struct NodeRange {
|
||||
|
@ -59,7 +59,7 @@ impl ElementMapping {
|
|||
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()
|
||||
}
|
||||
|
||||
|
@ -113,8 +113,8 @@ impl ElementMapping {
|
|||
old_i += 1;
|
||||
|
||||
// possibly pop several items
|
||||
while repair_stack.len() > 0 && old_i == entries[repair_stack.last().entry_idx].range.end() {
|
||||
let item = repair_stack.pop();
|
||||
while repair_stack.len() > 0 && old_i == entries[repair_stack.last().get_ref().entry_idx].range.end() {
|
||||
let item = repair_stack.pop().unwrap();
|
||||
debug!("repair_for_box_changes: Set range for {:u} to {}",
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
/// only ever see these and must never see instances of `JS`.
|
||||
#[deriving(Clone, Eq)]
|
||||
pub struct LayoutNode<'a> {
|
||||
/// The wrapped node.
|
||||
priv node: JS<Node>,
|
||||
|
@ -148,6 +147,24 @@ pub struct LayoutNode<'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> {
|
||||
unsafe fn new_with_this_lifetime(&self, node: &JS<Node>) -> LayoutNode<'ln> {
|
||||
LayoutNode {
|
||||
|
@ -244,7 +261,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
|
|||
match attr.namespace {
|
||||
SpecificNamespace(ref ns) => {
|
||||
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
|
||||
AnyNamespace => false,
|
||||
|
|
|
@ -12,12 +12,14 @@ macro_rules! bitfield(
|
|||
impl $bitfieldname {
|
||||
#[inline]
|
||||
pub fn $getter(self) -> bool {
|
||||
(*self & $value) != 0
|
||||
let $bitfieldname(this) = self;
|
||||
(this & $value) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 }))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -20,9 +20,7 @@ use servo_net::resource_task::ResourceTask;
|
|||
use servo_util::opts::Opts;
|
||||
use servo_util::time::ProfilerChan;
|
||||
use std::cell::RefCell;
|
||||
//FIXME: switch to std::rc when we upgrade Rust
|
||||
use layers::temp_rc::Rc;
|
||||
//use std::rc::Rc;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// A uniquely-identifiable pipeline of script task, layout task, and render task.
|
||||
pub struct Pipeline {
|
||||
|
@ -94,7 +92,8 @@ impl Pipeline {
|
|||
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,
|
||||
subpage_id,
|
||||
|
@ -190,16 +189,17 @@ impl Pipeline {
|
|||
|
||||
pub fn load(&self, url: Url) {
|
||||
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) {
|
||||
self.render_chan.try_send(PaintPermissionGranted);
|
||||
self.render_chan.chan.try_send(PaintPermissionGranted);
|
||||
}
|
||||
|
||||
pub fn revoke_paint_permission(&self) {
|
||||
debug!("pipeline revoking render channel paint permission");
|
||||
self.render_chan.try_send(PaintPermissionRevoked);
|
||||
self.render_chan.chan.try_send(PaintPermissionRevoked);
|
||||
}
|
||||
|
||||
pub fn reload(&self) {
|
||||
|
@ -211,7 +211,8 @@ impl Pipeline {
|
|||
pub fn exit(&self) {
|
||||
// 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.
|
||||
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
|
||||
// NOTE: We don't wait for script task as we don't always own it
|
||||
self.render_shutdown_port.recv_opt();
|
||||
|
|
|
@ -12,11 +12,10 @@ use windowing::RefreshWindowEvent;
|
|||
use windowing::{Forward, Back};
|
||||
|
||||
use alert::{Alert, AlertMethods};
|
||||
use extra::time::Timespec;
|
||||
use extra::time;
|
||||
use time;
|
||||
use time::Timespec;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::libc::{exit, c_int};
|
||||
use std::local_data;
|
||||
use std::rc::Rc;
|
||||
|
||||
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(
|
||||
(
|
||||
$callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
|
||||
|
@ -128,64 +120,14 @@ impl WindowMethods<Application> for Window {
|
|||
};
|
||||
|
||||
// Register event handlers.
|
||||
window.glfw_window.set_framebuffer_size_callback(
|
||||
glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) {
|
||||
let tmp = local_window();
|
||||
tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
|
||||
}));
|
||||
window.glfw_window.set_refresh_callback(
|
||||
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;
|
||||
window.glfw_window.set_framebuffer_size_polling(true);
|
||||
window.glfw_window.set_refresh_polling(true);
|
||||
window.glfw_window.set_key_polling(true);
|
||||
window.glfw_window.set_mouse_button_polling(true);
|
||||
window.glfw_window.set_cursor_pos_polling(true);
|
||||
window.glfw_window.set_scroll_polling(true);
|
||||
|
||||
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;
|
||||
|
||||
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());
|
||||
let wrapped_window = Rc::new(window);
|
||||
|
||||
wrapped_window
|
||||
}
|
||||
|
@ -203,14 +145,18 @@ impl WindowMethods<Application> for Window {
|
|||
|
||||
fn recv(&self) -> WindowEvent {
|
||||
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();
|
||||
for (_, event) in self.glfw_window.flush_events() {
|
||||
self.handle_window_event(&self.glfw_window, event);
|
||||
}
|
||||
|
||||
if self.glfw_window.should_close() {
|
||||
QuitWindowEvent
|
||||
} 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 {
|
||||
IdleWindowEvent
|
||||
}
|
||||
|
@ -243,6 +189,52 @@ impl WindowMethods<Application> for 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.
|
||||
fn update_window_title(&self) {
|
||||
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())
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ impl WindowMethods<Application> for Window {
|
|||
}
|
||||
glut::mouse_func(~MouseCallbackState);
|
||||
|
||||
let wrapped_window = Rc::from_send(window);
|
||||
let wrapped_window = Rc::new(window);
|
||||
|
||||
install_local_window(wrapped_window.clone());
|
||||
|
||||
|
@ -151,11 +151,11 @@ impl WindowMethods<Application> for Window {
|
|||
|
||||
fn recv(&self) -> WindowEvent {
|
||||
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();
|
||||
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 {
|
||||
IdleWindowEvent
|
||||
}
|
||||
|
|
|
@ -8,43 +8,47 @@
|
|||
|
||||
#[feature(globs, macro_rules, managed_boxes, thread_local)];
|
||||
|
||||
extern mod alert;
|
||||
extern mod azure;
|
||||
extern mod geom;
|
||||
extern mod gfx;
|
||||
extern crate alert;
|
||||
extern crate azure;
|
||||
extern crate geom;
|
||||
extern crate gfx;
|
||||
#[cfg(not(target_os="android"))]
|
||||
extern mod glfw;
|
||||
extern crate glfw = "glfw-rs";
|
||||
#[cfg(target_os="android")]
|
||||
extern mod glut;
|
||||
extern mod js;
|
||||
extern mod layers;
|
||||
extern mod opengles;
|
||||
extern mod png;
|
||||
extern crate glut;
|
||||
extern crate js;
|
||||
extern crate layers;
|
||||
extern crate opengles;
|
||||
extern crate png;
|
||||
#[cfg(target_os="android")]
|
||||
extern mod rustuv;
|
||||
extern mod script;
|
||||
extern mod servo_net = "net";
|
||||
extern mod servo_msg = "msg";
|
||||
extern mod servo_util = "util";
|
||||
extern mod style;
|
||||
extern mod sharegl;
|
||||
extern mod stb_image;
|
||||
extern crate rustuv;
|
||||
extern crate script;
|
||||
extern crate servo_net = "net";
|
||||
extern crate servo_msg = "msg";
|
||||
extern crate servo_util = "util";
|
||||
extern crate style;
|
||||
extern crate sharegl;
|
||||
extern crate stb_image;
|
||||
|
||||
extern mod extra;
|
||||
extern mod green;
|
||||
extern mod native;
|
||||
extern crate collections;
|
||||
extern crate extra;
|
||||
extern crate green;
|
||||
extern crate native;
|
||||
extern crate serialize;
|
||||
extern crate sync;
|
||||
extern crate time;
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
extern mod core_graphics;
|
||||
extern crate core_graphics;
|
||||
#[cfg(target_os="macos")]
|
||||
extern mod core_text;
|
||||
extern crate core_text;
|
||||
|
||||
#[cfg(not(test))]
|
||||
use compositing::{CompositorChan, CompositorTask};
|
||||
#[cfg(not(test))]
|
||||
use constellation::Constellation;
|
||||
#[cfg(not(test))]
|
||||
use servo_msg::constellation_msg::InitLoadUrlMsg;
|
||||
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
|
||||
|
||||
#[cfg(not(test))]
|
||||
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
|
||||
|
@ -109,9 +113,6 @@ pub mod windowing;
|
|||
#[path="platform/mod.rs"]
|
||||
pub mod platform;
|
||||
|
||||
#[path = "util/mod.rs"]
|
||||
pub mod util;
|
||||
|
||||
#[cfg(not(test), target_os="linux")]
|
||||
#[cfg(not(test), target_os="macos")]
|
||||
#[start]
|
||||
|
@ -175,7 +176,8 @@ fn run(opts: opts::Opts) {
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
}
|
|
@ -11,7 +11,7 @@ use layers::platform::surface::{NativeSurface, NativeSurfaceMethods};
|
|||
|
||||
use constellation_msg::PipelineId;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
pub struct LayerBuffer {
|
||||
/// 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 {
|
||||
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;
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for @ScriptListener {
|
||||
impl<S: Encoder> Encodable<S> for ~ScriptListener {
|
||||
fn encode(&self, _s: &mut S) {
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +126,7 @@ impl Tile for ~LayerBuffer {
|
|||
self.screen_pos.size.width * self.screen_pos.size.height
|
||||
}
|
||||
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> {
|
||||
self.screen_pos.size
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
use extra::url::Url;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
use std::comm::SharedChan;
|
||||
use std::comm::Chan;
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct ConstellationChan(SharedChan<Msg>);
|
||||
pub struct ConstellationChan(Chan<Msg>);
|
||||
|
||||
impl ConstellationChan {
|
||||
pub fn new() -> (Port<Msg>, ConstellationChan) {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
(port, ConstellationChan(chan))
|
||||
}
|
||||
}
|
||||
|
@ -48,20 +48,20 @@ pub enum Msg {
|
|||
}
|
||||
|
||||
/// Represents the two different ways to which a page can be navigated
|
||||
#[deriving(Clone, Eq, IterBytes)]
|
||||
#[deriving(Clone, Eq, Hash)]
|
||||
pub enum NavigationType {
|
||||
Load, // entered or clicked on a url
|
||||
Navigate, // browser forward/back buttons
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, IterBytes)]
|
||||
#[deriving(Clone, Eq, Hash)]
|
||||
pub enum NavigationDirection {
|
||||
Forward,
|
||||
Back,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, IterBytes, Encodable)]
|
||||
#[deriving(Clone, Eq, Hash, Encodable)]
|
||||
pub struct PipelineId(uint);
|
||||
|
||||
#[deriving(Clone, Eq, IterBytes, Encodable)]
|
||||
#[deriving(Clone, Eq, Hash, Encodable)]
|
||||
pub struct SubpageId(uint);
|
||||
|
|
|
@ -7,16 +7,17 @@
|
|||
|
||||
#[feature(managed_boxes)];
|
||||
|
||||
extern mod azure;
|
||||
extern mod extra;
|
||||
extern mod geom;
|
||||
extern mod layers;
|
||||
extern mod std;
|
||||
extern crate azure;
|
||||
extern crate extra;
|
||||
extern crate geom;
|
||||
extern crate layers;
|
||||
extern crate serialize;
|
||||
extern crate std;
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
extern mod core_foundation;
|
||||
extern crate core_foundation;
|
||||
#[cfg(target_os="macos")]
|
||||
extern mod io_surface;
|
||||
extern crate io_surface;
|
||||
|
||||
pub mod compositor_msg;
|
||||
pub mod constellation_msg;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending};
|
||||
|
||||
use extra::url::Url;
|
||||
use extra::base64::FromBase64;
|
||||
use serialize::base64::FromBase64;
|
||||
|
||||
use http::headers::test_utils::from_stream_with_str;
|
||||
use http::headers::content_type::MediaType;
|
||||
|
|
|
@ -3,22 +3,20 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending};
|
||||
use servo_util::io::result;
|
||||
|
||||
use std::io;
|
||||
use std::io::File;
|
||||
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<(), ()> {
|
||||
loop {
|
||||
match (result(|| {
|
||||
let data = reader.read_bytes(READ_SIZE);
|
||||
progress_chan.send(Payload(data));
|
||||
})) {
|
||||
Ok(()) => (),
|
||||
let mut buf = ~[];
|
||||
match reader.push_bytes(&mut buf, READ_SIZE) {
|
||||
Ok(_) => progress_chan.send(Payload(buf)),
|
||||
Err(e) => match e.kind {
|
||||
io::EndOfFile => return Ok(()),
|
||||
_ => return Err(()),
|
||||
|
@ -32,14 +30,12 @@ pub fn factory() -> LoaderTask {
|
|||
assert!("file" == url.scheme);
|
||||
let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
|
||||
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) {
|
||||
Some(ref mut reader) => {
|
||||
Ok(ref mut reader) => {
|
||||
let res = read_all(reader as &mut io::Stream, &progress_chan);
|
||||
progress_chan.send(Done(res));
|
||||
}
|
||||
None => {
|
||||
Err(_) => {
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
|
||||
|
||||
use std::vec;
|
||||
use std::hashmap::HashSet;
|
||||
use collections::hashmap::HashSet;
|
||||
use extra::url::Url;
|
||||
use http::client::RequestWriter;
|
||||
use http::method::Get;
|
||||
use http::headers::HeaderEnum;
|
||||
use std::io::Reader;
|
||||
use std::io::net::tcp::TcpStream;
|
||||
use servo_util::task::spawn_named;
|
||||
|
||||
pub fn factory() -> LoaderTask {
|
||||
|
@ -55,8 +56,15 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
|
|||
|
||||
info!("requesting {:s}", url.to_str());
|
||||
|
||||
let request = ~RequestWriter::new(Get, url.clone());
|
||||
let mut response = match request.read_response() {
|
||||
let request = RequestWriter::<TcpStream>::new(Get, url.clone());
|
||||
let writer = match request {
|
||||
Ok(w) => ~w,
|
||||
Err(_) => {
|
||||
send_error(url, start_chan);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut response = match writer.read_response() {
|
||||
Ok(r) => r,
|
||||
Err(_) => {
|
||||
send_error(url, start_chan);
|
||||
|
@ -91,11 +99,11 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
|
|||
|
||||
unsafe { buf.set_len(1024); }
|
||||
match response.read(buf) {
|
||||
Some(len) => {
|
||||
Ok(len) => {
|
||||
unsafe { buf.set_len(len); }
|
||||
progress_chan.send(Payload(buf));
|
||||
}
|
||||
None => {
|
||||
Err(_) => {
|
||||
progress_chan.send(Done(Ok(())));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
|
||||
stb_image::Error => None
|
||||
stb_image::Error(_) => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ use image::base::Image;
|
|||
use image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
|
||||
use local_image_cache::LocalImageCache;
|
||||
|
||||
use extra::arc::{Arc, MutexArc};
|
||||
use sync::{Arc, MutexArc};
|
||||
use extra::url::Url;
|
||||
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
|
||||
// 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
|
||||
// should be done as early as possible and decode only once we
|
||||
// are sure that the image will be used.
|
||||
unsafe {
|
||||
holder.local_image_cache.unsafe_access(|local_image_cache| {
|
||||
local_image_cache.prefetch(&holder.url);
|
||||
local_image_cache.decode(&holder.url);
|
||||
});
|
||||
}
|
||||
holder.local_image_cache.access(|local_image_cache| {
|
||||
local_image_cache.prefetch(&holder.url);
|
||||
local_image_cache.decode(&holder.url);
|
||||
});
|
||||
|
||||
holder
|
||||
}
|
||||
|
@ -76,11 +74,10 @@ impl ImageHolder {
|
|||
// If this is the first time we've called this function, load
|
||||
// the image and store it for the future
|
||||
if self.image.is_none() {
|
||||
let port = unsafe {
|
||||
self.local_image_cache.unsafe_access(|local_image_cache| {
|
||||
let port =
|
||||
self.local_image_cache.access(|local_image_cache| {
|
||||
local_image_cache.get_image(&self.url)
|
||||
})
|
||||
};
|
||||
});
|
||||
match port.recv() {
|
||||
ImageReady(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
|
||||
let image = util::replace(&mut self.image, None);
|
||||
let image = mem::replace(&mut self.image, None);
|
||||
let result = image.clone();
|
||||
util::replace(&mut self.image, image);
|
||||
mem::replace(&mut self.image, image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ use resource_task;
|
|||
use resource_task::ResourceTask;
|
||||
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::to_str::ToStr;
|
||||
use std::util::replace;
|
||||
use std::result;
|
||||
use extra::arc::{Arc,MutexArc};
|
||||
use sync::{Arc,MutexArc};
|
||||
use extra::url::Url;
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
pub enum Msg {
|
||||
/// Tell the cache that we may need a particular image soon. Must be posted
|
||||
|
@ -78,7 +78,7 @@ impl Eq for ImageResponseMsg {
|
|||
|
||||
#[deriving(Clone)]
|
||||
pub struct ImageCacheTask {
|
||||
chan: SharedChan<Msg>,
|
||||
chan: Chan<Msg>,
|
||||
}
|
||||
|
||||
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>;
|
||||
|
||||
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
let chan_clone = chan.clone();
|
||||
|
||||
spawn(proc() {
|
||||
|
@ -111,7 +111,7 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
|||
|
||||
// FIXME: make this priv after visibility rules change
|
||||
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
|
||||
spawn(proc() {
|
||||
let inner_cache = ImageCacheTask(resource_task.clone());
|
||||
|
@ -143,7 +143,7 @@ struct ImageCache {
|
|||
/// The port on which we'll receive client requests
|
||||
port: Port<Msg>,
|
||||
/// 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
|
||||
state_map: UrlMap<ImageState>,
|
||||
/// List of clients waiting on a WaitForImage response
|
||||
|
@ -375,13 +375,11 @@ impl ImageCache {
|
|||
fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) {
|
||||
match self.wait_map.pop(&url) {
|
||||
Some(waiters) => {
|
||||
unsafe {
|
||||
waiters.unsafe_access(|waiters| {
|
||||
for response in waiters.iter() {
|
||||
response.send(f());
|
||||
}
|
||||
});
|
||||
}
|
||||
waiters.access(|waiters| {
|
||||
for response in waiters.iter() {
|
||||
response.send(f());
|
||||
}
|
||||
});
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
@ -409,9 +407,7 @@ impl ImageCache {
|
|||
if self.wait_map.contains_key(&url) {
|
||||
let waiters = self.wait_map.find_mut(&url).unwrap();
|
||||
let mut response = Some(response);
|
||||
unsafe {
|
||||
waiters.unsafe_access(|waiters| waiters.push(response.take().unwrap()))
|
||||
}
|
||||
waiters.access(|waiters| waiters.push(response.take().unwrap()));
|
||||
} else {
|
||||
self.wait_map.insert(url, MutexArc::new(~[response]));
|
||||
}
|
||||
|
@ -430,7 +426,7 @@ impl ImageCache {
|
|||
}
|
||||
|
||||
|
||||
trait ImageCacheTaskClient {
|
||||
pub trait ImageCacheTaskClient {
|
||||
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -492,11 +500,11 @@ mod tests {
|
|||
use resource_task;
|
||||
use resource_task::{ResourceTask, Metadata, start_sending};
|
||||
use image::base::test_image_bin;
|
||||
use util::spawn_listener;
|
||||
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 {
|
||||
spawn_listener("mock_resource_task", proc(port: Port<resource_task::ControlMsg>) {
|
||||
fn mock_resource_task(on_load: proc(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
||||
spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
|
||||
loop {
|
||||
match port.recv() {
|
||||
resource_task::Load(_, response) => {
|
||||
|
@ -568,7 +576,10 @@ mod tests {
|
|||
url_requested.recv();
|
||||
image_cache_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]
|
||||
|
@ -662,7 +673,7 @@ mod tests {
|
|||
|
||||
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 {
|
||||
match port.recv() {
|
||||
resource_task::Load(_, response) => {
|
||||
|
@ -696,7 +707,10 @@ mod tests {
|
|||
|
||||
// Our resource task should not have received another request for the image
|
||||
// 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]
|
||||
|
@ -705,7 +719,7 @@ mod tests {
|
|||
|
||||
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 {
|
||||
match port.recv() {
|
||||
resource_task::Load(_, response) => {
|
||||
|
@ -741,7 +755,10 @@ mod tests {
|
|||
|
||||
// Our resource task should not have received another request for the image
|
||||
// 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]
|
||||
|
|
|
@ -126,11 +126,11 @@ impl LocalImageCache {
|
|||
assert!(self.on_image_available.is_some());
|
||||
let on_image_available = self.on_image_available.as_ref().unwrap().respond();
|
||||
let url = (*url).clone();
|
||||
do spawn_named("LocalImageCache") {
|
||||
spawn_named("LocalImageCache", proc() {
|
||||
let (response_port, response_chan) = Chan::new();
|
||||
image_cache_task.send(WaitForImage(url.clone(), response_chan));
|
||||
on_image_available(response_port.recv());
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
|
||||
#[feature(globs, managed_boxes)];
|
||||
|
||||
extern mod geom;
|
||||
extern mod http;
|
||||
extern mod servo_util = "util";
|
||||
extern mod stb_image;
|
||||
extern mod extra;
|
||||
extern mod png;
|
||||
extern crate collections;
|
||||
extern crate geom;
|
||||
extern crate http;
|
||||
extern crate servo_util = "util";
|
||||
extern crate stb_image;
|
||||
extern crate extra;
|
||||
extern crate png;
|
||||
extern crate serialize;
|
||||
extern crate sync;
|
||||
|
||||
/// Image handling.
|
||||
///
|
||||
|
@ -30,5 +33,4 @@ pub mod data_loader;
|
|||
pub mod image_cache_task;
|
||||
pub mod local_image_cache;
|
||||
pub mod resource_task;
|
||||
pub mod util;
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ use file_loader;
|
|||
use http_loader;
|
||||
use data_loader;
|
||||
|
||||
use std::comm::{Chan, Port, SharedChan};
|
||||
use std::comm::{Chan, Port};
|
||||
use std::task;
|
||||
use extra::url::Url;
|
||||
use util::spawn_listener;
|
||||
use http::headers::content_type::MediaType;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -85,8 +85,8 @@ pub enum ProgressMsg {
|
|||
|
||||
/// For use by loaders in responding to a Load message.
|
||||
pub fn start_sending(start_chan: Chan<LoadResponse>,
|
||||
metadata: Metadata) -> SharedChan<ProgressMsg> {
|
||||
let (progress_port, progress_chan) = SharedChan::new();
|
||||
metadata: Metadata) -> Chan<ProgressMsg> {
|
||||
let (progress_port, progress_chan) = Chan::new();
|
||||
start_chan.send(LoadResponse {
|
||||
metadata: metadata,
|
||||
progress_port: progress_port,
|
||||
|
@ -112,7 +112,7 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
|||
}
|
||||
|
||||
/// Handle to a resource task
|
||||
pub type ResourceTask = SharedChan<ControlMsg>;
|
||||
pub type ResourceTask = Chan<ControlMsg>;
|
||||
|
||||
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 {
|
||||
let chan = spawn_listener("ResourceManager", proc(from_client) {
|
||||
// TODO: change copy to move once we can move out of closures
|
||||
ResourceManager(from_client, loaders).start()
|
||||
let (setup_port, setup_chan) = Chan::new();
|
||||
let builder = task::task().named("ResourceManager");
|
||||
builder.spawn(proc() {
|
||||
let (port, chan) = Chan::new();
|
||||
setup_chan.send(chan);
|
||||
ResourceManager(port, loaders).start();
|
||||
});
|
||||
chan
|
||||
setup_port.recv()
|
||||
}
|
||||
|
||||
pub struct ResourceManager {
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -35,7 +35,7 @@ impl AttrList {
|
|||
}
|
||||
|
||||
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>> {
|
||||
|
|
|
@ -12,17 +12,17 @@ use std::cast;
|
|||
use std::libc;
|
||||
use std::ptr;
|
||||
|
||||
use extra::serialize::{Encodable, Encoder};
|
||||
use serialize::{Encodable, Encoder};
|
||||
|
||||
pub enum ExceptionHandling {
|
||||
// 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
|
||||
// binding object for a DOMError from the caller's scope, otherwise report
|
||||
// it.
|
||||
eRethrowContentExceptions,
|
||||
RethrowContentExceptions,
|
||||
// Throw any exception to the caller code.
|
||||
eRethrowExceptions
|
||||
RethrowExceptions
|
||||
}
|
||||
|
||||
#[deriving(Clone,Eq)]
|
||||
|
|
|
@ -184,7 +184,7 @@ class CGMethodCall(CGThing):
|
|||
|
||||
if requiredArgs > 0:
|
||||
code = (
|
||||
"if (argc < %d) {\n"
|
||||
"if argc < %d {\n"
|
||||
" return 0; //XXXjdm throw exception\n"
|
||||
" //return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, %s);\n"
|
||||
"}" % (requiredArgs, methodName))
|
||||
|
@ -370,7 +370,7 @@ class CGMethodCall(CGThing):
|
|||
|
||||
overloadCGThings = []
|
||||
overloadCGThings.append(
|
||||
CGGeneric("let argcount = argc.min(&%d);" %
|
||||
CGGeneric("let argcount = cmp::min(argc, %d);" %
|
||||
maxArgCount))
|
||||
overloadCGThings.append(
|
||||
CGSwitch("argcount",
|
||||
|
@ -389,7 +389,7 @@ class CGMethodCall(CGThing):
|
|||
class FakeCastableDescriptor():
|
||||
def __init__(self, descriptor):
|
||||
self.castable = True
|
||||
self.nativeType = "*Box<%s>" % descriptor.concreteType
|
||||
self.nativeType = "*%s" % descriptor.concreteType
|
||||
self.name = descriptor.name
|
||||
class FakeInterface:
|
||||
def inheritanceDepth(self):
|
||||
|
@ -720,7 +720,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
|||
return handleDefault(conversionCode,
|
||||
"${declName}.SetNull()")
|
||||
|
||||
value = "str::from_utf8(data).to_owned()"
|
||||
value = "str::from_utf8(data).unwrap().to_owned()"
|
||||
if type.nullable():
|
||||
value = "Some(%s)" % value
|
||||
|
||||
|
@ -993,7 +993,7 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
|
|||
|
||||
conversion = CGList(
|
||||
[CGGeneric(
|
||||
string.Template("if (${index} < ${argc}) {").substitute(
|
||||
string.Template("if ${index} < ${argc} {").substitute(
|
||||
argcAndIndex
|
||||
)),
|
||||
declConstruct,
|
||||
|
@ -1132,7 +1132,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
|||
raise TypeError("We don't support nullable enumerated return types "
|
||||
"yet")
|
||||
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() {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1641,7 +1641,9 @@ class CGImports(CGWrapper):
|
|||
# sometimes produces two 'break's in a row. See for example
|
||||
# CallbackMember.getArgConversions.
|
||||
'unreachable_code',
|
||||
'non_camel_case_types',
|
||||
'non_uppercase_statics',
|
||||
'unnecessary_parens',
|
||||
'unused_imports',
|
||||
'unused_variable',
|
||||
'unused_unsafe',
|
||||
|
@ -1688,11 +1690,11 @@ class CGNamespace(CGWrapper):
|
|||
|
||||
def DOMClass(descriptor):
|
||||
protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain]
|
||||
# Pad out the list to the right length with _ID_Count so we
|
||||
# guarantee that all the lists are the same length. _ID_Count
|
||||
# Pad out the list to the right length with IDCount so we
|
||||
# guarantee that all the lists are the same length. IDCount
|
||||
# is never the ID of any prototype, so it's safe to use as
|
||||
# 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)
|
||||
return """DOMClass {
|
||||
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));
|
||||
""" % descriptor.name
|
||||
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,
|
||||
ptr::null(), ptr::null());
|
||||
if obj.is_null() {
|
||||
|
@ -2084,7 +2086,7 @@ def CreateBindingJSObject(descriptor, parent=None):
|
|||
}
|
||||
|
||||
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
|
||||
|
||||
|
@ -2230,7 +2232,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
val = ('%(' + name + ')s') % self.properties.variableNames(False)
|
||||
if val == "ptr::null()":
|
||||
return val
|
||||
return "ptr::to_unsafe_ptr(&%s[0])" % val
|
||||
return "&%s[0]" % val
|
||||
|
||||
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
|
||||
%s, %s, %d,
|
||||
|
@ -2376,7 +2378,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
|||
trace: %s
|
||||
};
|
||||
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,
|
||||
('Some(%s)' % TRACE_HOOK_NAME),
|
||||
|
@ -2388,7 +2390,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
|||
body = "" #XXXjdm xray stuff isn't necessary yet
|
||||
|
||||
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);
|
||||
return %s(cx, global, receiver).is_not_null();""" % (getter))
|
||||
|
||||
|
@ -2469,7 +2471,7 @@ class CGCallGenerator(CGThing):
|
|||
self.cgRoot.append(call)
|
||||
|
||||
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(CGGeneric("}"))
|
||||
if result is not None:
|
||||
|
@ -2693,7 +2695,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
|
|||
" return false as JSBool;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"let this: *Box<%s>;" % self.descriptor.concreteType))
|
||||
"let this: *%s;" % self.descriptor.concreteType))
|
||||
|
||||
def generate_code(self):
|
||||
assert(False) # Override me
|
||||
|
@ -2721,7 +2723,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
|
|||
self.method = method
|
||||
name = method.identifier.name
|
||||
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')]
|
||||
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
|
||||
|
||||
|
@ -2732,13 +2734,13 @@ class CGSpecializedMethod(CGAbstractExternMethod):
|
|||
argsPre = []
|
||||
if name in self.descriptor.needsAbstract:
|
||||
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']
|
||||
return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(),
|
||||
self.descriptor, self.method),
|
||||
pre=extraPre +
|
||||
" let obj = (*obj.unnamed);\n" +
|
||||
" let this = &mut (*this).data;\n").define()
|
||||
" let obj = *obj.unnamed;\n" +
|
||||
" let this = &mut *this;\n").define()
|
||||
|
||||
class CGGenericGetter(CGAbstractBindingMethod):
|
||||
"""
|
||||
|
@ -2776,7 +2778,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
|
|||
name = 'get_' + attr.identifier.name
|
||||
args = [ Argument('*JSContext', 'cx'),
|
||||
Argument('JSHandleObject', 'obj'),
|
||||
Argument('*mut Box<%s>' % descriptor.concreteType, 'this'),
|
||||
Argument('*mut %s' % descriptor.concreteType, 'this'),
|
||||
Argument('*mut JSVal', 'vp') ]
|
||||
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
|
||||
|
||||
|
@ -2790,15 +2792,15 @@ class CGSpecializedGetter(CGAbstractExternMethod):
|
|||
getter=True))
|
||||
if name in self.descriptor.needsAbstract:
|
||||
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']
|
||||
if self.attr.type.nullable() or not infallible:
|
||||
nativeName = "Get" + nativeName
|
||||
return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName,
|
||||
self.descriptor, self.attr)),
|
||||
pre=extraPre +
|
||||
" let obj = (*obj.unnamed);\n" +
|
||||
" let this = &mut (*this).data;\n").define()
|
||||
" let obj = *obj.unnamed;\n" +
|
||||
" let this = &mut *this;\n").define()
|
||||
|
||||
class CGGenericSetter(CGAbstractBindingMethod):
|
||||
"""
|
||||
|
@ -2842,7 +2844,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
|
|||
name = 'set_' + attr.identifier.name
|
||||
args = [ Argument('*JSContext', 'cx'),
|
||||
Argument('JSHandleObject', 'obj'),
|
||||
Argument('*mut Box<%s>' % descriptor.concreteType, 'this'),
|
||||
Argument('*mut %s' % descriptor.concreteType, 'this'),
|
||||
Argument('*mut JSVal', 'argv')]
|
||||
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
|
||||
|
||||
|
@ -2853,13 +2855,13 @@ class CGSpecializedSetter(CGAbstractExternMethod):
|
|||
extraPre = ''
|
||||
if name in self.descriptor.needsAbstract:
|
||||
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']
|
||||
return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName,
|
||||
self.descriptor, self.attr)),
|
||||
pre=extraPre +
|
||||
" let obj = (*obj.unnamed);\n" +
|
||||
" let this = &mut (*this).data;\n").define()
|
||||
" let obj = *obj.unnamed;\n" +
|
||||
" let this = &mut *this;\n").define()
|
||||
|
||||
def infallibleForMember(member, type, descriptorProvider):
|
||||
"""
|
||||
|
@ -3891,8 +3893,8 @@ class CGProxyUnwrap(CGAbstractMethod):
|
|||
obj = js::UnwrapObject(obj);
|
||||
}*/
|
||||
//MOZ_ASSERT(IsProxy(obj));
|
||||
let box_: *Box<%s> = cast::transmute(GetProxyPrivate(obj).to_private());
|
||||
return ptr::to_unsafe_ptr(&(*box_).data);""" % (self.descriptor.concreteType)
|
||||
let box_: *%s = cast::transmute(GetProxyPrivate(obj).to_private());
|
||||
return box_;""" % (self.descriptor.concreteType)
|
||||
|
||||
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
|
||||
def __init__(self, descriptor):
|
||||
|
@ -3913,7 +3915,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
|
|||
if indexedGetter:
|
||||
readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
|
||||
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}
|
||||
get = ("if index.is_some() {\n" +
|
||||
" let index = index.unwrap();\n" +
|
||||
|
@ -3955,7 +3957,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
|
|||
if namedGetter:
|
||||
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
|
||||
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}
|
||||
# Once we start supporting OverrideBuiltins we need to make
|
||||
# ResolveOwnProperty or EnumerateOwnProperties filter out named
|
||||
|
@ -4101,7 +4103,7 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
|
|||
getFromExpando = """let expando = GetExpandoObject(proxy);
|
||||
if expando.is_not_null() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4201,7 +4203,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
|
|||
|
||||
def definition_body_prologue(self):
|
||||
return """
|
||||
let this: *%s = &(*unwrap::<*Box<%s>>(obj)).data;
|
||||
let this: *%s = unwrap::<*%s>(obj);
|
||||
""" % (self.descriptor.concreteType, self.descriptor.concreteType)
|
||||
|
||||
def definition_body(self):
|
||||
|
@ -4407,7 +4409,7 @@ class CGNamespacedEnum(CGThing):
|
|||
entries.append(entry)
|
||||
|
||||
# Append a Count.
|
||||
entries.append('_' + enumName + '_Count = ' + str(len(entries)))
|
||||
entries.append(enumName + 'Count = ' + str(len(entries)))
|
||||
|
||||
# Indent.
|
||||
entries = [' ' + e for e in entries]
|
||||
|
@ -4537,7 +4539,7 @@ class CGDictionary(CGThing):
|
|||
"\n"
|
||||
" pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n"
|
||||
" unsafe {\n"
|
||||
" if (!initedIds && !self.InitIds(cx)) {\n"
|
||||
" if !initedIds && !self.InitIds(cx) {\n"
|
||||
" return 0;\n"
|
||||
" }\n"
|
||||
"${initParent}"
|
||||
|
@ -4604,15 +4606,15 @@ class CGDictionary(CGThing):
|
|||
|
||||
if True: #XXXjdm hack until 'static mut' exists for global jsids
|
||||
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)
|
||||
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)
|
||||
else:
|
||||
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)
|
||||
propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, ptr::to_unsafe_ptr(&temp))" %
|
||||
propGet = ("JS_GetPropertyById(cx, val.to_object(), %s, &temp)" %
|
||||
propId)
|
||||
|
||||
conversionReplacements = {
|
||||
|
@ -4796,7 +4798,7 @@ class CGBindingRoot(CGThing):
|
|||
'dom::bindings::utils::{NativePropertyHooks}',
|
||||
'dom::bindings::utils::global_object_for_js_object',
|
||||
'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::{unwrap_object, VoidVal, with_gc_disabled}',
|
||||
'dom::bindings::utils::{with_gc_enabled, XrayResolveProperty}',
|
||||
|
@ -4818,12 +4820,13 @@ class CGBindingRoot(CGThing):
|
|||
'servo_util::str::DOMString',
|
||||
'servo_util::vec::zip_copies',
|
||||
'std::cast',
|
||||
'std::cmp',
|
||||
'std::libc',
|
||||
'std::ptr',
|
||||
'std::vec',
|
||||
'std::str',
|
||||
'std::num',
|
||||
'std::unstable::raw::Box',
|
||||
'std::intrinsics::uninit',
|
||||
])
|
||||
|
||||
# Add the auto-generated comment.
|
||||
|
@ -5223,7 +5226,7 @@ class CGCallback(CGClass):
|
|||
# method, insert our optional argument for deciding whether the
|
||||
# CallSetup should re-throw exceptions on aRv.
|
||||
args.append(Argument("ExceptionHandling", "aExceptionHandling",
|
||||
"eReportExceptions"))
|
||||
"ReportExceptions"))
|
||||
|
||||
args[0] = Argument('&' + args[0].argType, args[0].name, args[0].default)
|
||||
method.args[2] = args[0]
|
||||
|
@ -5515,7 +5518,7 @@ class CallbackMember(CGNativeMember):
|
|||
args.append(Argument("JSCompartment*", "aCompartment", "nullptr"))
|
||||
else:
|
||||
args.append(Argument("ExceptionHandling", "aExceptionHandling",
|
||||
"eReportExceptions"))
|
||||
"ReportExceptions"))
|
||||
return args
|
||||
# We want to allow the caller to pass in a "this" object, as
|
||||
# well as a JSContext.
|
||||
|
@ -5530,7 +5533,7 @@ class CallbackMember(CGNativeMember):
|
|||
if self.rethrowContentException:
|
||||
# getArgs doesn't add the aExceptionHandling argument but does add
|
||||
# aCompartment for us.
|
||||
callSetup += ", eRethrowContentExceptions, aCompartment"
|
||||
callSetup += ", RethrowContentExceptions, aCompartment"
|
||||
else:
|
||||
callSetup += ", aExceptionHandling"
|
||||
callSetup += ");"
|
||||
|
@ -5767,7 +5770,7 @@ class GlobalGenRoots():
|
|||
CGGeneric("use dom::types::*;\n"),
|
||||
CGGeneric("use dom::bindings::js::JS;\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")]
|
||||
for descriptor in descriptors:
|
||||
name = descriptor.name
|
||||
|
|
|
@ -7,7 +7,7 @@ use js::jsapi::{JS_IsExceptionPending};
|
|||
|
||||
use js::glue::{ReportError};
|
||||
|
||||
#[deriving(ToStr)]
|
||||
#[deriving(Show)]
|
||||
pub enum Error {
|
||||
FailureUnknown,
|
||||
NotFound,
|
||||
|
|
|
@ -9,7 +9,6 @@ use layout_interface::TrustedNodeAddress;
|
|||
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::unstable::raw::Box;
|
||||
|
||||
pub struct JS<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> {
|
||||
JS {
|
||||
ptr: RefCell::new(inner as *mut T)
|
||||
|
|
|
@ -19,12 +19,10 @@ use std::ptr;
|
|||
use std::str;
|
||||
use std::mem::size_of;
|
||||
|
||||
type c_bool = libc::c_int;
|
||||
|
||||
static JSPROXYSLOT_EXPANDO: u32 = 0;
|
||||
|
||||
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 {
|
||||
let handler = GetProxyHandler(proxy);
|
||||
if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) == 0 {
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::cast;
|
|||
use std::libc;
|
||||
use std::ptr;
|
||||
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
|
||||
// any encoder but JSTracer. Since we derive trace hooks automatically,
|
||||
|
|
|
@ -8,16 +8,15 @@ use dom::bindings::js::JS;
|
|||
use dom::window;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
use std::libc::c_uint;
|
||||
use std::cast;
|
||||
use std::cmp::Eq;
|
||||
use std::hashmap::HashMap;
|
||||
use std::libc;
|
||||
use std::ptr;
|
||||
use std::ptr::null;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use std::unstable::raw::Box;
|
||||
use js::glue::*;
|
||||
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
||||
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,
|
||||
proto_id: PrototypeList::id::ID,
|
||||
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| {
|
||||
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 {
|
||||
cast::transmute(x)
|
||||
}
|
||||
|
@ -149,7 +144,7 @@ pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString {
|
|||
let length = 0;
|
||||
let chars = JS_GetStringCharsAndLength(cx, s, &length);
|
||||
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) {
|
||||
let protoArray = ~([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]);
|
||||
let protoArray = ~([0 as *JSObject, ..PrototypeList::id::IDCount as uint]);
|
||||
unsafe {
|
||||
let box_ = squirrel_away_unboxed(protoArray);
|
||||
JS_SetReservedSlot(global,
|
||||
|
@ -437,7 +432,6 @@ pub fn reflect_dom_object<T: Reflectable>
|
|||
#[deriving(Eq)]
|
||||
pub struct Reflector {
|
||||
object: *JSObject,
|
||||
force_box_layout: @int,
|
||||
}
|
||||
|
||||
impl Reflector {
|
||||
|
@ -455,7 +449,6 @@ impl Reflector {
|
|||
pub fn new() -> Reflector {
|
||||
Reflector {
|
||||
object: ptr::null(),
|
||||
force_box_layout: @1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -470,7 +463,7 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
|
|||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
*found = hasProp != 0;
|
||||
|
@ -651,8 +644,8 @@ pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
|
|||
let clasp = JS_GetClass(global);
|
||||
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
|
||||
// FIXME(jdm): Either don't hardcode or sanity assert prototype stuff.
|
||||
match unwrap_object::<*mut Box<window::Window>>(global, PrototypeList::id::Window, 1) {
|
||||
Ok(win) => JS::from_box(win),
|
||||
match unwrap_object::<*mut window::Window>(global, PrototypeList::id::Window, 1) {
|
||||
Ok(win) => JS::from_raw(win),
|
||||
Err(_) => fail!("found DOM global that doesn't unwrap to Window"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage};
|
|||
use servo_util::namespace::{Namespace, Null};
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use collections::hashmap::HashMap;
|
||||
use extra::url::{Url, from_str};
|
||||
use js::jsapi::{JSObject, JSContext};
|
||||
use std::ascii::StrAsciiExt;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
#[deriving(Eq,Encodable)]
|
||||
pub enum IsHTMLDocument {
|
||||
|
@ -341,17 +341,17 @@ impl Document {
|
|||
match title_node {
|
||||
Some(ref mut title_node) => {
|
||||
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());
|
||||
title_node.AppendChild(&mut NodeCast::from(&new_text));
|
||||
assert!(title_node.AppendChild(&mut NodeCast::from(&new_text)).is_ok());
|
||||
},
|
||||
None => {
|
||||
let mut new_title: JS<Node> =
|
||||
NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self));
|
||||
let new_text = self.CreateTextNode(abstract_self, title.clone());
|
||||
new_title.AppendChild(&mut NodeCast::from(&new_text));
|
||||
head.AppendChild(&mut new_title);
|
||||
assert!(new_title.AppendChild(&mut NodeCast::from(&new_text)).is_ok());
|
||||
assert!(head.AppendChild(&mut new_title).is_ok());
|
||||
},
|
||||
}
|
||||
});
|
||||
|
@ -418,9 +418,9 @@ impl Document {
|
|||
match old_body {
|
||||
Some(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);
|
||||
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
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,7 +10,7 @@ use dom::window::Window;
|
|||
use servo_util::str::DOMString;
|
||||
|
||||
#[repr(uint)]
|
||||
#[deriving(ToStr, Encodable)]
|
||||
#[deriving(Show, Encodable)]
|
||||
enum DOMErrorName {
|
||||
IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR,
|
||||
HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR,
|
||||
|
|
|
@ -72,18 +72,18 @@ impl DOMImplementation {
|
|||
{
|
||||
// Step 3.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
match title {
|
||||
|
@ -91,18 +91,18 @@ impl DOMImplementation {
|
|||
Some(title_str) => {
|
||||
// Step 6.1.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
|
|
@ -203,9 +203,9 @@ impl Element {
|
|||
let (prefix, local_name) = get_attribute_parts(name.clone());
|
||||
match prefix {
|
||||
Some(ref prefix_str) => {
|
||||
if (namespace == namespace::Null ||
|
||||
("xml" == prefix_str.as_slice() && namespace != namespace::XML) ||
|
||||
("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS)) {
|
||||
if namespace == namespace::Null ||
|
||||
("xml" == prefix_str.as_slice() && namespace != namespace::XML) ||
|
||||
("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS) {
|
||||
return Err(NamespaceError);
|
||||
}
|
||||
},
|
||||
|
@ -410,7 +410,7 @@ impl Element {
|
|||
pub fn set_string_attribute(&mut self, abstract_self: &JS<Element>,
|
||||
name: &str, value: DOMString) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::EventBinding;
|
|||
use dom::bindings::codegen::EventBinding::EventConstants;
|
||||
use dom::bindings::js::JS;
|
||||
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::window::Window;
|
||||
use servo_util::str::DOMString;
|
||||
|
@ -24,10 +24,10 @@ pub enum Event_ {
|
|||
|
||||
#[deriving(Encodable)]
|
||||
pub enum EventPhase {
|
||||
Phase_None = EventConstants::NONE,
|
||||
Phase_Capturing = EventConstants::CAPTURING_PHASE,
|
||||
Phase_At_Target = EventConstants::AT_TARGET,
|
||||
Phase_Bubbling = EventConstants::BUBBLING_PHASE,
|
||||
PhaseNone = EventConstants::NONE,
|
||||
PhaseCapturing = EventConstants::CAPTURING_PHASE,
|
||||
PhaseAtTarget = EventConstants::AT_TARGET,
|
||||
PhaseBubbling = EventConstants::BUBBLING_PHASE,
|
||||
}
|
||||
|
||||
#[deriving(Eq, Encodable)]
|
||||
|
@ -63,7 +63,7 @@ impl Event {
|
|||
reflector_: Reflector::new(),
|
||||
current_target: None,
|
||||
target: None,
|
||||
phase: Phase_None,
|
||||
phase: PhaseNone,
|
||||
type_: ~"",
|
||||
default_prevented: false,
|
||||
cancelable: true,
|
||||
|
@ -132,12 +132,11 @@ impl Event {
|
|||
pub fn InitEvent(&mut self,
|
||||
type_: DOMString,
|
||||
bubbles: bool,
|
||||
cancelable: bool) -> ErrorResult {
|
||||
cancelable: bool) {
|
||||
self.type_ = type_;
|
||||
self.cancelable = cancelable;
|
||||
self.bubbles = bubbles;
|
||||
self.initialized = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn IsTrusted(&self) -> bool {
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::bindings::callback::eReportExceptions;
|
||||
use dom::bindings::callback::ReportExceptions;
|
||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
|
||||
use dom::bindings::js::JS;
|
||||
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};
|
||||
|
||||
// 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
|
||||
|
||||
|
@ -45,7 +45,9 @@ pub fn dispatch_event(target: &JS<EventTarget>,
|
|||
Some(listeners) => {
|
||||
event.get_mut().current_target = Some(cur_target.clone());
|
||||
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 {
|
||||
break;
|
||||
|
@ -66,14 +68,16 @@ pub fn dispatch_event(target: &JS<EventTarget>,
|
|||
if !event.get().stop_propagation {
|
||||
{
|
||||
let event = event.get_mut();
|
||||
event.phase = Phase_At_Target;
|
||||
event.phase = PhaseAtTarget;
|
||||
event.current_target = Some(target.clone());
|
||||
}
|
||||
|
||||
let opt_listeners = target.get().get_listeners(type_);
|
||||
for listeners in opt_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 {
|
||||
break;
|
||||
}
|
||||
|
@ -83,14 +87,16 @@ pub fn dispatch_event(target: &JS<EventTarget>,
|
|||
|
||||
/* bubbling */
|
||||
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() {
|
||||
let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) {
|
||||
Some(listeners) => {
|
||||
event.get_mut().current_target = Some(cur_target.clone());
|
||||
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 {
|
||||
break;
|
||||
|
@ -109,7 +115,7 @@ pub fn dispatch_event(target: &JS<EventTarget>,
|
|||
|
||||
let event = event.get_mut();
|
||||
event.dispatching = false;
|
||||
event.phase = Phase_None;
|
||||
event.phase = PhaseNone;
|
||||
event.current_target = None;
|
||||
|
||||
!event.DefaultPrevented()
|
||||
|
|
|
@ -11,7 +11,7 @@ use dom::eventdispatcher::dispatch_event;
|
|||
use dom::node::NodeTypeId;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use collections::hashmap::HashMap;
|
||||
|
||||
#[deriving(Eq,Encodable)]
|
||||
pub enum ListenerPhase {
|
||||
|
|
|
@ -11,7 +11,7 @@ use dom::htmlformelement::HTMLFormElement;
|
|||
use dom::window::Window;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use collections::hashmap::HashMap;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
enum FormDatum {
|
||||
|
|
|
@ -15,9 +15,9 @@ use dom::windowproxy::WindowProxy;
|
|||
use servo_util::str::DOMString;
|
||||
|
||||
use extra::url::Url;
|
||||
use serialize::{Encoder, Encodable};
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use std::ascii::StrAsciiExt;
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
|
||||
enum SandboxAllowance {
|
||||
AllowNothing = 0x00,
|
||||
|
|
|
@ -19,7 +19,7 @@ use servo_net::image_cache_task;
|
|||
use servo_util::url::parse_url;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct HTMLImageElement {
|
||||
|
@ -120,8 +120,7 @@ impl HTMLImageElement {
|
|||
|
||||
pub fn SetSrc(&mut self, abstract_self: &JS<HTMLImageElement>, src: DOMString) -> ErrorResult {
|
||||
let node = &mut self.htmlelement.element;
|
||||
node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone());
|
||||
Ok(())
|
||||
node.set_attr(&ElementCast::from(abstract_self), ~"src", src.clone())
|
||||
}
|
||||
|
||||
pub fn CrossOrigin(&self) -> DOMString {
|
||||
|
@ -164,8 +163,7 @@ impl HTMLImageElement {
|
|||
pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) -> ErrorResult {
|
||||
let mut elem: JS<Element> = ElementCast::from(abstract_self);
|
||||
let mut elem_clone = elem.clone();
|
||||
elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str());
|
||||
Ok(())
|
||||
elem.get_mut().set_attr(&mut elem_clone, ~"width", width.to_str())
|
||||
}
|
||||
|
||||
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 {
|
||||
let node = &mut self.htmlelement.element;
|
||||
node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str());
|
||||
Ok(())
|
||||
node.set_attr(&ElementCast::from(abstract_self), ~"height", height.to_str())
|
||||
}
|
||||
|
||||
pub fn NaturalWidth(&self) -> u32 {
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
|||
|
||||
for node in *iterator {
|
||||
while open_elements.len() > iterator.depth {
|
||||
html.push_str(~"</" + open_elements.pop() + ">");
|
||||
html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
|
||||
}
|
||||
html.push_str(
|
||||
match node.type_id() {
|
||||
|
@ -59,7 +59,7 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
|
|||
);
|
||||
}
|
||||
while open_elements.len() > 0 {
|
||||
html.push_str(~"</" + open_elements.pop() + ">");
|
||||
html.push_str(~"</" + open_elements.pop().unwrap().as_slice() + ">");
|
||||
}
|
||||
html
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use servo_util::str::DOMString;
|
|||
use script_task::{Page};
|
||||
use std::rc::Rc;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
|
||||
#[deriving(Encodable)]
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use dom::bindings::codegen::MouseEventBinding;
|
||||
use dom::bindings::codegen::InheritTypes::MouseEventDerived;
|
||||
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::event::{Event, MouseEventTypeId};
|
||||
use dom::eventtarget::EventTarget;
|
||||
|
@ -135,7 +135,7 @@ impl MouseEvent {
|
|||
shiftKeyArg: bool,
|
||||
metaKeyArg: bool,
|
||||
buttonArg: u16,
|
||||
relatedTargetArg: Option<JS<EventTarget>>) -> ErrorResult {
|
||||
relatedTargetArg: Option<JS<EventTarget>>) {
|
||||
self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
|
||||
self.screen_x = screenXArg;
|
||||
self.screen_y = screenYArg;
|
||||
|
@ -147,7 +147,6 @@ impl MouseEvent {
|
|||
self.meta_key = metaKeyArg;
|
||||
self.button = buttonArg;
|
||||
self.related_target = relatedTargetArg;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,11 +37,9 @@ use std::cast;
|
|||
use std::cell::{RefCell, Ref, RefMut};
|
||||
use std::iter::{Map, Filter};
|
||||
use std::libc::uintptr_t;
|
||||
use std::ptr;
|
||||
use std::unstable::raw::Box;
|
||||
use std::util;
|
||||
use std::mem;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
//
|
||||
// The basic Node structure
|
||||
|
@ -562,8 +560,8 @@ impl NodeHelpers for JS<Node> {
|
|||
if object.is_null() {
|
||||
fail!("Attempted to create a `JS<Node>` from an invalid pointer!")
|
||||
}
|
||||
let boxed_node: *mut Box<Node> = utils::unwrap(object);
|
||||
JS::from_box(boxed_node)
|
||||
let boxed_node: *mut Node = utils::unwrap(object);
|
||||
JS::from_raw(boxed_node)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -734,6 +732,8 @@ enum CloneChildrenFlag {
|
|||
DoNotCloneChildren
|
||||
}
|
||||
|
||||
fn as_uintptr<T>(t: &T) -> uintptr_t { t as *T as uintptr_t }
|
||||
|
||||
impl Node {
|
||||
pub fn ancestors(&self) -> AncestorIterator {
|
||||
AncestorIterator {
|
||||
|
@ -806,11 +806,14 @@ impl Node {
|
|||
/// Sends layout data, if any, back to the script task to be destroyed.
|
||||
pub unsafe fn reap_layout_data(&mut self) {
|
||||
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();
|
||||
match layout_chan {
|
||||
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 |
|
||||
TextNodeTypeId |
|
||||
ProcessingInstructionNodeTypeId => {
|
||||
self.SetTextContent(abstract_self, val);
|
||||
self.SetTextContent(abstract_self, val)
|
||||
}
|
||||
_ => {}
|
||||
_ => Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-node-textcontent
|
||||
|
@ -1268,7 +1270,7 @@ impl Node {
|
|||
|
||||
// http://dom.spec.whatwg.org/#concept-node-remove
|
||||
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 6-7: mutation observers.
|
||||
|
@ -1564,7 +1566,7 @@ impl Node {
|
|||
match prev_text {
|
||||
Some(ref 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);
|
||||
},
|
||||
None => prev_text = Some(child)
|
||||
|
@ -1685,15 +1687,18 @@ impl Node {
|
|||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
NodeConstants::DOCUMENT_POSITION_PRECEDING
|
||||
};
|
||||
// step 3.
|
||||
return random +
|
||||
NodeConstants::DOCUMENT_POSITION_DISCONNECTED +
|
||||
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
|
||||
NodeConstants::DOCUMENT_POSITION_DISCONNECTED +
|
||||
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
|
||||
}
|
||||
|
||||
for child in lastself.traverse_preorder() {
|
||||
|
|
|
@ -44,6 +44,7 @@ interface Document : Node {
|
|||
partial interface Document {
|
||||
[SetterThrows]
|
||||
attribute DOMString title;
|
||||
[SetterThrows]
|
||||
attribute HTMLElement? body;
|
||||
readonly attribute HTMLHeadElement? head;
|
||||
NodeList getElementsByName(DOMString elementName);
|
||||
|
|
|
@ -33,7 +33,6 @@ interface Event {
|
|||
readonly attribute boolean isTrusted;
|
||||
readonly attribute DOMTimeStamp timeStamp;
|
||||
|
||||
[Throws]
|
||||
void initEvent(DOMString type, boolean bubbles, boolean cancelable);
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ interface MouseEvent : UIEvent {
|
|||
readonly attribute unsigned short buttons;
|
||||
readonly attribute EventTarget? relatedTarget;
|
||||
// Deprecated in DOM Level 3:
|
||||
[Throws]
|
||||
void initMouseEvent(DOMString typeArg,
|
||||
boolean canBubbleArg,
|
||||
boolean cancelableArg,
|
||||
|
|
|
@ -25,22 +25,22 @@ use js::jsval::JSVal;
|
|||
use js::jsval::{NullValue, ObjectValue};
|
||||
use js::JSPROP_ENUMERATE;
|
||||
|
||||
use collections::hashmap::HashSet;
|
||||
use std::cast;
|
||||
use std::comm::SharedChan;
|
||||
use std::cmp;
|
||||
use std::comm::Chan;
|
||||
use std::comm::Select;
|
||||
use std::hashmap::HashSet;
|
||||
use std::hash::{Hash, sip};
|
||||
use std::io::timer::Timer;
|
||||
use std::num;
|
||||
use std::rc::Rc;
|
||||
use std::to_bytes::Cb;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
use extra::url::{Url};
|
||||
|
||||
pub enum TimerControlMsg {
|
||||
TimerMessage_Fire(~TimerData),
|
||||
TimerMessage_Close,
|
||||
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the script task
|
||||
TimerMessageFire(~TimerData),
|
||||
TimerMessageClose,
|
||||
TimerMessageTriggerExit //XXXjdm this is just a quick hack to talk to the script task
|
||||
}
|
||||
|
||||
pub struct TimerHandle {
|
||||
|
@ -53,9 +53,9 @@ impl<S: Encoder> Encodable<S> for TimerHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl IterBytes for TimerHandle {
|
||||
fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
|
||||
self.handle.iter_bytes(lsb0, f)
|
||||
impl Hash for TimerHandle {
|
||||
fn hash(&self, state: &mut sip::SipState) {
|
||||
self.handle.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ pub struct Window {
|
|||
struct Untraceable {
|
||||
page: Rc<Page>,
|
||||
compositor: ~ScriptListener,
|
||||
timer_chan: SharedChan<TimerControlMsg>,
|
||||
timer_chan: Chan<TimerControlMsg>,
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for Untraceable {
|
||||
|
@ -115,7 +115,7 @@ impl Window {
|
|||
#[unsafe_destructor]
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
self.extra.timer_chan.send(TimerMessage_Close);
|
||||
self.extra.timer_chan.send(TimerMessageClose);
|
||||
for handle in self.active_timers.iter() {
|
||||
handle.cancel();
|
||||
}
|
||||
|
@ -134,11 +134,11 @@ pub struct TimerData {
|
|||
impl Window {
|
||||
pub fn Alert(&self, s: DOMString) {
|
||||
// Right now, just print to the console
|
||||
println(format!("ALERT: {:s}", s));
|
||||
println!("ALERT: {:s}", s);
|
||||
}
|
||||
|
||||
pub fn Close(&self) {
|
||||
self.extra.timer_chan.send(TimerMessage_TriggerExit);
|
||||
self.extra.timer_chan.send(TimerMessageTriggerExit);
|
||||
}
|
||||
|
||||
pub fn Document(&self) -> JS<Document> {
|
||||
|
@ -226,7 +226,7 @@ impl Reflectable for Window {
|
|||
|
||||
impl Window {
|
||||
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;
|
||||
self.next_timer_handle += 1;
|
||||
|
||||
|
@ -237,15 +237,17 @@ impl Window {
|
|||
let chan = self.extra.timer_chan.clone();
|
||||
spawn_named("Window:SetTimeout", proc() {
|
||||
let mut tm = tm;
|
||||
let mut timeout_port = tm.oneshot(timeout);
|
||||
let mut cancel_port = cancel_port;
|
||||
let timeout_port = tm.oneshot(timeout);
|
||||
let cancel_port = cancel_port;
|
||||
|
||||
let select = Select::new();
|
||||
let timeout_handle = select.add(&mut timeout_port);
|
||||
let _cancel_handle = select.add(&mut cancel_port);
|
||||
let mut timeout_handle = select.handle(&timeout_port);
|
||||
unsafe { timeout_handle.add() };
|
||||
let mut cancel_handle = select.handle(&cancel_port);
|
||||
unsafe { cancel_handle.add() };
|
||||
let id = select.wait();
|
||||
if id == timeout_handle.id {
|
||||
chan.send(TimerMessage_Fire(~TimerData {
|
||||
if id == timeout_handle.id() {
|
||||
chan.send(TimerMessageFire(~TimerData {
|
||||
handle: handle,
|
||||
funval: callback,
|
||||
args: ~[],
|
||||
|
@ -290,14 +292,15 @@ impl Window {
|
|||
compositor: compositor,
|
||||
page: page.clone(),
|
||||
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();
|
||||
spawn_named("timer controller", proc() {
|
||||
let ScriptChan(script_chan) = script_chan;
|
||||
loop {
|
||||
match timer_port.recv() {
|
||||
TimerMessage_Close => break,
|
||||
TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)),
|
||||
TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)),
|
||||
TimerMessageClose => break,
|
||||
TimerMessageFire(td) => script_chan.send(FireTimerMsg(id, td)),
|
||||
TimerMessageTriggerExit => script_chan.send(ExitWindowMsg(id)),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -34,10 +34,11 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
|||
resource_task.send(Load(url, input_chan));
|
||||
let LoadResponse { metadata: metadata, progress_port: progress_port }
|
||||
= input_port.recv();
|
||||
let final_url = &metadata.final_url;
|
||||
let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice());
|
||||
let iter = ProgressMsgPortIterator { progress_port: progress_port };
|
||||
Stylesheet::from_bytes_iter(
|
||||
iter, metadata.final_url,
|
||||
iter, final_url.clone(),
|
||||
protocol_encoding_label, Some(environment_encoding))
|
||||
}
|
||||
InlineProvenance(base_url, data) => {
|
||||
|
|
|
@ -28,7 +28,7 @@ use servo_util::url::parse_url;
|
|||
use std::ascii::StrAsciiExt;
|
||||
use std::cast;
|
||||
use std::cell::RefCell;
|
||||
use std::comm::{Port, SharedChan};
|
||||
use std::comm::{Port, Chan};
|
||||
use std::str;
|
||||
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.
|
||||
|
||||
*/
|
||||
fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
|
||||
fn css_link_listener(to_parent: Chan<HtmlDiscoveryMessage>,
|
||||
from_parent: Port<CSSMessage>,
|
||||
resource_task: ResourceTask) {
|
||||
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>,
|
||||
resource_task: ResourceTask) {
|
||||
let mut result_vec = ~[];
|
||||
|
@ -140,7 +140,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
|
|||
}
|
||||
Ok((metadata, bytes)) => {
|
||||
result_vec.push(JSFile {
|
||||
data: str::from_utf8(bytes).to_owned(),
|
||||
data: str::from_utf8(bytes).unwrap().to_owned(),
|
||||
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.
|
||||
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 (css_msg_port, css_chan) = SharedChan::new();
|
||||
let (css_msg_port, css_chan) = Chan::new();
|
||||
spawn_named("parse_html:css", proc() {
|
||||
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.
|
||||
let resource_task2 = resource_task.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() {
|
||||
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 doc_cell = RefCell::new(document);
|
||||
|
||||
let tree_handler = hubbub::TreeHandler {
|
||||
create_comment: |data: ~str| {
|
||||
debug!("create comment");
|
||||
let comment: JS<Node> = NodeCast::from(&Comment::new(data, document));
|
||||
unsafe { comment.to_hubbub_node() }
|
||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||
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| {
|
||||
debug!("create doctype");
|
||||
|
@ -315,21 +320,29 @@ pub fn parse_html(page: &Page,
|
|||
public_id: public_id,
|
||||
system_id: system_id,
|
||||
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 {
|
||||
doctype_node.to_hubbub_node()
|
||||
}
|
||||
},
|
||||
create_element: |tag: ~hubbub::Tag| {
|
||||
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");
|
||||
for attr in tag.attributes.iter() {
|
||||
let elem = element.clone();
|
||||
element.get_mut().set_attr(&elem,
|
||||
attr.name.clone(),
|
||||
attr.value.clone());
|
||||
//FIXME: this should have proper error handling or explicitly drop
|
||||
// exceptions on the ground
|
||||
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
|
||||
|
@ -366,7 +379,8 @@ pub fn parse_html(page: &Page,
|
|||
|
||||
// Subpage Id
|
||||
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 {
|
||||
pipeline_id: pipeline_id,
|
||||
|
@ -384,7 +398,10 @@ pub fn parse_html(page: &Page,
|
|||
},
|
||||
create_text: |data: ~str| {
|
||||
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() }
|
||||
},
|
||||
ref_node: |_| {},
|
||||
|
@ -394,7 +411,7 @@ pub fn parse_html(page: &Page,
|
|||
debug!("append child {:x} {:x}", parent, child);
|
||||
let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent);
|
||||
let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child);
|
||||
parent.AppendChild(&mut child);
|
||||
assert!(parent.AppendChild(&mut child).is_ok());
|
||||
}
|
||||
child
|
||||
},
|
||||
|
@ -431,11 +448,17 @@ pub fn parse_html(page: &Page,
|
|||
},
|
||||
set_quirks_mode: |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| {
|
||||
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| {
|
||||
unsafe {
|
||||
|
@ -500,6 +523,7 @@ pub fn parse_html(page: &Page,
|
|||
}
|
||||
}
|
||||
|
||||
debug!("finished parsing");
|
||||
css_chan.send(CSSTaskExit);
|
||||
js_chan.send(JSTaskExit);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use geom::size::Size2D;
|
|||
use script_task::{ScriptChan};
|
||||
use servo_util::geometry::Au;
|
||||
use std::cmp;
|
||||
use std::comm::{Chan, SharedChan};
|
||||
use std::comm::Chan;
|
||||
use std::libc::c_void;
|
||||
use style::Stylesheet;
|
||||
|
||||
|
@ -132,11 +132,11 @@ pub struct Reflow {
|
|||
|
||||
/// Encapsulates a channel to the layout task.
|
||||
#[deriving(Clone)]
|
||||
pub struct LayoutChan(SharedChan<Msg>);
|
||||
pub struct LayoutChan(Chan<Msg>);
|
||||
|
||||
impl LayoutChan {
|
||||
pub fn new() -> (Port<Msg>, LayoutChan) {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
(port, LayoutChan(chan))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,14 @@ macro_rules! bitfield(
|
|||
impl $bitfieldname {
|
||||
#[inline]
|
||||
pub fn $getter(self) -> bool {
|
||||
(*self & $value) != 0
|
||||
let $bitfieldname(s) = self;
|
||||
(s & $value) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 }))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -10,16 +10,18 @@
|
|||
|
||||
#[feature(globs, macro_rules, struct_variant, managed_boxes)];
|
||||
|
||||
extern mod geom;
|
||||
extern mod hubbub;
|
||||
extern mod encoding;
|
||||
extern mod js;
|
||||
extern mod servo_net = "net";
|
||||
extern mod servo_util = "util";
|
||||
extern mod style;
|
||||
extern mod servo_msg = "msg";
|
||||
extern mod extra;
|
||||
extern mod native;
|
||||
extern crate collections;
|
||||
extern crate geom;
|
||||
extern crate hubbub;
|
||||
extern crate encoding;
|
||||
extern crate js;
|
||||
extern crate serialize;
|
||||
extern crate servo_net = "net";
|
||||
extern crate servo_util = "util";
|
||||
extern crate style;
|
||||
extern crate servo_msg = "msg";
|
||||
extern crate extra;
|
||||
extern crate native;
|
||||
|
||||
// Macros
|
||||
mod macros;
|
||||
|
|
|
@ -50,13 +50,13 @@ use servo_util::task::send_on_failure;
|
|||
use servo_util::namespace::Null;
|
||||
use std::cast;
|
||||
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::rc::Rc;
|
||||
use std::task;
|
||||
use std::util::replace;
|
||||
|
||||
use extra::serialize::{Encoder, Encodable};
|
||||
use serialize::{Encoder, Encodable};
|
||||
|
||||
/// Messages used to control the script task.
|
||||
pub enum ScriptMsg {
|
||||
|
@ -90,7 +90,7 @@ pub struct NewLayoutInfo {
|
|||
|
||||
/// Encapsulates external communication with the script task.
|
||||
#[deriving(Clone)]
|
||||
pub struct ScriptChan(SharedChan<ScriptMsg>);
|
||||
pub struct ScriptChan(Chan<ScriptMsg>);
|
||||
|
||||
impl<S: Encoder> Encodable<S> for ScriptChan {
|
||||
fn encode(&self, _s: &mut S) {
|
||||
|
@ -100,7 +100,7 @@ impl<S: Encoder> Encodable<S> for ScriptChan {
|
|||
impl ScriptChan {
|
||||
/// Creates a new script chan.
|
||||
pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
|
||||
let (port, chan) = SharedChan::new();
|
||||
let (port, chan) = Chan::new();
|
||||
(port, ScriptChan(chan))
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ pub struct PageTreeIterator<'a> {
|
|||
impl PageTree {
|
||||
fn new(id: PipelineId, layout_chan: LayoutChan, window_size: Size2D<uint>) -> PageTree {
|
||||
PageTree {
|
||||
page: unsafe { Rc::new_unchecked(Page {
|
||||
page: Rc::new(Page {
|
||||
id: id,
|
||||
frame: RefCell::new(None),
|
||||
layout_chan: layout_chan,
|
||||
|
@ -177,7 +177,7 @@ impl PageTree {
|
|||
resize_event: RefCell::new(None),
|
||||
fragment_node: RefCell::new(None),
|
||||
last_reflow_id: RefCell::new(0)
|
||||
}) },
|
||||
}),
|
||||
inner: ~[],
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ impl PageTree {
|
|||
.map(|(idx, _)| idx)
|
||||
};
|
||||
match remove_idx {
|
||||
Some(idx) => return Some(self.inner.remove(idx)),
|
||||
Some(idx) => return Some(self.inner.remove(idx).unwrap()),
|
||||
None => {
|
||||
for page_tree in self.inner.mut_iter() {
|
||||
match page_tree.remove(id) {
|
||||
|
@ -237,11 +237,9 @@ impl PageTree {
|
|||
impl<'a> Iterator<Rc<Page>> for PageTreeIterator<'a> {
|
||||
fn next(&mut self) -> Option<Rc<Page>> {
|
||||
if !self.stack.is_empty() {
|
||||
let next = self.stack.pop();
|
||||
{
|
||||
for child in next.inner.mut_iter() {
|
||||
self.stack.push(child);
|
||||
}
|
||||
let next = self.stack.pop().unwrap();
|
||||
for child in next.inner.mut_iter() {
|
||||
self.stack.push(child);
|
||||
}
|
||||
Some(next.page.clone())
|
||||
} else {
|
||||
|
@ -307,7 +305,7 @@ impl Page {
|
|||
|
||||
pub fn get_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
|
||||
|
@ -319,11 +317,14 @@ impl Page {
|
|||
match join_port {
|
||||
Some(ref join_port) => {
|
||||
match join_port.try_recv() {
|
||||
None => {
|
||||
Empty => {
|
||||
info!("script: waiting on layout");
|
||||
join_port.recv();
|
||||
}
|
||||
Some(_) => {}
|
||||
Data(_) => {}
|
||||
Disconnected => {
|
||||
fail!("Layout task failed while script was waiting for a result.");
|
||||
}
|
||||
}
|
||||
|
||||
debug!("script: layout joined")
|
||||
|
@ -339,7 +340,8 @@ impl Page {
|
|||
response_port: Port<T>)
|
||||
-> T {
|
||||
self.join_layout();
|
||||
self.layout_chan.send(QueryMsg(query));
|
||||
let LayoutChan(ref chan) = self.layout_chan;
|
||||
chan.send(QueryMsg(query));
|
||||
response_port.recv()
|
||||
}
|
||||
|
||||
|
@ -397,7 +399,8 @@ impl Page {
|
|||
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")
|
||||
}
|
||||
|
@ -493,8 +496,7 @@ impl ScriptTask {
|
|||
-> Rc<ScriptTask> {
|
||||
let js_runtime = js::rust::rt();
|
||||
|
||||
unsafe {
|
||||
Rc::new_unchecked(ScriptTask {
|
||||
Rc::new(ScriptTask {
|
||||
page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)),
|
||||
|
||||
image_cache_task: img_cache_task,
|
||||
|
@ -507,8 +509,7 @@ impl ScriptTask {
|
|||
|
||||
js_runtime: js_runtime,
|
||||
mouse_over_targets: RefCell::new(None)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Starts the script task. After calling this method, the script task will loop receiving
|
||||
|
@ -530,9 +531,9 @@ impl ScriptTask {
|
|||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask,
|
||||
window_size: Size2D<uint>) {
|
||||
let mut builder = task::task();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), (*constellation_chan).clone());
|
||||
builder.name("ScriptTask");
|
||||
let mut builder = task::task().named("ScriptTask");
|
||||
let ConstellationChan(const_chan) = constellation_chan.clone();
|
||||
send_on_failure(&mut builder, FailureMsg(failure_msg), const_chan);
|
||||
builder.spawn(proc() {
|
||||
let script_task = ScriptTask::new(id,
|
||||
compositor as ~ScriptListener,
|
||||
|
@ -593,8 +594,8 @@ impl ScriptTask {
|
|||
}
|
||||
|
||||
match self.port.try_recv() {
|
||||
None => break,
|
||||
Some(ev) => event = ev,
|
||||
Empty | Disconnected => break,
|
||||
Data(ev) => event = ev,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -652,7 +653,7 @@ impl ScriptTask {
|
|||
let this_value = if timer_data.args.len() > 0 {
|
||||
fail!("NYI")
|
||||
} 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`.
|
||||
|
@ -683,7 +684,8 @@ impl ScriptTask {
|
|||
/// Handles a navigate forward or backward message.
|
||||
/// TODO(tkuehn): is it ever possible to navigate only on a subframe?
|
||||
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
|
||||
|
@ -696,7 +698,7 @@ impl ScriptTask {
|
|||
let mut page_url = page.mut_url();
|
||||
let last_loaded_url = replace(page_url.get(), None);
|
||||
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);
|
||||
}
|
||||
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))) => {
|
||||
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 {
|
||||
IFrameSandboxed
|
||||
} else {
|
||||
IFrameUnsandboxed
|
||||
};
|
||||
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
||||
pipeline_id,
|
||||
subpage_id,
|
||||
sandboxed));
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(LoadIframeUrlMsg(iframe_url,
|
||||
pipeline_id,
|
||||
subpage_id,
|
||||
sandboxed));
|
||||
}
|
||||
None => break
|
||||
}
|
||||
|
@ -862,7 +867,7 @@ impl ScriptTask {
|
|||
let js_info = page.js_info();
|
||||
let js_info = js_info.get().get_ref();
|
||||
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
|
||||
};
|
||||
|
@ -873,12 +878,14 @@ impl ScriptTask {
|
|||
let (cx, global_obj) = {
|
||||
let js_info = page.js_info();
|
||||
(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,
|
||||
file.data.clone(),
|
||||
file.url.to_str(),
|
||||
1);
|
||||
//FIXME: this should have some kind of error handling, or explicitly
|
||||
// drop an exception on the floor.
|
||||
assert!(cx.borrow().evaluate_script(global_obj,
|
||||
file.data.clone(),
|
||||
file.url.to_str(),
|
||||
1).is_ok());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -890,12 +897,13 @@ impl ScriptTask {
|
|||
let doctarget = EventTargetCast::from(&document);
|
||||
let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window);
|
||||
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();
|
||||
*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>> {
|
||||
|
@ -908,7 +916,7 @@ impl ScriptTask {
|
|||
let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element());
|
||||
anchors.find(|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
|
||||
})
|
||||
}).map(|node| ElementCast::to(&node))
|
||||
|
@ -973,7 +981,7 @@ impl ScriptTask {
|
|||
// FIXME: this event should be dispatch on WindowProxy. See #1715
|
||||
let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window);
|
||||
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 =>()
|
||||
}
|
||||
|
@ -1121,8 +1129,9 @@ impl ScriptTask {
|
|||
None => {}
|
||||
}
|
||||
} 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.
|
||||
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();
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* 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/. */
|
||||
|
||||
#[allow(non_camel_case_types)];
|
||||
|
||||
pub use servo_util::geometry::Au;
|
||||
|
||||
pub type CSSFloat = f64;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue