mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Resvoled merge conflict
This commit is contained in:
commit
1511d7a2ad
143 changed files with 1834 additions and 2075 deletions
|
@ -1,7 +1,7 @@
|
|||
# The Servo Parallel Browser Project
|
||||
|
||||
Servo is a prototype web browser engine written in the
|
||||
[Rust](https://github.com/mozilla/rust) language. It is currently developed on
|
||||
[Rust](https://github.com/rust-lang/rust) language. It is currently developed on
|
||||
64bit OS X, 64bit Linux, Android, and Gonk (Firefox OS).
|
||||
|
||||
Servo welcomes contribution from everyone. See
|
||||
|
|
|
@ -39,6 +39,7 @@ pub enum CanvasMsg {
|
|||
SetFillStyle(FillOrStrokeStyle),
|
||||
SetStrokeStyle(FillOrStrokeStyle),
|
||||
SetLineWidth(f32),
|
||||
SetMiterLimit(f32),
|
||||
SetTransform(Matrix2D<f32>),
|
||||
SetGlobalAlpha(f32),
|
||||
Recreate(Size2D<i32>),
|
||||
|
@ -202,7 +203,7 @@ impl<'a> CanvasPaintTask<'a> {
|
|||
draw_options: DrawOptions::new(1.0, 0),
|
||||
fill_style: Pattern::Color(ColorPattern::new(color::black())),
|
||||
stroke_style: Pattern::Color(ColorPattern::new(color::black())),
|
||||
stroke_opts: StrokeOptions::new(1.0, JoinStyle::MiterOrBevel, CapStyle::Butt, 1.0, &[]),
|
||||
stroke_opts: StrokeOptions::new(1.0, JoinStyle::MiterOrBevel, CapStyle::Butt, 10.0, &[]),
|
||||
path_builder: path_builder,
|
||||
transform: Matrix2D::identity(),
|
||||
}
|
||||
|
@ -245,6 +246,7 @@ impl<'a> CanvasPaintTask<'a> {
|
|||
CanvasMsg::SetFillStyle(style) => painter.set_fill_style(style),
|
||||
CanvasMsg::SetStrokeStyle(style) => painter.set_stroke_style(style),
|
||||
CanvasMsg::SetLineWidth(width) => painter.set_line_width(width),
|
||||
CanvasMsg::SetMiterLimit(limit) => painter.set_miter_limit(limit),
|
||||
CanvasMsg::SetTransform(ref matrix) => painter.set_transform(matrix),
|
||||
CanvasMsg::SetGlobalAlpha(alpha) => painter.set_global_alpha(alpha),
|
||||
CanvasMsg::Recreate(size) => painter.recreate(size),
|
||||
|
@ -425,6 +427,10 @@ impl<'a> CanvasPaintTask<'a> {
|
|||
self.stroke_opts.line_width = width;
|
||||
}
|
||||
|
||||
fn set_miter_limit(&mut self, limit: f32) {
|
||||
self.stroke_opts.miter_limit = limit;
|
||||
}
|
||||
|
||||
fn set_transform(&mut self, transform: &Matrix2D<f32>) {
|
||||
self.transform = *transform;
|
||||
self.drawtarget.set_transform(transform)
|
||||
|
|
|
@ -76,8 +76,7 @@ impl FontHandleMethods for FontHandle {
|
|||
let ft_ctx: FT_Library = fctx.ctx.ctx;
|
||||
if ft_ctx.is_null() { return Err(()); }
|
||||
|
||||
let bytes = &template.bytes;
|
||||
let face_result = create_face_from_buffer(ft_ctx, bytes.as_ptr(), bytes.len(), pt_size);
|
||||
let face_result = create_face_from_buffer(ft_ctx, &template.bytes, pt_size);
|
||||
|
||||
// TODO: this could be more simply written as result::chain
|
||||
// and moving buf into the struct ctor, but cant' move out of
|
||||
|
@ -94,12 +93,12 @@ impl FontHandleMethods for FontHandle {
|
|||
Err(()) => Err(())
|
||||
};
|
||||
|
||||
fn create_face_from_buffer(lib: FT_Library, cbuf: *const u8, cbuflen: uint, pt_size: Option<Au>)
|
||||
fn create_face_from_buffer(lib: FT_Library, buffer: &[u8], pt_size: Option<Au>)
|
||||
-> Result<FT_Face, ()> {
|
||||
unsafe {
|
||||
let mut face: FT_Face = ptr::null_mut();
|
||||
let face_index = 0 as FT_Long;
|
||||
let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long,
|
||||
let result = FT_New_Memory_Face(lib, buffer.as_ptr(), buffer.len() as FT_Long,
|
||||
face_index, &mut face);
|
||||
|
||||
if !result.succeeded() || face.is_null() {
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) {
|
|||
unsafe {
|
||||
let config = FcConfigGetCurrent();
|
||||
let fontSet = FcConfigGetFonts(config, FcSetSystem);
|
||||
for i in 0..((*fontSet).nfont as int) {
|
||||
for i in 0..((*fontSet).nfont as isize) {
|
||||
let font = (*fontSet).fonts.offset(i);
|
||||
let mut family: *mut FcChar8 = ptr::null_mut();
|
||||
let mut v: c_int = 0;
|
||||
|
@ -74,7 +74,7 @@ pub fn get_variations_for_family<F>(family_name: &str, mut callback: F)
|
|||
|
||||
debug!("found {} variations", (*matches).nfont);
|
||||
|
||||
for i in 0..((*matches).nfont as int) {
|
||||
for i in 0..((*matches).nfont as isize) {
|
||||
let font = (*matches).fonts.offset(i);
|
||||
let mut file: *mut FcChar8 = ptr::null_mut();
|
||||
let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut c_char, 0, &mut file) == FcResultMatch {
|
||||
|
|
|
@ -16,6 +16,7 @@ use text::glyph::{CharIndex, GlyphStore};
|
|||
/// A single "paragraph" of text in one font size and style.
|
||||
#[derive(Clone)]
|
||||
pub struct TextRun {
|
||||
/// The UTF-8 string represented by this text run.
|
||||
pub text: Arc<String>,
|
||||
pub font_template: Arc<FontTemplateData>,
|
||||
pub actual_pt_size: Au,
|
||||
|
@ -310,7 +311,8 @@ impl<'a> TextRun {
|
|||
self.font_metrics.descent)
|
||||
}
|
||||
|
||||
pub fn metrics_for_slice(&self, glyphs: &GlyphStore, slice_range: &Range<CharIndex>) -> RunMetrics {
|
||||
pub fn metrics_for_slice(&self, glyphs: &GlyphStore, slice_range: &Range<CharIndex>)
|
||||
-> RunMetrics {
|
||||
RunMetrics::new(glyphs.advance_for_char_range(slice_range),
|
||||
self.font_metrics.ascent,
|
||||
self.font_metrics.descent)
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* 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 text::glyph::CharIndex;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy)]
|
||||
pub enum CompressionMode {
|
||||
CompressNone,
|
||||
|
@ -25,12 +23,10 @@ pub enum CompressionMode {
|
|||
pub fn transform_text(text: &str,
|
||||
mode: CompressionMode,
|
||||
incoming_whitespace: bool,
|
||||
output_text: &mut String,
|
||||
new_line_pos: &mut Vec<CharIndex>)
|
||||
output_text: &mut String)
|
||||
-> bool {
|
||||
let out_whitespace = match mode {
|
||||
CompressionMode::CompressNone | CompressionMode::DiscardNewline => {
|
||||
let mut new_line_index = CharIndex(0);
|
||||
for ch in text.chars() {
|
||||
if is_discardable_char(ch, mode) {
|
||||
// TODO: record skipped char
|
||||
|
@ -38,15 +34,6 @@ pub fn transform_text(text: &str,
|
|||
// TODO: record kept char
|
||||
if ch == '\t' {
|
||||
// TODO: set "has tab" flag
|
||||
} else if ch == '\n' {
|
||||
// Save new-line's position for line-break
|
||||
// This value is relative(not absolute)
|
||||
new_line_pos.push(new_line_index);
|
||||
new_line_index = CharIndex(0);
|
||||
}
|
||||
|
||||
if ch != '\n' {
|
||||
new_line_index = new_line_index + CharIndex(1);
|
||||
}
|
||||
output_text.push(ch);
|
||||
}
|
||||
|
@ -124,6 +111,6 @@ pub fn fixed_to_rounded_int(before: isize, f: i32) -> isize {
|
|||
if f > 0i32 {
|
||||
((half + f) >> before) as isize
|
||||
} else {
|
||||
-((half - f) >> before) as isize
|
||||
-((half - f) >> before as usize) as isize
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1994,7 +1994,8 @@ pub struct ISizeConstraintSolution {
|
|||
}
|
||||
|
||||
impl ISizeConstraintSolution {
|
||||
pub fn new(inline_size: Au, margin_inline_start: Au, margin_inline_end: Au) -> ISizeConstraintSolution {
|
||||
pub fn new(inline_size: Au, margin_inline_start: Au, margin_inline_end: Au)
|
||||
-> ISizeConstraintSolution {
|
||||
ISizeConstraintSolution {
|
||||
inline_start: Au(0),
|
||||
inline_end: Au(0),
|
||||
|
|
|
@ -27,16 +27,11 @@ use geom::{Point2D, Rect, Size2D};
|
|||
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||
use gfx::text::glyph::CharIndex;
|
||||
use gfx::text::text_run::{TextRun, TextRunSlice};
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId};
|
||||
use net_traits::image::holder::ImageHolder;
|
||||
use net_traits::local_image_cache::LocalImageCache;
|
||||
use util::geometry::{self, Au, ZERO_POINT};
|
||||
use util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin, WritingMode};
|
||||
use util::range::*;
|
||||
use util::smallvec::SmallVec;
|
||||
use util::str::is_whitespace;
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::LinkedList;
|
||||
|
@ -56,6 +51,12 @@ use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
|||
use style::values::computed::{LengthOrPercentageOrNone};
|
||||
use text::TextRunScanner;
|
||||
use url::Url;
|
||||
use util::geometry::{self, Au, ZERO_POINT};
|
||||
use util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin, WritingMode};
|
||||
use util::range::*;
|
||||
use util::smallvec::SmallVec;
|
||||
use util::str::is_whitespace;
|
||||
use util;
|
||||
|
||||
/// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position
|
||||
/// themselves. In general, fragments do not have a simple correspondence with CSS fragments in the
|
||||
|
@ -580,36 +581,27 @@ pub struct ScannedTextFragmentInfo {
|
|||
/// The text run that this represents.
|
||||
pub run: Arc<Box<TextRun>>,
|
||||
|
||||
/// The intrinsic size of the text fragment.
|
||||
pub content_size: LogicalSize<Au>,
|
||||
|
||||
/// The range within the above text run that this represents.
|
||||
pub range: Range<CharIndex>,
|
||||
|
||||
/// The positions of newlines within this scanned text fragment.
|
||||
///
|
||||
/// FIXME(#2260, pcwalton): Can't this go somewhere else, like in the text run or something?
|
||||
/// Or can we just remove it?
|
||||
pub new_line_pos: Vec<CharIndex>,
|
||||
|
||||
/// The new_line_pos is eaten during line breaking. If we need to re-merge
|
||||
/// fragments, it will have to be restored.
|
||||
pub original_new_line_pos: Option<Vec<CharIndex>>,
|
||||
|
||||
/// The intrinsic size of the text fragment.
|
||||
pub content_size: LogicalSize<Au>,
|
||||
/// The endpoint of the above range, including whitespace that was stripped out. This exists
|
||||
/// so that we can restore the range to its original value (before line breaking occurred) when
|
||||
/// performing incremental reflow.
|
||||
pub range_end_including_stripped_whitespace: CharIndex,
|
||||
}
|
||||
|
||||
impl ScannedTextFragmentInfo {
|
||||
/// Creates the information specific to a scanned text fragment from a range and a text run.
|
||||
pub fn new(run: Arc<Box<TextRun>>,
|
||||
range: Range<CharIndex>,
|
||||
new_line_positions: Vec<CharIndex>,
|
||||
content_size: LogicalSize<Au>)
|
||||
pub fn new(run: Arc<Box<TextRun>>, range: Range<CharIndex>, content_size: LogicalSize<Au>)
|
||||
-> ScannedTextFragmentInfo {
|
||||
ScannedTextFragmentInfo {
|
||||
run: run,
|
||||
range: range,
|
||||
new_line_pos: new_line_positions,
|
||||
original_new_line_pos: None,
|
||||
content_size: content_size,
|
||||
range_end_including_stripped_whitespace: range.end(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -769,32 +761,6 @@ impl Fragment {
|
|||
self.margin = LogicalMargin::zero(self.style.writing_mode);
|
||||
}
|
||||
|
||||
/// Saves the new_line_pos vector into a `SpecificFragmentInfo::ScannedText`. This will fail
|
||||
/// if called on any other type of fragment.
|
||||
pub fn save_new_line_pos(&mut self) {
|
||||
match &mut self.specific {
|
||||
&mut SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
if !info.new_line_pos.is_empty() {
|
||||
info.original_new_line_pos = Some(info.new_line_pos.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore_new_line_pos(&mut self) {
|
||||
match &mut self.specific {
|
||||
&mut SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
match info.original_new_line_pos.take() {
|
||||
None => {}
|
||||
Some(new_line_pos) => info.new_line_pos = new_line_pos,
|
||||
}
|
||||
return
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a debug ID of this fragment. This ID should not be considered stable across
|
||||
/// multiple layouts or fragment manipulations.
|
||||
pub fn debug_id(&self) -> u16 {
|
||||
|
@ -823,14 +789,12 @@ impl Fragment {
|
|||
}
|
||||
|
||||
/// Transforms this fragment using the given `SplitInfo`, preserving all the other data.
|
||||
pub fn transform_with_split_info(&self,
|
||||
split: &SplitInfo,
|
||||
text_run: Arc<Box<TextRun>>)
|
||||
pub fn transform_with_split_info(&self, split: &SplitInfo, text_run: Arc<Box<TextRun>>)
|
||||
-> Fragment {
|
||||
let size = LogicalSize::new(self.style.writing_mode,
|
||||
split.inline_size,
|
||||
self.border_box.size.block);
|
||||
let info = box ScannedTextFragmentInfo::new(text_run, split.range, Vec::new(), size);
|
||||
let info = box ScannedTextFragmentInfo::new(text_run, split.range, size);
|
||||
self.transform(size, SpecificFragmentInfo::ScannedText(info))
|
||||
}
|
||||
|
||||
|
@ -857,7 +821,6 @@ impl Fragment {
|
|||
style: Arc<ComputedValues>,
|
||||
first_frag: bool,
|
||||
last_frag: bool) {
|
||||
|
||||
if self.inline_context.is_none() {
|
||||
self.inline_context = Some(InlineFragmentContext::new());
|
||||
}
|
||||
|
@ -1179,25 +1142,11 @@ impl Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns true if this element can be split. This is true for text fragments.
|
||||
/// Returns true if this element can be split. This is true for text fragments, unless
|
||||
/// `white-space: pre` is set.
|
||||
pub fn can_split(&self) -> bool {
|
||||
self.is_scanned_text_fragment()
|
||||
}
|
||||
|
||||
/// Returns the newline positions of this fragment, if it's a scanned text fragment.
|
||||
pub fn newline_positions(&self) -> Option<&Vec<CharIndex>> {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref info) => Some(&info.new_line_pos),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the newline positions of this fragment, if it's a scanned text fragment.
|
||||
pub fn newline_positions_mut(&mut self) -> Option<&mut Vec<CharIndex>> {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref mut info) => Some(&mut info.new_line_pos),
|
||||
_ => None,
|
||||
}
|
||||
self.is_scanned_text_fragment() &&
|
||||
self.style.get_inheritedtext().white_space != white_space::T::pre
|
||||
}
|
||||
|
||||
/// Returns true if and only if this fragment is a generated content fragment.
|
||||
|
@ -1359,64 +1308,6 @@ impl Fragment {
|
|||
self.border_box - self.border_padding
|
||||
}
|
||||
|
||||
/// Find the split of a fragment that includes a new-line character.
|
||||
///
|
||||
/// A return value of `None` indicates that the fragment is not splittable.
|
||||
/// Otherwise the split information is returned. The right information is
|
||||
/// optional due to the possibility of it being whitespace.
|
||||
//
|
||||
// TODO(bjz): The text run should be removed in the future, but it is currently needed for
|
||||
// the current method of fragment splitting in the `inline::try_append_*` functions.
|
||||
pub fn find_split_info_by_new_line(&self)
|
||||
-> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Canvas(_) |
|
||||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::GeneratedContent(_) |
|
||||
SpecificFragmentInfo::Iframe(_) |
|
||||
SpecificFragmentInfo::Image(_) |
|
||||
SpecificFragmentInfo::Table |
|
||||
SpecificFragmentInfo::TableCell |
|
||||
SpecificFragmentInfo::TableRow |
|
||||
SpecificFragmentInfo::TableWrapper => {
|
||||
None
|
||||
}
|
||||
SpecificFragmentInfo::TableColumn(_) => {
|
||||
panic!("Table column fragments do not need to split")
|
||||
}
|
||||
SpecificFragmentInfo::UnscannedText(_) => {
|
||||
panic!("Unscanned text fragments should have been scanned by now!")
|
||||
}
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
|
||||
panic!("Inline blocks or inline absolute hypothetical fragments do not get split")
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
||||
let mut new_line_pos = text_fragment_info.new_line_pos.clone();
|
||||
let cur_new_line_pos = new_line_pos.remove(0);
|
||||
|
||||
let inline_start_range = Range::new(text_fragment_info.range.begin(),
|
||||
cur_new_line_pos);
|
||||
let inline_end_range = Range::new(
|
||||
text_fragment_info.range.begin() + cur_new_line_pos + CharIndex(1),
|
||||
text_fragment_info.range.length() - (cur_new_line_pos + CharIndex(1)));
|
||||
|
||||
// Left fragment is for inline-start text of first founded new-line character.
|
||||
let inline_start_fragment = SplitInfo::new(inline_start_range,
|
||||
&**text_fragment_info);
|
||||
|
||||
// Right fragment is for inline-end text of first founded new-line character.
|
||||
let inline_end_fragment = if inline_end_range.length() > CharIndex(0) {
|
||||
Some(SplitInfo::new(inline_end_range, &**text_fragment_info))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Some((inline_start_fragment, inline_end_fragment, text_fragment_info.run.clone()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to find the split positions of a text fragment so that its inline-size is no more
|
||||
/// than `max_inline_size`.
|
||||
///
|
||||
|
@ -1495,13 +1386,13 @@ impl Fragment {
|
|||
|
||||
/// A helper method that uses the breaking strategy described by `slice_iterator` (at present,
|
||||
/// either natural word breaking or character breaking) to split this fragment.
|
||||
fn calculate_split_position_using_breaking_strategy<'a,I>(&self,
|
||||
fn calculate_split_position_using_breaking_strategy<'a,I>(
|
||||
&self,
|
||||
slice_iterator: I,
|
||||
max_inline_size: Au,
|
||||
flags: SplitOptions)
|
||||
-> Option<SplitResult>
|
||||
where I: Iterator<Item=
|
||||
TextRunSlice<'a>> {
|
||||
where I: Iterator<Item=TextRunSlice<'a>> {
|
||||
let text_fragment_info =
|
||||
if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific {
|
||||
text_fragment_info
|
||||
|
@ -1515,31 +1406,35 @@ impl Fragment {
|
|||
let mut inline_end_range = None;
|
||||
let mut overflowing = false;
|
||||
|
||||
debug!("calculate_split_position: splitting text fragment (strlen={}, range={:?}, \
|
||||
max_inline_size={:?})",
|
||||
debug!("calculate_split_position_using_breaking_strategy: splitting text fragment \
|
||||
(strlen={}, range={:?}, max_inline_size={:?})",
|
||||
text_fragment_info.run.text.len(),
|
||||
text_fragment_info.range,
|
||||
max_inline_size);
|
||||
|
||||
for slice in slice_iterator {
|
||||
debug!("calculate_split_position: considering slice (offset={:?}, slice range={:?}, \
|
||||
remaining_inline_size={:?})",
|
||||
debug!("calculate_split_position_using_breaking_strategy: considering slice \
|
||||
(offset={:?}, slice range={:?}, remaining_inline_size={:?})",
|
||||
slice.offset,
|
||||
slice.range,
|
||||
remaining_inline_size);
|
||||
|
||||
// Use the `remaining_inline_size` to find a split point if possible. If not, go around
|
||||
// the loop again with the next slice.
|
||||
let metrics = text_fragment_info.run.metrics_for_slice(slice.glyphs, &slice.range);
|
||||
let advance = metrics.advance_width;
|
||||
|
||||
// Have we found the split point?
|
||||
if advance <= remaining_inline_size || slice.glyphs.is_whitespace() {
|
||||
// Keep going; we haven't found the split point yet.
|
||||
if flags.contains(STARTS_LINE) && pieces_processed_count == 0 &&
|
||||
if flags.contains(STARTS_LINE) &&
|
||||
pieces_processed_count == 0 &&
|
||||
slice.glyphs.is_whitespace() {
|
||||
debug!("calculate_split_position: skipping leading trimmable whitespace");
|
||||
debug!("calculate_split_position_using_breaking_strategy: skipping \
|
||||
leading trimmable whitespace");
|
||||
inline_start_range.shift_by(slice.range.length());
|
||||
} else {
|
||||
debug!("split_to_inline_size: enlarging span");
|
||||
debug!("calculate_split_position_using_breaking_strategy: enlarging span");
|
||||
remaining_inline_size = remaining_inline_size - advance;
|
||||
inline_start_range.extend_by(slice.range.length());
|
||||
}
|
||||
|
@ -1570,16 +1465,15 @@ impl Fragment {
|
|||
inline_end);
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// If we failed to find a suitable split point, we're on the verge of overflowing the line.
|
||||
// If we failed to find a suitable split point, we're on the verge of overflowing the
|
||||
// line.
|
||||
if inline_start_range.is_empty() || overflowing {
|
||||
// If we've been instructed to retry at character boundaries (probably via
|
||||
// `overflow-wrap: break-word`), do so.
|
||||
if flags.contains(RETRY_AT_CHARACTER_BOUNDARIES) {
|
||||
let character_breaking_strategy =
|
||||
text_fragment_info.run.character_slices_in_range(&text_fragment_info.range);
|
||||
text_fragment_info.run
|
||||
.character_slices_in_range(&text_fragment_info.range);
|
||||
let mut flags = flags;
|
||||
flags.remove(RETRY_AT_CHARACTER_BOUNDARIES);
|
||||
return self.calculate_split_position_using_breaking_strategy(
|
||||
|
@ -1588,43 +1482,15 @@ impl Fragment {
|
|||
flags)
|
||||
}
|
||||
|
||||
// We aren't at the start of the line, so don't overflow. Let inline layout wrap to the
|
||||
// next line instead.
|
||||
// We aren't at the start of the line, so don't overflow. Let inline layout wrap to
|
||||
// the next line instead.
|
||||
if !flags.contains(STARTS_LINE) {
|
||||
return None
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing whitespace from the inline-start split, if necessary.
|
||||
//
|
||||
// FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
|
||||
strip_trailing_whitespace(&**text_fragment_info.run, &mut inline_start_range);
|
||||
|
||||
// Remove leading whitespace from the inline-end split, if necessary.
|
||||
//
|
||||
// FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
|
||||
if let Some(ref mut inline_end_range) = inline_end_range {
|
||||
let inline_end_fragment_text =
|
||||
text_fragment_info.run.text.slice_chars(inline_end_range.begin().to_usize(),
|
||||
inline_end_range.end().to_usize());
|
||||
let mut leading_whitespace_character_count = 0;
|
||||
for ch in inline_end_fragment_text.chars() {
|
||||
if ch.is_whitespace() {
|
||||
leading_whitespace_character_count += 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
inline_end_range.adjust_by(CharIndex(leading_whitespace_character_count),
|
||||
-CharIndex(leading_whitespace_character_count));
|
||||
}
|
||||
|
||||
// Normalize our split so that the inline-end fragment will never be `Some` while the
|
||||
// inline-start fragment is `None`.
|
||||
if inline_start_range.is_empty() && inline_end_range.is_some() {
|
||||
inline_start_range = inline_end_range.unwrap();
|
||||
inline_end_range = None
|
||||
}
|
||||
|
||||
let inline_start = if !inline_start_range.is_empty() {
|
||||
Some(SplitInfo::new(inline_start_range, &**text_fragment_info))
|
||||
|
@ -1642,22 +1508,21 @@ impl Fragment {
|
|||
})
|
||||
}
|
||||
|
||||
/// Attempts to strip trailing whitespace from this fragment by adjusting the text run range.
|
||||
/// Returns true if any modifications were made.
|
||||
pub fn strip_trailing_whitespace_if_necessary(&mut self) -> bool {
|
||||
let text_fragment_info =
|
||||
if let SpecificFragmentInfo::ScannedText(ref mut text_fragment_info) = self.specific {
|
||||
text_fragment_info
|
||||
} else {
|
||||
return false
|
||||
};
|
||||
|
||||
let run = text_fragment_info.run.clone();
|
||||
if strip_trailing_whitespace(&**run, &mut text_fragment_info.range) {
|
||||
self.border_box.size.inline = run.advance_for_range(&text_fragment_info.range);
|
||||
return true
|
||||
/// The opposite of `calculate_split_position_using_breaking_strategy`: merges this fragment
|
||||
/// with the next one.
|
||||
pub fn merge_with(&mut self, next_fragment: Fragment) {
|
||||
match (&mut self.specific, &next_fragment.specific) {
|
||||
(&mut SpecificFragmentInfo::ScannedText(ref mut this_info),
|
||||
&SpecificFragmentInfo::ScannedText(ref other_info)) => {
|
||||
debug_assert!(util::arc_ptr_eq(&this_info.run, &other_info.run));
|
||||
this_info.range.extend_to(other_info.range_end_including_stripped_whitespace);
|
||||
this_info.content_size.inline =
|
||||
this_info.run.metrics_for_range(&this_info.range).advance_width;
|
||||
self.border_box.size.inline = this_info.content_size.inline +
|
||||
self.border_padding.inline_start_end();
|
||||
}
|
||||
_ => panic!("Can only merge two scanned-text fragments!"),
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns true if this fragment is an unscanned text fragment that consists entirely of
|
||||
|
@ -1669,7 +1534,7 @@ impl Fragment {
|
|||
}
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
|
||||
is_whitespace(text_fragment_info.text.as_slice())
|
||||
util::str::is_whitespace(text_fragment_info.text.as_slice())
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1890,11 +1755,14 @@ impl Fragment {
|
|||
/// Returns true if this fragment can merge with another adjacent fragment or false otherwise.
|
||||
pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
|
||||
match (&self.specific, &other.specific) {
|
||||
(&SpecificFragmentInfo::UnscannedText(_), &SpecificFragmentInfo::UnscannedText(_)) => {
|
||||
(&SpecificFragmentInfo::UnscannedText(ref first_unscanned_text),
|
||||
&SpecificFragmentInfo::UnscannedText(_)) => {
|
||||
// FIXME: Should probably use a whitelist of styles that can safely differ (#3165)
|
||||
let length = first_unscanned_text.text.len();
|
||||
self.style().get_font() == other.style().get_font() &&
|
||||
self.text_decoration() == other.text_decoration() &&
|
||||
self.white_space() == other.white_space()
|
||||
self.white_space() == other.white_space() &&
|
||||
(length == 0 || first_unscanned_text.text.char_at_reverse(length) != '\n')
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -2076,14 +1944,57 @@ impl Fragment {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref scanned_text) => {
|
||||
!scanned_text.range.is_empty() &&
|
||||
scanned_text.run.text.char_at_reverse(scanned_text.range
|
||||
.end()
|
||||
.get() as usize) == '\n'
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn strip_leading_whitespace_if_necessary(&mut self) {
|
||||
let mut scanned_text_fragment_info = match self.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) => {
|
||||
scanned_text_fragment_info
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if self.style.get_inheritedtext().white_space == white_space::T::pre {
|
||||
return
|
||||
}
|
||||
|
||||
let mut leading_whitespace_character_count = 0;
|
||||
{
|
||||
let text = scanned_text_fragment_info.run.text.slice_chars(
|
||||
scanned_text_fragment_info.range.begin().to_usize(),
|
||||
scanned_text_fragment_info.range.end().to_usize());
|
||||
for character in text.chars() {
|
||||
if util::str::char_is_whitespace(character) {
|
||||
leading_whitespace_character_count += 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scanned_text_fragment_info.range.adjust_by(CharIndex(leading_whitespace_character_count),
|
||||
-CharIndex(leading_whitespace_character_count));
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Fragment {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "({} {} ", self.debug_id(), self.specific.get_type()));
|
||||
try!(write!(f, "bp {:?}", self.border_padding));
|
||||
try!(write!(f, " "));
|
||||
try!(write!(f, "m {:?}", self.margin));
|
||||
try!(write!(f, "bb {:?} bp {:?} m {:?}",
|
||||
self.border_box,
|
||||
self.border_padding,
|
||||
self.margin));
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
@ -2105,7 +2016,7 @@ bitflags! {
|
|||
const STARTS_LINE = 0x01,
|
||||
#[doc="True if we should attempt to split at character boundaries if this split fails. \
|
||||
This is used to implement `overflow-wrap: break-word`."]
|
||||
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02
|
||||
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2129,25 +2040,3 @@ pub enum CoordinateSystem {
|
|||
Own,
|
||||
}
|
||||
|
||||
/// Given a range and a text run, adjusts the range to eliminate trailing whitespace. Returns true
|
||||
/// if any modifications were made.
|
||||
fn strip_trailing_whitespace(text_run: &TextRun, range: &mut Range<CharIndex>) -> bool {
|
||||
// FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
|
||||
let text = text_run.text.slice_chars(range.begin().to_usize(), range.end().to_usize());
|
||||
let mut trailing_whitespace_character_count = 0;
|
||||
for ch in text.chars().rev() {
|
||||
if ch.is_whitespace() {
|
||||
trailing_whitespace_character_count += 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if trailing_whitespace_character_count == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
range.extend_by(-CharIndex(trailing_whitespace_character_count));
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,9 @@ use css::node_style::StyledNode;
|
|||
use context::LayoutContext;
|
||||
use display_list_builder::{FragmentDisplayListBuilding, InlineFlowDisplayListBuilding};
|
||||
use floats::{FloatKind, Floats, PlacementInfo};
|
||||
use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
|
||||
use flow::{self, BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
|
||||
use flow::{IS_ABSOLUTELY_POSITIONED};
|
||||
use flow;
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, ScannedTextFragmentInfo};
|
||||
use fragment::{SpecificFragmentInfo, SplitInfo};
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
|
||||
use layout_debug;
|
||||
use model::IntrinsicISizesContribution;
|
||||
|
@ -23,20 +21,21 @@ use geom::{Point2D, Rect};
|
|||
use gfx::font::FontMetrics;
|
||||
use gfx::font_context::FontContext;
|
||||
use gfx::text::glyph::CharIndex;
|
||||
use util::arc_ptr_eq;
|
||||
use util::geometry::{Au, ZERO_RECT};
|
||||
use util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
|
||||
use util::range::{Range, RangeIndex};
|
||||
use gfx::text::text_run::TextRun;
|
||||
use std::cmp::max;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::num::ToPrimitive;
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor};
|
||||
use std::sync::Arc;
|
||||
use std::u16;
|
||||
use style::computed_values::{overflow_x, text_align, text_justify, text_overflow, vertical_align};
|
||||
use style::computed_values::{white_space};
|
||||
use style::properties::ComputedValues;
|
||||
use std::sync::Arc;
|
||||
use util::geometry::{Au, MAX_AU, ZERO_RECT};
|
||||
use util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
|
||||
use util::range::{Range, RangeIndex};
|
||||
use util;
|
||||
|
||||
// From gfxFontConstants.h in Firefox
|
||||
static FONT_SUBSCRIPT_OFFSET_RATIO: f64 = 0.20;
|
||||
|
@ -160,7 +159,9 @@ int_range_index! {
|
|||
bitflags! {
|
||||
flags InlineReflowFlags: u8 {
|
||||
#[doc="The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."]
|
||||
const NO_WRAP_INLINE_REFLOW_FLAG = 0x01
|
||||
const NO_WRAP_INLINE_REFLOW_FLAG = 0x01,
|
||||
#[doc="The `white-space: pre` property from CSS 2.1 § 16.6 is in effect."]
|
||||
const WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG = 0x02
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +192,7 @@ impl LineBreaker {
|
|||
pending_line: Line {
|
||||
range: Range::empty(),
|
||||
bounds: LogicalRect::zero(float_context.writing_mode),
|
||||
green_zone: LogicalSize::zero(float_context.writing_mode)
|
||||
green_zone: LogicalSize::zero(float_context.writing_mode),
|
||||
},
|
||||
floats: float_context,
|
||||
lines: Vec::new(),
|
||||
|
@ -216,7 +217,7 @@ impl LineBreaker {
|
|||
self.cur_b,
|
||||
Au(0),
|
||||
Au(0));
|
||||
self.pending_line.green_zone = LogicalSize::zero(self.floats.writing_mode)
|
||||
self.pending_line.green_zone = LogicalSize::zero(self.floats.writing_mode);
|
||||
}
|
||||
|
||||
/// Reflows fragments for the given inline flow.
|
||||
|
@ -226,23 +227,13 @@ impl LineBreaker {
|
|||
// Create our fragment iterator.
|
||||
debug!("LineBreaker: scanning for lines, {} fragments", flow.fragments.len());
|
||||
let mut old_fragments = mem::replace(&mut flow.fragments, InlineFragments::new());
|
||||
let mut old_fragment_iter = old_fragments.fragments.into_iter();
|
||||
let old_fragment_iter = old_fragments.fragments.into_iter();
|
||||
|
||||
// Set up our initial line state with the clean lines from a previous reflow.
|
||||
//
|
||||
// TODO(pcwalton): This would likely be better as a list of dirty line indices. That way we
|
||||
// could resynchronize if we discover during reflow that all subsequent fragments must have
|
||||
// the same position as they had in the previous reflow. I don't know how common this case
|
||||
// really is in practice, but it's probably worth handling.
|
||||
self.lines = mem::replace(&mut flow.lines, Vec::new());
|
||||
match self.lines.as_slice().last() {
|
||||
None => {}
|
||||
Some(last_line) => {
|
||||
for _ in range(FragmentIndex(0), last_line.range.end()) {
|
||||
self.new_fragments.push(old_fragment_iter.next().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
self.lines = Vec::new();
|
||||
|
||||
// Do the reflow.
|
||||
self.reflow_fragments(old_fragment_iter, flow, layout_context);
|
||||
|
@ -270,30 +261,14 @@ impl LineBreaker {
|
|||
// Set up our reflow flags.
|
||||
let flags = match fragment.style().get_inheritedtext().white_space {
|
||||
white_space::T::normal => InlineReflowFlags::empty(),
|
||||
white_space::T::pre | white_space::T::nowrap => NO_WRAP_INLINE_REFLOW_FLAG,
|
||||
white_space::T::nowrap => NO_WRAP_INLINE_REFLOW_FLAG,
|
||||
white_space::T::pre => {
|
||||
WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG | NO_WRAP_INLINE_REFLOW_FLAG
|
||||
}
|
||||
};
|
||||
|
||||
// Try to append the fragment, and commit the line (so we can try again with the next
|
||||
// line) if we couldn't.
|
||||
match fragment.style().get_inheritedtext().white_space {
|
||||
white_space::T::normal | white_space::T::nowrap => {
|
||||
if !self.append_fragment_to_line_if_possible(fragment,
|
||||
flow,
|
||||
layout_context,
|
||||
flags) {
|
||||
self.flush_current_line()
|
||||
}
|
||||
}
|
||||
white_space::T::pre => {
|
||||
// FIXME(pcwalton): Surely we can unify
|
||||
// `append_fragment_to_line_if_possible` and
|
||||
// `try_append_to_line_by_new_line` by adding another bit in the reflow
|
||||
// flags.
|
||||
if !self.try_append_to_line_by_new_line(layout_context, fragment) {
|
||||
self.flush_current_line()
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try to append the fragment.
|
||||
self.reflow_fragment(fragment, flow, layout_context, flags);
|
||||
}
|
||||
|
||||
if !self.pending_line_is_empty() {
|
||||
|
@ -301,37 +276,25 @@ impl LineBreaker {
|
|||
self.lines.len());
|
||||
self.flush_current_line()
|
||||
}
|
||||
|
||||
// Strip trailing whitespace from the last line if necessary.
|
||||
if let Some(ref mut last_line) = self.lines.last_mut() {
|
||||
if let Some(ref mut last_fragment) = self.new_fragments.last_mut() {
|
||||
let previous_inline_size = last_line.bounds.size.inline -
|
||||
last_fragment.border_box.size.inline;
|
||||
if last_fragment.strip_trailing_whitespace_if_necessary() {
|
||||
last_line.bounds.size.inline = previous_inline_size +
|
||||
last_fragment.border_box.size.inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Acquires a new fragment to lay out from the work list or fragment list as appropriate.
|
||||
/// Note that you probably don't want to call this method directly in order to be
|
||||
/// incremental-reflow-safe; try `next_unbroken_fragment` instead.
|
||||
/// If the fragment was at the end of an old line, undoes the line break for that fragment.
|
||||
/// Note that you probably don't want to call this method directly in order to be incremental-
|
||||
/// reflow-safe; try `next_unbroken_fragment` instead.
|
||||
fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
|
||||
where I: Iterator<Item=Fragment> {
|
||||
let mut fragment;
|
||||
if self.work_list.is_empty() {
|
||||
return match old_fragment_iter.next() {
|
||||
None => None,
|
||||
Some(fragment) => {
|
||||
debug!("LineBreaker: working with fragment from flow: {:?}", fragment);
|
||||
Some(fragment)
|
||||
}
|
||||
match old_fragment_iter.next() {
|
||||
None => return None,
|
||||
Some(this_fragment) => fragment = this_fragment,
|
||||
}
|
||||
} else {
|
||||
return self.work_list.pop_front()
|
||||
}
|
||||
|
||||
debug!("LineBreaker: working with fragment from work list: {:?}", self.work_list.front());
|
||||
self.work_list.pop_front()
|
||||
Some(fragment)
|
||||
}
|
||||
|
||||
/// Acquires a new fragment to lay out from the work list or fragment list, merging it with any
|
||||
|
@ -346,10 +309,6 @@ impl LineBreaker {
|
|||
};
|
||||
|
||||
loop {
|
||||
// FIXME(pcwalton): Yuck! I hate this `new_line_pos` stuff. Can we avoid having to do
|
||||
// this?
|
||||
result.restore_new_line_pos();
|
||||
|
||||
let candidate = match self.next_fragment(old_fragment_iter) {
|
||||
None => return Some(result),
|
||||
Some(fragment) => fragment,
|
||||
|
@ -357,31 +316,58 @@ impl LineBreaker {
|
|||
|
||||
let need_to_merge = match (&mut result.specific, &candidate.specific) {
|
||||
(&mut SpecificFragmentInfo::ScannedText(ref mut result_info),
|
||||
&SpecificFragmentInfo::ScannedText(ref candidate_info))
|
||||
if arc_ptr_eq(&result_info.run, &candidate_info.run) &&
|
||||
result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => {
|
||||
// We found a previously-broken fragment. Merge it up.
|
||||
result_info.range.extend_by(candidate_info.range.length() + CharIndex(1));
|
||||
true
|
||||
&SpecificFragmentInfo::ScannedText(ref candidate_info)) => {
|
||||
util::arc_ptr_eq(&result_info.run, &candidate_info.run) &&
|
||||
inline_contexts_are_equal(&result.inline_context,
|
||||
&candidate.inline_context)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !need_to_merge {
|
||||
|
||||
if need_to_merge {
|
||||
result.merge_with(candidate);
|
||||
continue
|
||||
}
|
||||
|
||||
self.work_list.push_front(candidate);
|
||||
return Some(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Commits a line to the list.
|
||||
fn flush_current_line(&mut self) {
|
||||
debug!("LineBreaker: flushing line {}: {:?}", self.lines.len(), self.pending_line);
|
||||
self.strip_trailing_whitespace_from_pending_line_if_necessary();
|
||||
self.lines.push(self.pending_line);
|
||||
self.cur_b = self.pending_line.bounds.start.b + self.pending_line.bounds.size.block;
|
||||
self.reset_line();
|
||||
}
|
||||
|
||||
/// Removes trailing whitespace from the pending line if necessary. This is done right before
|
||||
/// flushing it.
|
||||
fn strip_trailing_whitespace_from_pending_line_if_necessary(&mut self) {
|
||||
if self.pending_line.range.is_empty() {
|
||||
return
|
||||
}
|
||||
let last_fragment_index = self.pending_line.range.end() - FragmentIndex(1);
|
||||
let mut fragment = &mut self.new_fragments[last_fragment_index.get() as usize];
|
||||
if let SpecificFragmentInfo::ScannedText(ref mut scanned_text_fragment_info) =
|
||||
fragment.specific {
|
||||
let scanned_text_fragment_info = &mut **scanned_text_fragment_info;
|
||||
let mut range = &mut scanned_text_fragment_info.range;
|
||||
strip_trailing_whitespace_if_necessary(&**scanned_text_fragment_info.run, range);
|
||||
|
||||
let old_fragment_inline_size = fragment.border_box.size.inline;
|
||||
scanned_text_fragment_info.content_size.inline =
|
||||
scanned_text_fragment_info.run.metrics_for_range(range).advance_width;
|
||||
fragment.border_box.size.inline = scanned_text_fragment_info.content_size.inline +
|
||||
fragment.border_padding.inline_start_end();
|
||||
self.pending_line.bounds.size.inline = self.pending_line.bounds.size.inline -
|
||||
(old_fragment_inline_size - fragment.border_box.size.inline)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(eatkinson): this assumes that the tallest fragment in the line determines the line
|
||||
// block-size. This might not be the case with some weird text fonts.
|
||||
fn new_block_size_for_line(&self, new_fragment: &Fragment, layout_context: &LayoutContext)
|
||||
|
@ -488,71 +474,16 @@ impl LineBreaker {
|
|||
false
|
||||
}
|
||||
|
||||
/// Tries to append the given fragment to the line for `pre`-formatted text, splitting it if
|
||||
/// necessary. Returns true if we successfully pushed the fragment to the line or false if we
|
||||
/// couldn't.
|
||||
fn try_append_to_line_by_new_line(&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
in_fragment: Fragment)
|
||||
-> bool {
|
||||
let should_push = match in_fragment.newline_positions() {
|
||||
None => true,
|
||||
Some(ref positions) => positions.is_empty(),
|
||||
};
|
||||
if should_push {
|
||||
debug!("LineBreaker: did not find a newline character; pushing the fragment to \
|
||||
the line without splitting");
|
||||
self.push_fragment_to_line(layout_context, in_fragment);
|
||||
return true
|
||||
}
|
||||
|
||||
debug!("LineBreaker: Found a new-line character, so splitting the line.");
|
||||
|
||||
let (inline_start, inline_end, run) =
|
||||
in_fragment.find_split_info_by_new_line()
|
||||
.expect("LineBreaker: this split case makes no sense!");
|
||||
let writing_mode = self.floats.writing_mode;
|
||||
|
||||
let split_fragment = |split: SplitInfo| {
|
||||
let size = LogicalSize::new(writing_mode,
|
||||
split.inline_size,
|
||||
in_fragment.border_box.size.block);
|
||||
let info = box ScannedTextFragmentInfo::new(run.clone(),
|
||||
split.range,
|
||||
(*in_fragment.newline_positions()
|
||||
.unwrap()).clone(),
|
||||
size);
|
||||
in_fragment.transform(size, SpecificFragmentInfo::ScannedText(info))
|
||||
};
|
||||
|
||||
debug!("LineBreaker: Pushing the fragment to the inline_start of the new-line character \
|
||||
to the line.");
|
||||
let mut inline_start = split_fragment(inline_start);
|
||||
inline_start.save_new_line_pos();
|
||||
*inline_start.newline_positions_mut().unwrap() = vec![];
|
||||
self.push_fragment_to_line(layout_context, inline_start);
|
||||
|
||||
for inline_end in inline_end.into_iter() {
|
||||
debug!("LineBreaker: Deferring the fragment to the inline_end of the new-line \
|
||||
character to the line.");
|
||||
let mut inline_end = split_fragment(inline_end);
|
||||
inline_end.newline_positions_mut().unwrap().remove(0);
|
||||
self.work_list.push_front(inline_end);
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Tries to append the given fragment to the line, splitting it if necessary. Returns true if
|
||||
/// we successfully pushed the fragment to the line or false if we couldn't.
|
||||
fn append_fragment_to_line_if_possible(&mut self,
|
||||
fragment: Fragment,
|
||||
/// Tries to append the given fragment to the line, splitting it if necessary. Commits the
|
||||
/// current line if needed.
|
||||
fn reflow_fragment(&mut self,
|
||||
mut fragment: Fragment,
|
||||
flow: &InlineFlow,
|
||||
layout_context: &LayoutContext,
|
||||
flags: InlineReflowFlags)
|
||||
-> bool {
|
||||
flags: InlineReflowFlags) {
|
||||
// Determine initial placement for the fragment if we need to.
|
||||
if self.pending_line_is_empty() {
|
||||
fragment.strip_leading_whitespace_if_necessary();
|
||||
let (line_bounds, _) = self.initial_line_placement(flow, &fragment, self.cur_b);
|
||||
self.pending_line.bounds.start = line_bounds.start;
|
||||
self.pending_line.green_zone = line_bounds.size;
|
||||
|
@ -572,8 +503,21 @@ impl LineBreaker {
|
|||
let new_block_size = self.new_block_size_for_line(&fragment, layout_context);
|
||||
if new_block_size > green_zone.block {
|
||||
// Uh-oh. Float collision imminent. Enter the float collision avoider!
|
||||
return self.avoid_floats(flow, fragment, new_block_size)
|
||||
if !self.avoid_floats(flow, fragment, new_block_size) {
|
||||
self.flush_current_line();
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// If we must flush the line after finishing this fragment due to `white-space: pre`,
|
||||
// detect that.
|
||||
let line_flush_mode =
|
||||
if flags.contains(WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG) &&
|
||||
fragment.requires_line_break_afterward_if_wrapping_on_newlines() {
|
||||
LineFlushMode::Flush
|
||||
} else {
|
||||
LineFlushMode::No
|
||||
};
|
||||
|
||||
// If we're not going to overflow the green zone vertically, we might still do so
|
||||
// horizontally. We'll try to place the whole fragment on this line and break somewhere if
|
||||
|
@ -583,23 +527,27 @@ impl LineBreaker {
|
|||
fragment.border_box.size.inline + indentation;
|
||||
if new_inline_size <= green_zone.inline {
|
||||
debug!("LineBreaker: fragment fits without splitting");
|
||||
self.push_fragment_to_line(layout_context, fragment);
|
||||
return true
|
||||
self.push_fragment_to_line(layout_context, fragment, line_flush_mode);
|
||||
return
|
||||
}
|
||||
|
||||
// If we can't split the fragment or aren't allowed to because of the wrapping mode, then
|
||||
// just overflow.
|
||||
if (!fragment.can_split() && self.pending_line_is_empty()) ||
|
||||
flags.contains(NO_WRAP_INLINE_REFLOW_FLAG) {
|
||||
(flags.contains(NO_WRAP_INLINE_REFLOW_FLAG) &&
|
||||
!flags.contains(WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG)) {
|
||||
debug!("LineBreaker: fragment can't split and line {} is empty, so overflowing",
|
||||
self.lines.len());
|
||||
self.push_fragment_to_line(layout_context, fragment);
|
||||
return false
|
||||
self.push_fragment_to_line(layout_context, fragment, LineFlushMode::No);
|
||||
return
|
||||
}
|
||||
|
||||
// Split it up!
|
||||
let available_inline_size = green_zone.inline - self.pending_line.bounds.size.inline -
|
||||
indentation;
|
||||
let available_inline_size = if !flags.contains(NO_WRAP_INLINE_REFLOW_FLAG) {
|
||||
green_zone.inline - self.pending_line.bounds.size.inline - indentation
|
||||
} else {
|
||||
MAX_AU
|
||||
};
|
||||
let inline_start_fragment;
|
||||
let inline_end_fragment;
|
||||
let split_result = match fragment.calculate_split_position(available_inline_size,
|
||||
|
@ -607,7 +555,8 @@ impl LineBreaker {
|
|||
None => {
|
||||
debug!("LineBreaker: fragment was unsplittable; deferring to next line");
|
||||
self.work_list.push_front(fragment);
|
||||
return false
|
||||
self.flush_current_line();
|
||||
return
|
||||
}
|
||||
Some(split_result) => split_result,
|
||||
};
|
||||
|
@ -623,23 +572,30 @@ impl LineBreaker {
|
|||
// the second fragment. If there's no second fragment, the next line will start off empty.
|
||||
match (inline_start_fragment, inline_end_fragment) {
|
||||
(Some(inline_start_fragment), Some(inline_end_fragment)) => {
|
||||
self.push_fragment_to_line(layout_context, inline_start_fragment);
|
||||
self.flush_current_line();
|
||||
self.push_fragment_to_line(layout_context,
|
||||
inline_start_fragment,
|
||||
LineFlushMode::Flush);
|
||||
self.work_list.push_front(inline_end_fragment)
|
||||
},
|
||||
(Some(fragment), None) => {
|
||||
self.push_fragment_to_line(layout_context, fragment);
|
||||
self.push_fragment_to_line(layout_context, fragment, line_flush_mode);
|
||||
}
|
||||
(None, Some(fragment)) => {
|
||||
// Yes, this can happen!
|
||||
self.flush_current_line();
|
||||
self.work_list.push_front(fragment)
|
||||
}
|
||||
(None, Some(_)) => debug_assert!(false, "un-normalized split result"),
|
||||
(None, None) => {}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Pushes a fragment to the current line unconditionally, possibly truncating it and placing
|
||||
/// an ellipsis based on the value of `text-overflow`.
|
||||
fn push_fragment_to_line(&mut self, layout_context: &LayoutContext, fragment: Fragment) {
|
||||
/// an ellipsis based on the value of `text-overflow`. If `flush_line` is `Flush`, then flushes
|
||||
/// the line afterward;
|
||||
fn push_fragment_to_line(&mut self,
|
||||
layout_context: &LayoutContext,
|
||||
fragment: Fragment,
|
||||
line_flush_mode: LineFlushMode) {
|
||||
let indentation = self.indentation_for_pending_fragment();
|
||||
if self.pending_line_is_empty() {
|
||||
assert!(self.new_fragments.len() <= (u16::MAX as usize));
|
||||
|
@ -661,9 +617,7 @@ impl LineBreaker {
|
|||
|
||||
if !need_ellipsis {
|
||||
self.push_fragment_to_line_ignoring_text_overflow(fragment);
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
let ellipsis = fragment.transform_into_ellipsis(layout_context);
|
||||
if let Some(truncation_info) =
|
||||
fragment.truncate_to_inline_size(available_inline_size -
|
||||
|
@ -675,11 +629,15 @@ impl LineBreaker {
|
|||
self.push_fragment_to_line_ignoring_text_overflow(ellipsis);
|
||||
}
|
||||
|
||||
if line_flush_mode == LineFlushMode::Flush {
|
||||
self.flush_current_line()
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes a fragment to the current line unconditionally, without placing an ellipsis in the
|
||||
/// case of `text-overflow: ellipsis`.
|
||||
fn push_fragment_to_line_ignoring_text_overflow(&mut self, fragment: Fragment) {
|
||||
let indentation = self.indentation_for_pending_fragment();
|
||||
|
||||
self.pending_line.range.extend_by(FragmentIndex(1));
|
||||
self.pending_line.bounds.size.inline = self.pending_line.bounds.size.inline +
|
||||
fragment.border_box.size.inline +
|
||||
|
@ -813,7 +771,7 @@ impl InlineFlow {
|
|||
///
|
||||
/// The extra boolean is set if and only if `largest_block_size_for_top_fragments` and/or
|
||||
/// `largest_block_size_for_bottom_fragments` were updated. That is, if the box has a `top` or
|
||||
/// `bottom` value for `vertical-align, true is returned.
|
||||
/// `bottom` value for `vertical-align`, true is returned.
|
||||
fn distance_from_baseline(fragment: &Fragment,
|
||||
ascent: Au,
|
||||
parent_text_block_start: Au,
|
||||
|
@ -1180,7 +1138,7 @@ impl Flow for InlineFlow {
|
|||
// Reset our state, so that we handle incremental reflow correctly.
|
||||
//
|
||||
// TODO(pcwalton): Do something smarter, like Gecko and WebKit?
|
||||
self.lines = Vec::new();
|
||||
self.lines.clear();
|
||||
|
||||
// Determine how much indentation the first line wants.
|
||||
let mut indentation = if self.fragments.is_empty() {
|
||||
|
@ -1431,6 +1389,30 @@ impl InlineFragmentContext {
|
|||
styles: vec!()
|
||||
}
|
||||
}
|
||||
|
||||
fn ptr_eq(&self, other: &InlineFragmentContext) -> bool {
|
||||
if self.styles.len() != other.styles.len() {
|
||||
return false
|
||||
}
|
||||
for (this_style, other_style) in self.styles.iter().zip(other.styles.iter()) {
|
||||
if !util::arc_ptr_eq(this_style, other_style) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn inline_contexts_are_equal(inline_context_a: &Option<InlineFragmentContext>,
|
||||
inline_context_b: &Option<InlineFragmentContext>)
|
||||
-> bool {
|
||||
match (inline_context_a, inline_context_b) {
|
||||
(&Some(ref inline_context_a), &Some(ref inline_context_b)) => {
|
||||
inline_context_a.ptr_eq(inline_context_b)
|
||||
}
|
||||
(&None, &None) => true,
|
||||
(&Some(_), &None) | (&None, &Some(_)) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Block-size above the baseline, depth below the baseline, and ascent for a fragment. See CSS 2.1
|
||||
|
@ -1464,3 +1446,31 @@ impl InlineMetrics {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum LineFlushMode {
|
||||
No,
|
||||
Flush,
|
||||
}
|
||||
|
||||
/// Given a range and a text run, adjusts the range to eliminate trailing whitespace.
|
||||
fn strip_trailing_whitespace_if_necessary(text_run: &TextRun, range: &mut Range<CharIndex>) {
|
||||
// FIXME(pcwalton): Is there a more clever (i.e. faster) way to do this?
|
||||
debug!("stripping trailing whitespace: range={:?}, len={}",
|
||||
range,
|
||||
text_run.text.chars().count());
|
||||
let text = text_run.text.slice_chars(range.begin().to_usize(), range.end().to_usize());
|
||||
let mut trailing_whitespace_character_count = 0;
|
||||
for ch in text.chars().rev() {
|
||||
if util::str::char_is_whitespace(ch) {
|
||||
trailing_whitespace_character_count += 1
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if trailing_whitespace_character_count != 0 {
|
||||
range.extend_by(CharIndex(-trailing_whitespace_character_count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,12 @@ impl MarginCollapseInfo {
|
|||
|
||||
pub fn current_float_ceiling(&mut self) -> Au {
|
||||
match self.state {
|
||||
MarginCollapseState::AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
|
||||
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
|
||||
// We do not include the top margin in the float ceiling, because the float flow
|
||||
// needs to be positioned relative to our *border box*, not our margin box. See
|
||||
// `tests/ref/float_under_top_margin_a.html`.
|
||||
Au(0)
|
||||
}
|
||||
MarginCollapseState::AccumulatingMarginIn => self.margin_in.collapse(),
|
||||
}
|
||||
}
|
||||
|
@ -182,18 +187,22 @@ impl MarginCollapseInfo {
|
|||
/// Adds the child's potentially collapsible block-start margin to the current margin state and
|
||||
/// advances the Y offset by the appropriate amount to handle that margin. Returns the amount
|
||||
/// that should be added to the Y offset during block layout.
|
||||
pub fn advance_block_start_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
|
||||
pub fn advance_block_start_margin(&mut self, child_collapsible_margins: &CollapsibleMargins)
|
||||
-> Au {
|
||||
match (self.state, *child_collapsible_margins) {
|
||||
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(block_start, _)) => {
|
||||
(MarginCollapseState::AccumulatingCollapsibleTopMargin,
|
||||
CollapsibleMargins::None(block_start, _)) => {
|
||||
self.state = MarginCollapseState::AccumulatingMarginIn;
|
||||
block_start
|
||||
}
|
||||
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::Collapse(block_start, _)) => {
|
||||
(MarginCollapseState::AccumulatingCollapsibleTopMargin,
|
||||
CollapsibleMargins::Collapse(block_start, _)) => {
|
||||
self.block_start_margin.union(block_start);
|
||||
self.state = MarginCollapseState::AccumulatingMarginIn;
|
||||
Au(0)
|
||||
}
|
||||
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(block_start, _)) => {
|
||||
(MarginCollapseState::AccumulatingMarginIn,
|
||||
CollapsibleMargins::None(block_start, _)) => {
|
||||
let previous_margin_value = self.margin_in.collapse();
|
||||
self.margin_in = AdjoiningMargins::new();
|
||||
previous_margin_value + block_start
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#![deny(unsafe_code)]
|
||||
|
||||
use fragment::{Fragment, SpecificFragmentInfo, ScannedTextFragmentInfo};
|
||||
use fragment::{Fragment, SpecificFragmentInfo, ScannedTextFragmentInfo, UnscannedTextFragmentInfo};
|
||||
use inline::InlineFragments;
|
||||
|
||||
use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG};
|
||||
|
@ -15,18 +15,19 @@ use gfx::font_context::FontContext;
|
|||
use gfx::text::glyph::CharIndex;
|
||||
use gfx::text::text_run::TextRun;
|
||||
use gfx::text::util::{self, CompressionMode};
|
||||
use util::linked_list::split_off_head;
|
||||
use util::geometry::Au;
|
||||
use util::logical_geometry::{LogicalSize, WritingMode};
|
||||
use util::range::Range;
|
||||
use util::smallvec::{SmallVec, SmallVec1};
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::LinkedList;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
|
||||
use style::computed_values::{white_space};
|
||||
use style::properties::ComputedValues;
|
||||
use style::properties::style_structs::Font as FontStyle;
|
||||
use std::sync::Arc;
|
||||
use util::geometry::Au;
|
||||
use util::linked_list::split_off_head;
|
||||
use util::logical_geometry::{LogicalSize, WritingMode};
|
||||
use util::range::Range;
|
||||
use util::smallvec::{SmallVec, SmallVec1};
|
||||
|
||||
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s.
|
||||
pub struct TextRunScanner {
|
||||
|
@ -40,7 +41,9 @@ impl TextRunScanner {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn scan_for_runs(&mut self, font_context: &mut FontContext, mut fragments: LinkedList<Fragment>)
|
||||
pub fn scan_for_runs(&mut self,
|
||||
font_context: &mut FontContext,
|
||||
mut fragments: LinkedList<Fragment>)
|
||||
-> InlineFragments {
|
||||
debug!("TextRunScanner: scanning {} fragments for text runs...", fragments.len());
|
||||
|
||||
|
@ -50,12 +53,14 @@ impl TextRunScanner {
|
|||
let mut last_whitespace = true;
|
||||
while !fragments.is_empty() {
|
||||
// Create a clump.
|
||||
split_first_fragment_at_newline_if_necessary(&mut fragments);
|
||||
self.clump.append(&mut split_off_head(&mut fragments));
|
||||
while !fragments.is_empty() && self.clump
|
||||
.back()
|
||||
.unwrap()
|
||||
.can_merge_with_fragment(fragments.front()
|
||||
.unwrap()) {
|
||||
split_first_fragment_at_newline_if_necessary(&mut fragments);
|
||||
self.clump.append(&mut split_off_head(&mut fragments));
|
||||
}
|
||||
|
||||
|
@ -101,7 +106,6 @@ impl TextRunScanner {
|
|||
//
|
||||
// Concatenate all of the transformed strings together, saving the new character indices.
|
||||
let mut new_ranges: SmallVec1<Range<CharIndex>> = SmallVec1::new();
|
||||
let mut new_line_positions: SmallVec1<NewLinePositions> = SmallVec1::new();
|
||||
let mut char_total = CharIndex(0);
|
||||
let run = {
|
||||
let fontgroup;
|
||||
|
@ -137,14 +141,11 @@ impl TextRunScanner {
|
|||
_ => panic!("Expected an unscanned text fragment!"),
|
||||
};
|
||||
|
||||
let mut new_line_pos = Vec::new();
|
||||
let old_length = CharIndex(run_text.chars().count() as isize);
|
||||
last_whitespace = util::transform_text(in_fragment.as_slice(),
|
||||
compression,
|
||||
last_whitespace,
|
||||
&mut run_text,
|
||||
&mut new_line_pos);
|
||||
new_line_positions.push(NewLinePositions(new_line_pos));
|
||||
&mut run_text);
|
||||
|
||||
let added_chars = CharIndex(run_text.chars().count() as isize) - old_length;
|
||||
new_ranges.push(Range::new(char_total, added_chars));
|
||||
|
@ -200,13 +201,8 @@ impl TextRunScanner {
|
|||
}
|
||||
|
||||
let text_size = old_fragment.border_box.size;
|
||||
let &mut NewLinePositions(ref mut new_line_positions) =
|
||||
new_line_positions.get_mut(logical_offset);
|
||||
let mut new_text_fragment_info =
|
||||
box ScannedTextFragmentInfo::new(run.clone(),
|
||||
range,
|
||||
mem::replace(new_line_positions, Vec::new()),
|
||||
text_size);
|
||||
box ScannedTextFragmentInfo::new(run.clone(), range, text_size);
|
||||
let new_metrics = new_text_fragment_info.run.metrics_for_range(&range);
|
||||
let bounding_box_size = bounding_box_for_run_metrics(&new_metrics,
|
||||
old_fragment.style.writing_mode);
|
||||
|
@ -270,8 +266,6 @@ impl TextRunScanner {
|
|||
}
|
||||
}
|
||||
|
||||
struct NewLinePositions(Vec<CharIndex>);
|
||||
|
||||
#[inline]
|
||||
fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode)
|
||||
-> LogicalSize<Au> {
|
||||
|
@ -318,3 +312,45 @@ pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) ->
|
|||
line_height::T::Length(l) => l
|
||||
}
|
||||
}
|
||||
|
||||
fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragment>) {
|
||||
if fragments.len() < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
let new_fragment = {
|
||||
let mut first_fragment = fragments.front_mut().unwrap();
|
||||
let string_before;
|
||||
{
|
||||
let unscanned_text_fragment_info = match first_fragment.specific {
|
||||
SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
|
||||
unscanned_text_fragment_info
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if first_fragment.style.get_inheritedtext().white_space != white_space::T::pre {
|
||||
return
|
||||
}
|
||||
|
||||
let position = match unscanned_text_fragment_info.text.find('\n') {
|
||||
Some(position) if position < unscanned_text_fragment_info.text.len() - 1 => {
|
||||
position
|
||||
}
|
||||
Some(_) | None => return,
|
||||
};
|
||||
|
||||
string_before =
|
||||
box unscanned_text_fragment_info.text[..(position + 1)].to_owned();
|
||||
unscanned_text_fragment_info.text =
|
||||
box unscanned_text_fragment_info.text[(position + 1)..].to_owned();
|
||||
}
|
||||
first_fragment.transform(first_fragment.border_box.size,
|
||||
SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo {
|
||||
text: string_before,
|
||||
}))
|
||||
};
|
||||
|
||||
fragments.push_front(new_fragment);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,11 +41,12 @@ use opaque_node::OpaqueNodeMethods;
|
|||
|
||||
use cssparser::RGBA;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLCanvasElementCast, HTMLImageElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTextAreaElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{NodeCast, TextCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLCanvasElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
|
||||
use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast};
|
||||
use script::dom::bindings::js::LayoutJS;
|
||||
use script::dom::characterdata::LayoutCharacterDataHelpers;
|
||||
use script::dom::element::{Element, ElementTypeId};
|
||||
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
|
||||
use script::dom::htmlelement::HTMLElementTypeId;
|
||||
|
@ -222,9 +223,8 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
|
|||
let text: Option<LayoutJS<Text>> = TextCast::to_layout_js(self.get_jsmanaged());
|
||||
if let Some(text) = text {
|
||||
return vec![
|
||||
ContentItem::String((*text.unsafe_get()).characterdata()
|
||||
.data_for_layout()
|
||||
.to_owned())
|
||||
ContentItem::String(
|
||||
CharacterDataCast::from_layout_js(&text).data_for_layout().to_owned())
|
||||
];
|
||||
}
|
||||
let input: Option<LayoutJS<HTMLInputElement>> =
|
||||
|
@ -961,7 +961,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
|||
None => return false
|
||||
};
|
||||
|
||||
if !is_whitespace((*text.unsafe_get()).characterdata().data_for_layout()) {
|
||||
if !is_whitespace(CharacterDataCast::from_layout_js(&text).data_for_layout()) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ impl MIMEClassifier {
|
|||
self.binary_or_plaintext.classify(data)
|
||||
}
|
||||
fn is_xml(tp: &str, sub_tp: &str) -> bool {
|
||||
let suffix = &sub_tp[(max((sub_tp.len() as int) - ("+xml".len() as int), 0i) as uint)..];
|
||||
let suffix = &sub_tp[(max(sub_tp.len() as isize - "+xml".len() as isize, 0) as usize)..];
|
||||
match (tp, sub_tp, suffix) {
|
||||
(_, _, "+xml") | ("application", "xml",_) | ("text", "xml",_) => {true}
|
||||
_ => {false}
|
||||
|
@ -170,13 +170,13 @@ struct ByteMatcher {
|
|||
}
|
||||
|
||||
impl ByteMatcher {
|
||||
fn matches(&self, data: &Vec<u8>) -> Option<uint> {
|
||||
fn matches(&self, data: &Vec<u8>) -> Option<usize> {
|
||||
|
||||
if data.len() < self.pattern.len() {
|
||||
return None;
|
||||
}
|
||||
//TODO replace with iterators if I ever figure them out...
|
||||
let mut i = 0u;
|
||||
let mut i: usize = 0;
|
||||
let max_i = data.len()-self.pattern.len();
|
||||
|
||||
loop {
|
||||
|
@ -184,12 +184,12 @@ impl ByteMatcher {
|
|||
break;
|
||||
}
|
||||
|
||||
i=i + 1;
|
||||
i = i + 1;
|
||||
if i > max_i {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
for j in range(0u,self.pattern.len()) {
|
||||
for j in 0..self.pattern.len() {
|
||||
if (data[i] & self.mask[j]) != (self.pattern[j] & self.mask[j]) {
|
||||
return None;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ impl Mp4Matcher {
|
|||
return false;
|
||||
}
|
||||
let box_size = ((data[0] as u32) << 3 | (data[1] as u32) << 2 |
|
||||
(data[2] as u32) << 1 | (data[3] as u32)) as uint;
|
||||
(data[2] as u32) << 1 | (data[3] as u32)) as usize;
|
||||
if (data.len() < box_size) || (box_size % 4 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -239,14 +239,14 @@ impl Mp4Matcher {
|
|||
let ftyp = [0x66, 0x74, 0x79, 0x70];
|
||||
let mp4 = [0x6D, 0x70, 0x34];
|
||||
|
||||
for i in range(4u,8u) {
|
||||
for i in 4..8 {
|
||||
if data[i] != ftyp[i - 4] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
let mut all_match = true;
|
||||
for i in range(8u,11u) {
|
||||
if data[i]!=mp4[i - 8u] {
|
||||
for i in 8..11 {
|
||||
if data[i]!=mp4[i - 8] {
|
||||
all_match = false;
|
||||
break;
|
||||
}
|
||||
|
@ -255,11 +255,11 @@ impl Mp4Matcher {
|
|||
return true;
|
||||
}
|
||||
|
||||
let mut bytes_read = 16u;
|
||||
let mut bytes_read: usize = 16;
|
||||
|
||||
while bytes_read < box_size {
|
||||
all_match = true;
|
||||
for i in range(0u,3u) {
|
||||
for i in 0..3 {
|
||||
if mp4[i] != data[i + bytes_read] {
|
||||
all_match = false;
|
||||
break;
|
||||
|
|
|
@ -5427,6 +5427,12 @@ impl ${name}Cast {
|
|||
unsafe { derived.transmute_borrowed() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn from_layout_js<T: ${fromBound}+Reflectable>(derived: &LayoutJS<T>) -> LayoutJS<${name}> {
|
||||
unsafe { derived.transmute_copy() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<${name}> {
|
||||
unsafe { derived.transmute() }
|
||||
|
|
|
@ -71,10 +71,9 @@ pub type Fallible<T> = Result<T, Error>;
|
|||
/// return `()`.
|
||||
pub type ErrorResult = Fallible<()>;
|
||||
|
||||
/// Set a pending DOM exception for the given `result` on `cx`.
|
||||
/// Set a pending exception for the given `result` on `cx`.
|
||||
pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
||||
result: Error) {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
let code = match result {
|
||||
Error::IndexSize => DOMErrorName::IndexSizeError,
|
||||
Error::NotFound => DOMErrorName::NotFoundError,
|
||||
|
@ -93,11 +92,17 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
|
|||
Error::DataClone => DOMErrorName::DataCloneError,
|
||||
Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError,
|
||||
Error::Type(message) => {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
throw_type_error(cx, &message);
|
||||
return;
|
||||
}
|
||||
Error::JSFailed => panic!(),
|
||||
Error::JSFailed => {
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 1);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||
let exception = DOMException::new(global, code).root();
|
||||
let thrown = exception.to_jsval(cx);
|
||||
unsafe {
|
||||
|
|
|
@ -7,14 +7,17 @@
|
|||
use dom::bindings::codegen::PrototypeList;
|
||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||
use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class};
|
||||
use dom::bindings::error::throw_type_error;
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{Temporary, Root};
|
||||
use dom::browsercontext;
|
||||
use dom::window;
|
||||
use util::namespace;
|
||||
use util::str::DOMString;
|
||||
|
||||
use libc;
|
||||
use libc::c_uint;
|
||||
use std::borrow::ToOwned;
|
||||
use std::boxed;
|
||||
use std::cell::Cell;
|
||||
use std::ffi::CString;
|
||||
|
@ -43,6 +46,7 @@ use js::rust::with_compartment;
|
|||
use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
|
||||
use js::JSFUN_CONSTRUCTOR;
|
||||
use js;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
/// Proxy handler for a WindowProxy.
|
||||
pub struct WindowProxyHandler(pub *const libc::c_void);
|
||||
|
@ -604,6 +608,68 @@ pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details.
|
||||
pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult {
|
||||
match xml_name_type(qualified_name) {
|
||||
XMLName::InvalidXMLName => {
|
||||
// Step 1.
|
||||
return Err(Error::InvalidCharacter);
|
||||
},
|
||||
XMLName::Name => {
|
||||
// Step 2.
|
||||
return Err(Error::Namespace);
|
||||
},
|
||||
XMLName::QName => Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate a namespace and qualified name and extract their parts.
|
||||
/// See https://dom.spec.whatwg.org/#validate-and-extract for details.
|
||||
pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str)
|
||||
-> Fallible<(Namespace, Option<DOMString>, Atom)> {
|
||||
// Step 1.
|
||||
let namespace = namespace::from_domstring(namespace);
|
||||
|
||||
// Step 2.
|
||||
try!(validate_qualified_name(qualified_name));
|
||||
|
||||
let (prefix, local_name) = if qualified_name.contains(":") {
|
||||
// Step 5.
|
||||
let mut parts = qualified_name.splitn(1, ':');
|
||||
let prefix = parts.next().unwrap();
|
||||
debug_assert!(!prefix.is_empty());
|
||||
let local_name = parts.next().unwrap();
|
||||
debug_assert!(!local_name.contains(":"));
|
||||
(Some(prefix), local_name)
|
||||
} else {
|
||||
(None, qualified_name)
|
||||
};
|
||||
|
||||
match (namespace, prefix) {
|
||||
(ns!(""), Some(_)) => {
|
||||
// Step 6.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, Some("xml")) if ns != &ns!(XML) => {
|
||||
// Step 7.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ref ns, p) if ns != &ns!(XMLNS) &&
|
||||
(qualified_name == "xmlns" || p == Some("xmlns")) => {
|
||||
// Step 8.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns!(XMLNS), p) if qualified_name != "xmlns" && p != Some("xmlns") => {
|
||||
// Step 9.
|
||||
Err(Error::Namespace)
|
||||
},
|
||||
(ns, p) => {
|
||||
// Step 10.
|
||||
Ok((ns, p.map(|s| s.to_owned()), Atom::from_slice(local_name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Results of `xml_name_type`.
|
||||
#[derive(PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
|
|
|
@ -53,6 +53,7 @@ pub struct CanvasRenderingContext2D {
|
|||
image_smoothing_enabled: Cell<bool>,
|
||||
stroke_color: Cell<RGBA>,
|
||||
line_width: Cell<f64>,
|
||||
miter_limit: Cell<f64>,
|
||||
fill_color: Cell<RGBA>,
|
||||
transform: Cell<Matrix2D<f32>>,
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ impl CanvasRenderingContext2D {
|
|||
image_smoothing_enabled: Cell::new(true),
|
||||
stroke_color: Cell::new(black),
|
||||
line_width: Cell::new(1.0),
|
||||
miter_limit: Cell::new(10.0),
|
||||
fill_color: Cell::new(black),
|
||||
transform: Cell::new(Matrix2D::identity()),
|
||||
}
|
||||
|
@ -258,6 +260,18 @@ impl CanvasRenderingContext2D {
|
|||
_ => panic!("Image Cache: Unknown Result")
|
||||
}
|
||||
}
|
||||
|
||||
fn create_drawable_rect(&self, x: f64, y: f64, w: f64, h: f64) -> Option<Rect<f32>> {
|
||||
if !([x, y, w, h].iter().all(|val| val.is_finite())) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if w == 0.0 && h == 0.0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Rect(Point2D(x as f32, y as f32), Size2D(w as f32, h as f32)))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CanvasRenderingContext2DHelpers {
|
||||
|
@ -358,34 +372,22 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
}
|
||||
|
||||
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::FillRect(rect)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::ClearRect(rect)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
|
||||
if !(x.is_finite() && y.is_finite() &&
|
||||
width.is_finite() && height.is_finite()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rect = Rect(Point2D(x as f32, y as f32), Size2D(width as f32, height as f32));
|
||||
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
|
||||
self.renderer.send(CanvasMsg::StrokeRect(rect)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn BeginPath(self) {
|
||||
self.renderer.send(CanvasMsg::BeginPath).unwrap();
|
||||
|
@ -816,6 +818,19 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
|
|||
self.line_width.set(width);
|
||||
self.renderer.send(CanvasMsg::SetLineWidth(width as f32)).unwrap()
|
||||
}
|
||||
|
||||
fn MiterLimit(self) -> f64 {
|
||||
self.miter_limit.get()
|
||||
}
|
||||
|
||||
fn SetMiterLimit(self, limit: f64) {
|
||||
if !limit.is_finite() || limit <= 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
self.miter_limit.set(limit);
|
||||
self.renderer.send(CanvasMsg::SetMiterLimit(limit as f32)).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, ElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::error::{Fallible, ErrorResult};
|
||||
use dom::bindings::error::Error::IndexSize;
|
||||
use dom::bindings::js::JSRef;
|
||||
use dom::bindings::js::{JSRef, LayoutJS, Temporary};
|
||||
use dom::document::Document;
|
||||
use dom::element::Element;
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||
use dom::node::{Node, NodeHelpers, NodeTypeId};
|
||||
|
||||
|
@ -18,6 +20,7 @@ use util::str::DOMString;
|
|||
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Ref;
|
||||
use std::cmp;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct CharacterData {
|
||||
|
@ -43,67 +46,59 @@ impl CharacterData {
|
|||
data: DOMRefCell::new(data),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn node<'a>(&'a self) -> &'a Node {
|
||||
&self.node
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> Ref<DOMString> {
|
||||
self.data.borrow()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_data(&self, data: DOMString) {
|
||||
*self.data.borrow_mut() = data;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
||||
self.data.borrow_for_layout().as_slice()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
fn Data(self) -> DOMString {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
data.clone()
|
||||
}
|
||||
|
||||
fn SetData(self, arg: DOMString) -> ErrorResult {
|
||||
*self.data.borrow_mut() = arg;
|
||||
Ok(())
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
fn SetData(self, data: DOMString) {
|
||||
*self.data.borrow_mut() = data;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-length
|
||||
fn Length(self) -> u32 {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
data.chars().count() as u32
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-substringdata
|
||||
fn SubstringData(self, offset: u32, count: u32) -> Fallible<DOMString> {
|
||||
// FIXME(https://github.com/rust-lang/rust/issues/23338)
|
||||
let data = self.data.borrow();
|
||||
Ok(data.slice_chars(offset as usize, (offset + count) as usize).to_owned())
|
||||
// Step 1.
|
||||
let len = data.chars().count();
|
||||
if len > offset as usize {
|
||||
// Step 2.
|
||||
return Err(IndexSize);
|
||||
}
|
||||
// Step 3.
|
||||
let end = cmp::min((offset + count) as usize, len);
|
||||
// Step 4.
|
||||
Ok(data.slice_chars(offset as usize, end).to_owned())
|
||||
}
|
||||
|
||||
fn AppendData(self, arg: DOMString) -> ErrorResult {
|
||||
self.data.borrow_mut().push_str(arg.as_slice());
|
||||
Ok(())
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-appenddata
|
||||
fn AppendData(self, data: DOMString) {
|
||||
self.data.borrow_mut().push_str(&data);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-insertdata
|
||||
fn InsertData(self, offset: u32, arg: DOMString) -> ErrorResult {
|
||||
self.ReplaceData(offset, 0, arg)
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-deletedata
|
||||
fn DeleteData(self, offset: u32, count: u32) -> ErrorResult {
|
||||
self.ReplaceData(offset, count, "".to_owned())
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-replacedata
|
||||
fn ReplaceData(self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
|
||||
let length = self.data.borrow().chars().count() as u32;
|
||||
if offset > length {
|
||||
|
@ -127,5 +122,40 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> {
|
|||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
node.remove_self();
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).preceding_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).following_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CharacterDataHelpers<'a> {
|
||||
fn data(self) -> Ref<'a, DOMString>;
|
||||
}
|
||||
|
||||
impl<'a> CharacterDataHelpers<'a> for JSRef<'a, CharacterData> {
|
||||
#[inline]
|
||||
fn data(self) -> Ref<'a, DOMString> {
|
||||
self.extended_deref().data.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub trait LayoutCharacterDataHelpers {
|
||||
unsafe fn data_for_layout<'a>(&'a self) -> &'a str;
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
impl LayoutCharacterDataHelpers for LayoutJS<CharacterData> {
|
||||
#[inline]
|
||||
unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
||||
&(*self.unsafe_get()).data.borrow_for_layout()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,5 @@ impl Comment {
|
|||
let document = global.as_window().Document().root();
|
||||
Ok(Comment::new(data, document.r()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,23 +18,24 @@ use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLAnchorElementCas
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLAppletElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLEmbedElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, CharacterDataCast};
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security};
|
||||
use dom::bindings::error::Error::{HierarchyRequest, Namespace};
|
||||
use dom::bindings::error::Error::HierarchyRequest;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
||||
use dom::bindings::refcounted::Trusted;
|
||||
use dom::bindings::utils::reflect_dom_object;
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||
use dom::characterdata::CharacterDataHelpers;
|
||||
use dom::comment::Comment;
|
||||
use dom::customevent::CustomEvent;
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::domimplementation::DOMImplementation;
|
||||
use dom::element::{Element, ElementCreator, AttributeHandlers, get_attribute_parts};
|
||||
use dom::element::{Element, ElementCreator, AttributeHandlers};
|
||||
use dom::element::{ElementTypeId, ActivationElementHelpers};
|
||||
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
|
||||
|
@ -67,7 +68,7 @@ use net_traits::CookieSource::NonHTTP;
|
|||
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||
use script_task::Runnable;
|
||||
use script_traits::{MouseButton, UntrustedNodeAddress};
|
||||
use util::{opts, namespace};
|
||||
use util::opts;
|
||||
use util::str::{DOMString, split_html_space_chars};
|
||||
use layout_interface::{ReflowGoal, ReflowQueryType};
|
||||
|
||||
|
@ -975,45 +976,10 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
fn CreateElementNS(self,
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: DOMString) -> Fallible<Temporary<Element>> {
|
||||
let ns = namespace::from_domstring(namespace);
|
||||
match xml_name_type(&qualified_name) {
|
||||
InvalidXMLName => {
|
||||
debug!("Not a valid element name");
|
||||
return Err(InvalidCharacter);
|
||||
},
|
||||
Name => {
|
||||
debug!("Not a valid qualified element name");
|
||||
return Err(Namespace);
|
||||
},
|
||||
QName => {}
|
||||
}
|
||||
|
||||
let (prefix_from_qname, local_name_from_qname) = get_attribute_parts(&qualified_name);
|
||||
match (&ns, prefix_from_qname, local_name_from_qname) {
|
||||
// throw if prefix is not null and namespace is null
|
||||
(&ns!(""), Some(_), _) => {
|
||||
debug!("Namespace can't be null with a non-null prefix");
|
||||
return Err(Namespace);
|
||||
},
|
||||
// throw if prefix is "xml" and namespace is not the XML namespace
|
||||
(_, Some(ref prefix), _) if "xml" == *prefix && ns != ns!(XML) => {
|
||||
debug!("Namespace must be the xml namespace if the prefix is 'xml'");
|
||||
return Err(Namespace);
|
||||
},
|
||||
// throw if namespace is the XMLNS namespace and neither qualifiedName nor prefix is
|
||||
// "xmlns"
|
||||
(&ns!(XMLNS), Some(ref prefix), _) if "xmlns" == *prefix => {},
|
||||
(&ns!(XMLNS), _, "xmlns") => {},
|
||||
(&ns!(XMLNS), _, _) => {
|
||||
debug!("The prefix or the qualified name must be 'xmlns' if namespace is the XMLNS namespace ");
|
||||
return Err(Namespace);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let name = QualName::new(ns, Atom::from_slice(local_name_from_qname));
|
||||
Ok(Element::create(name, prefix_from_qname.map(|s| s.to_owned()), self,
|
||||
ElementCreator::ScriptCreated))
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let name = QualName::new(namespace, local_name);
|
||||
Ok(Element::create(name, prefix, self, ElementCreator::ScriptCreated))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createattribute
|
||||
|
@ -1032,6 +998,18 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
Ok(Attr::new(window.r(), name, value, l_name, ns!(""), None, None))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createattributens
|
||||
fn CreateAttributeNS(self, namespace: Option<DOMString>, qualified_name: DOMString)
|
||||
-> Fallible<Temporary<Attr>> {
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let window = self.window.root();
|
||||
let value = AttrValue::String("".to_owned());
|
||||
let qualified_name = Atom::from_slice(&qualified_name);
|
||||
Ok(Attr::new(window.r(), local_name, value, qualified_name,
|
||||
namespace, prefix, None))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-document-createdocumentfragment
|
||||
fn CreateDocumentFragment(self) -> Temporary<DocumentFragment> {
|
||||
DocumentFragment::new(self)
|
||||
|
@ -1148,7 +1126,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
for child in title_element.children() {
|
||||
let child = child.root();
|
||||
if let Some(text) = TextCast::to_ref(child.r()) {
|
||||
title.push_str(&text.characterdata().data());
|
||||
title.push_str(&CharacterDataCast::from_ref(text).data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,10 @@ use dom::bindings::codegen::Bindings::DOMImplementationBinding::DOMImplementatio
|
|||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::error::Error::{InvalidCharacter, Namespace};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, JSRef, Root, Temporary, OptionalRootable};
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::validate_qualified_name;
|
||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument};
|
||||
use dom::document::DocumentSource;
|
||||
use dom::documenttype::DocumentType;
|
||||
|
@ -52,18 +50,11 @@ impl DOMImplementation {
|
|||
// http://dom.spec.whatwg.org/#domimplementation
|
||||
impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> {
|
||||
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
||||
fn CreateDocumentType(self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Temporary<DocumentType>> {
|
||||
match xml_name_type(&qname) {
|
||||
// Step 1.
|
||||
InvalidXMLName => Err(InvalidCharacter),
|
||||
// Step 2.
|
||||
Name => Err(Namespace),
|
||||
// Step 3.
|
||||
QName => {
|
||||
fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString)
|
||||
-> Fallible<Temporary<DocumentType>> {
|
||||
try!(validate_qualified_name(&qualified_name));
|
||||
let document = self.document.root();
|
||||
Ok(DocumentType::new(qname, Some(pubid), Some(sysid), document.r()))
|
||||
}
|
||||
}
|
||||
Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r()))
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocument
|
||||
|
|
|
@ -24,14 +24,13 @@ use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextA
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast;
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::Error;
|
||||
use dom::bindings::error::Error::{InvalidCharacter, Syntax};
|
||||
use dom::bindings::error::Error::NoModificationAllowed;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
use dom::bindings::utils::{xml_name_type, validate_and_extract};
|
||||
use dom::bindings::utils::XMLName::InvalidXMLName;
|
||||
use dom::create::create_element;
|
||||
use dom::domrect::DOMRect;
|
||||
use dom::domrectlist::DOMRectList;
|
||||
|
@ -1037,58 +1036,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-element-setattributens
|
||||
fn SetAttributeNS(self,
|
||||
namespace_url: Option<DOMString>,
|
||||
name: DOMString,
|
||||
namespace: Option<DOMString>,
|
||||
qualified_name: DOMString,
|
||||
value: DOMString) -> ErrorResult {
|
||||
// Step 1.
|
||||
let namespace = namespace::from_domstring(namespace_url);
|
||||
|
||||
let name_type = xml_name_type(&name);
|
||||
match name_type {
|
||||
// Step 2.
|
||||
InvalidXMLName => return Err(InvalidCharacter),
|
||||
// Step 3.
|
||||
Name => return Err(Error::Namespace),
|
||||
QName => {}
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
let (prefix, local_name) = get_attribute_parts(&name);
|
||||
|
||||
if let Some(ref prefix_str) = prefix {
|
||||
// Step 5.
|
||||
if namespace == ns!("") {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
if "xml" == *prefix_str && namespace != ns!(XML) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 7b.
|
||||
if "xmlns" == *prefix_str && namespace != ns!(XMLNS) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
let name = Atom::from_slice(&name);
|
||||
let local_name = Atom::from_slice(local_name);
|
||||
let xmlns = atom!("xmlns");
|
||||
|
||||
// Step 7a.
|
||||
if xmlns == name && namespace != ns!(XMLNS) {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 8.
|
||||
if namespace == ns!(XMLNS) && xmlns != name && Some("xmlns") != prefix {
|
||||
return Err(Error::Namespace);
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
let (namespace, prefix, local_name) =
|
||||
try!(validate_and_extract(namespace, &qualified_name));
|
||||
let qualified_name = Atom::from_slice(&qualified_name);
|
||||
let value = self.parse_attribute(&namespace, &local_name, value);
|
||||
self.do_set_attribute(local_name.clone(), value, name,
|
||||
self.do_set_attribute(local_name.clone(), value, qualified_name,
|
||||
namespace.clone(), prefix.map(|s| s.to_owned()),
|
||||
|attr| {
|
||||
*attr.local_name() == local_name &&
|
||||
|
@ -1223,6 +1178,18 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
|
||||
fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).preceding_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
|
||||
fn GetNextElementSibling(self) -> Option<Temporary<Element>> {
|
||||
NodeCast::from_ref(self).following_siblings()
|
||||
.filter_map(ElementCast::to_temporary).next()
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-children
|
||||
fn Children(self) -> Temporary<HTMLCollection> {
|
||||
let window = window_from_node(self).root();
|
||||
|
@ -1293,17 +1260,6 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) {
|
||||
//FIXME: Throw for XML-invalid names
|
||||
//FIXME: Throw for XMLNS-invalid names
|
||||
if name.contains(":") {
|
||||
let mut parts = name.splitn(1, ':');
|
||||
(Some(parts.next().unwrap()), parts.next().unwrap())
|
||||
} else {
|
||||
(None, name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||
fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
|
||||
let node: &JSRef<Node> = NodeCast::from_borrowed_ref(self);
|
||||
|
|
|
@ -524,8 +524,7 @@ impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> {
|
|||
|
||||
// http://www.whatwg.org/html/#dom-script-text
|
||||
fn Text(self) -> DOMString {
|
||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
Node::collect_text_contents(node.children().map(|c| c.root()).map(|c| c.get_unsound_ref_forever()))
|
||||
Node::collect_text_contents(NodeCast::from_ref(self).children())
|
||||
}
|
||||
|
||||
// http://www.whatwg.org/html/#dom-script-text
|
||||
|
|
|
@ -6,8 +6,9 @@ use dom::bindings::codegen::Bindings::HTMLTitleElementBinding;
|
|||
use dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementMethods;
|
||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTitleElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{TextCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, TextCast};
|
||||
use dom::bindings::js::{JSRef, Temporary};
|
||||
use dom::characterdata::CharacterDataHelpers;
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId};
|
||||
use dom::element::ElementTypeId;
|
||||
|
@ -51,7 +52,7 @@ impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> {
|
|||
let child = child.root();
|
||||
let text: Option<JSRef<Text>> = TextCast::to_ref(child.r());
|
||||
match text {
|
||||
Some(text) => content.push_str(text.characterdata().data().as_slice()),
|
||||
Some(text) => content.push_str(&CharacterDataCast::from_ref(text).data()),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,6 +315,7 @@ pub mod servohtmlparser;
|
|||
pub mod storage;
|
||||
pub mod storageevent;
|
||||
pub mod text;
|
||||
pub mod textdecoder;
|
||||
pub mod textencoder;
|
||||
pub mod treewalker;
|
||||
pub mod uievent;
|
||||
|
|
|
@ -13,12 +13,11 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods;
|
|||
use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
|
||||
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
|
||||
use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTypeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast, ElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentCast, DocumentTypeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast, ElementDerived, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLFieldSetElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived;
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, NodeBase, NodeDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast};
|
||||
use dom::bindings::conversions;
|
||||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax};
|
||||
|
@ -29,7 +28,7 @@ use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS};
|
|||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::bindings::utils::{Reflectable, reflect_dom_object};
|
||||
use dom::characterdata::CharacterData;
|
||||
use dom::characterdata::{CharacterData, CharacterDataHelpers};
|
||||
use dom::comment::Comment;
|
||||
use dom::document::{Document, DocumentHelpers, IsHTMLDocument, DocumentSource};
|
||||
use dom::documentfragment::DocumentFragment;
|
||||
|
@ -415,6 +414,7 @@ pub trait NodeHelpers<'a> {
|
|||
fn rev_children(self) -> ReverseChildrenIterator;
|
||||
fn child_elements(self) -> ChildElementIterator;
|
||||
fn following_siblings(self) -> NodeSiblingIterator;
|
||||
fn preceding_siblings(self) -> ReverseChildrenIterator;
|
||||
fn is_in_doc(self) -> bool;
|
||||
fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool;
|
||||
fn is_parent_of(self, child: JSRef<Node>) -> bool;
|
||||
|
@ -764,6 +764,12 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
|||
}
|
||||
}
|
||||
|
||||
fn preceding_siblings(self) -> ReverseChildrenIterator {
|
||||
ReverseChildrenIterator {
|
||||
current: self.prev_sibling(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_parent_of(self, child: JSRef<Node>) -> bool {
|
||||
match child.parent_node() {
|
||||
Some(ref parent) if parent == &Temporary::from_rooted(self) => true,
|
||||
|
@ -1594,8 +1600,8 @@ impl Node {
|
|||
NodeCast::from_temporary(doc_fragment)
|
||||
},
|
||||
NodeTypeId::Comment => {
|
||||
let comment: JSRef<Comment> = CommentCast::to_ref(node).unwrap();
|
||||
let comment = Comment::new(comment.characterdata().data().clone(), document.r());
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
let comment = Comment::new(cdata.Data(), document.r());
|
||||
NodeCast::from_temporary(comment)
|
||||
},
|
||||
NodeTypeId::Document => {
|
||||
|
@ -1622,14 +1628,14 @@ impl Node {
|
|||
NodeCast::from_temporary(element)
|
||||
},
|
||||
NodeTypeId::Text => {
|
||||
let text: JSRef<Text> = TextCast::to_ref(node).unwrap();
|
||||
let text = Text::new(text.characterdata().data().clone(), document.r());
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
let text = Text::new(cdata.Data(), document.r());
|
||||
NodeCast::from_temporary(text)
|
||||
},
|
||||
NodeTypeId::ProcessingInstruction => {
|
||||
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
let pi = ProcessingInstruction::new(pi.target().clone(),
|
||||
pi.characterdata().data().clone(), document.r());
|
||||
CharacterDataCast::from_ref(pi).Data(), document.r());
|
||||
NodeCast::from_temporary(pi)
|
||||
},
|
||||
}.root();
|
||||
|
@ -1683,12 +1689,13 @@ impl Node {
|
|||
Temporary::from_rooted(copy.r())
|
||||
}
|
||||
|
||||
pub fn collect_text_contents<'a, T: Iterator<Item=JSRef<'a, Node>>>(iterator: T) -> String {
|
||||
pub fn collect_text_contents<T: Iterator<Item=Temporary<Node>>>(iterator: T) -> String {
|
||||
let mut content = String::new();
|
||||
for node in iterator {
|
||||
let text: Option<JSRef<Text>> = TextCast::to_ref(node);
|
||||
let node = node.root();
|
||||
let text = TextCast::to_ref(node.r());
|
||||
match text {
|
||||
Some(text) => content.push_str(text.characterdata().data().as_slice()),
|
||||
Some(text) => content.push_str(&CharacterDataCast::from_ref(text).Data()),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
@ -1834,7 +1841,8 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
match self.type_id {
|
||||
NodeTypeId::DocumentFragment |
|
||||
NodeTypeId::Element(..) => {
|
||||
let content = Node::collect_text_contents(self.traverse_preorder());
|
||||
let content = Node::collect_text_contents(
|
||||
self.traverse_preorder().map(Temporary::from_rooted));
|
||||
Some(content)
|
||||
}
|
||||
NodeTypeId::Comment |
|
||||
|
@ -1871,7 +1879,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
NodeTypeId::Text |
|
||||
NodeTypeId::ProcessingInstruction => {
|
||||
let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap();
|
||||
characterdata.set_data(value);
|
||||
characterdata.SetData(value);
|
||||
|
||||
// Notify the document that the content of this node is different
|
||||
let document = self.owner_doc().root();
|
||||
|
@ -2114,7 +2122,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
let other_pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(other).unwrap();
|
||||
(*pi.target() == *other_pi.target()) &&
|
||||
(*pi.characterdata().data() == *other_pi.characterdata().data())
|
||||
(*CharacterDataCast::from_ref(pi).data() == *CharacterDataCast::from_ref(other_pi).data())
|
||||
}
|
||||
fn is_equal_characterdata(node: JSRef<Node>, other: JSRef<Node>) -> bool {
|
||||
let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(node).unwrap();
|
||||
|
|
|
@ -38,10 +38,6 @@ impl ProcessingInstruction {
|
|||
document, ProcessingInstructionBinding::Wrap)
|
||||
}
|
||||
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
|
||||
pub fn target<'a>(&'a self) -> &'a DOMString {
|
||||
&self.target
|
||||
}
|
||||
|
|
|
@ -42,10 +42,5 @@ impl Text {
|
|||
let document = global.as_window().Document().root();
|
||||
Ok(Text::new(text, document.r()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn characterdata<'a>(&'a self) -> &'a CharacterData {
|
||||
&self.characterdata
|
||||
}
|
||||
}
|
||||
|
||||
|
|
99
components/script/dom/textdecoder.rs
Normal file
99
components/script/dom/textdecoder.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* 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 dom::bindings::codegen::Bindings::TextDecoderBinding;
|
||||
use dom::bindings::codegen::Bindings::TextDecoderBinding::TextDecoderMethods;
|
||||
use dom::bindings::error::{Error, Fallible};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JSRef, Temporary};
|
||||
use dom::bindings::str::USVString;
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
|
||||
use util::str::DOMString;
|
||||
|
||||
use encoding::Encoding;
|
||||
use encoding::types::{EncodingRef, DecoderTrap};
|
||||
use encoding::label::encoding_from_whatwg_label;
|
||||
use js::jsapi::{JSContext, JSObject};
|
||||
use js::jsfriendapi::bindgen::JS_GetObjectAsArrayBufferView;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct TextDecoder {
|
||||
reflector_: Reflector,
|
||||
encoding: EncodingRef,
|
||||
fatal: bool,
|
||||
}
|
||||
|
||||
impl TextDecoder {
|
||||
fn new_inherited(encoding: EncodingRef, fatal: bool) -> TextDecoder {
|
||||
TextDecoder {
|
||||
reflector_: Reflector::new(),
|
||||
encoding: encoding,
|
||||
fatal: fatal,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(global: GlobalRef, encoding: EncodingRef, fatal: bool) -> Temporary<TextDecoder> {
|
||||
reflect_dom_object(box TextDecoder::new_inherited(encoding, fatal),
|
||||
global,
|
||||
TextDecoderBinding::Wrap)
|
||||
}
|
||||
|
||||
/// https://encoding.spec.whatwg.org/#dom-textdecoder
|
||||
pub fn Constructor(global: GlobalRef,
|
||||
label: DOMString,
|
||||
options: &TextDecoderBinding::TextDecoderOptions)
|
||||
-> Fallible<Temporary<TextDecoder>> {
|
||||
let encoding = match encoding_from_whatwg_label(&label) {
|
||||
Some(enc) => enc,
|
||||
// FIXME: Should throw a RangeError as per spec
|
||||
None => return Err(Error::Syntax),
|
||||
};
|
||||
Ok(TextDecoder::new(global, encoding, options.fatal))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> {
|
||||
fn Encoding(self) -> DOMString {
|
||||
self.encoding.whatwg_name().unwrap().to_owned()
|
||||
}
|
||||
|
||||
fn Fatal(self) -> bool {
|
||||
self.fatal
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn Decode(self, cx: *mut JSContext, input: Option<*mut JSObject>)
|
||||
-> Fallible<USVString> {
|
||||
let input = match input {
|
||||
Some(input) => input,
|
||||
None => return Ok(USVString("".to_owned())),
|
||||
};
|
||||
|
||||
let mut length = 0;
|
||||
let mut data = ptr::null_mut();
|
||||
if unsafe { JS_GetObjectAsArrayBufferView(cx, input, &mut length, &mut data).is_null() } {
|
||||
return Err(Error::Type("Argument to TextDecoder.decode is not an ArrayBufferView".to_owned()));
|
||||
}
|
||||
|
||||
let buffer = unsafe {
|
||||
slice::from_raw_parts(data as *const _, length as usize)
|
||||
};
|
||||
let trap = if self.fatal {
|
||||
DecoderTrap::Strict
|
||||
} else {
|
||||
DecoderTrap::Replace
|
||||
};
|
||||
match self.encoding.decode(buffer, trap) {
|
||||
Ok(s) => Ok(USVString(s)),
|
||||
Err(_) => Err(Error::Type("Decoding failed".to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -136,7 +136,7 @@ interface CanvasDrawingStyles {
|
|||
attribute unrestricted double lineWidth; // (default 1)
|
||||
//attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
|
||||
//attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
|
||||
//attribute unrestricted double miterLimit; // (default 10)
|
||||
attribute unrestricted double miterLimit; // (default 10)
|
||||
|
||||
// dashed lines
|
||||
//void setLineDash(sequence<unrestricted double> segments); // default empty
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
*/
|
||||
|
||||
interface CharacterData : Node {
|
||||
[TreatNullAs=EmptyString,SetterThrows] attribute DOMString data;
|
||||
[TreatNullAs=EmptyString] attribute DOMString data;
|
||||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
DOMString substringData(unsigned long offset, unsigned long count);
|
||||
[Throws]
|
||||
void appendData(DOMString data);
|
||||
[Throws]
|
||||
void insertData(unsigned long offset, DOMString data);
|
||||
|
@ -26,3 +25,4 @@ interface CharacterData : Node {
|
|||
};
|
||||
|
||||
CharacterData implements ChildNode;
|
||||
CharacterData implements NonDocumentTypeChildNode;
|
||||
|
|
|
@ -16,10 +16,10 @@ interface ChildNode {
|
|||
void remove();
|
||||
};
|
||||
|
||||
// [NoInterfaceObject]
|
||||
// interface NonDocumentTypeChildNode {
|
||||
// [Pure]
|
||||
// readonly attribute Element? previousElementSibling;
|
||||
// [Pure]
|
||||
// readonly attribute Element? nextElementSibling;
|
||||
// };
|
||||
[NoInterfaceObject]
|
||||
interface NonDocumentTypeChildNode {
|
||||
[Pure]
|
||||
readonly attribute Element? previousElementSibling;
|
||||
[Pure]
|
||||
readonly attribute Element? nextElementSibling;
|
||||
};
|
||||
|
|
|
@ -27,27 +27,33 @@ interface Document : Node {
|
|||
HTMLCollection getElementsByClassName(DOMString classNames);
|
||||
Element? getElementById(DOMString elementId);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Element createElement(DOMString localName);
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Element createElementNS(DOMString? namespace, DOMString qualifiedName);
|
||||
[NewObject]
|
||||
DocumentFragment createDocumentFragment();
|
||||
[NewObject]
|
||||
Text createTextNode(DOMString data);
|
||||
[NewObject]
|
||||
Comment createComment(DOMString data);
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
|
||||
|
||||
[Throws]
|
||||
Attr createAttribute(DOMString localName);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Node importNode(Node node, optional boolean deep = false);
|
||||
[Throws]
|
||||
Node adoptNode(Node node);
|
||||
|
||||
[Throws]
|
||||
[NewObject, Throws]
|
||||
Attr createAttribute(DOMString localName);
|
||||
[NewObject, Throws]
|
||||
Attr createAttributeNS(DOMString? namespace, DOMString localName);
|
||||
|
||||
[NewObject, Throws]
|
||||
Event createEvent(DOMString interface_);
|
||||
|
||||
[NewObject]
|
||||
Range createRange();
|
||||
|
||||
// NodeFilter.SHOW_ALL = 0xFFFFFFFF
|
||||
|
|
|
@ -70,4 +70,5 @@ partial interface Element {
|
|||
};
|
||||
|
||||
Element implements ChildNode;
|
||||
Element implements NonDocumentTypeChildNode;
|
||||
Element implements ParentNode;
|
||||
|
|
21
components/script/dom/webidls/TextDecoder.webidl
Normal file
21
components/script/dom/webidls/TextDecoder.webidl
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
// https://encoding.spec.whatwg.org/#interface-textdecoder
|
||||
dictionary TextDecoderOptions {
|
||||
boolean fatal = false;
|
||||
//boolean ignoreBOM = false;
|
||||
};
|
||||
|
||||
[Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options)/*,
|
||||
Exposed=Window,Worker*/]
|
||||
interface TextDecoder {
|
||||
readonly attribute DOMString encoding;
|
||||
readonly attribute boolean fatal;
|
||||
//readonly attribute boolean ignoreBOM;
|
||||
//USVString decode(optional BufferSource input, optional TextDecodeOptions options);
|
||||
[Throws]
|
||||
USVString decode(optional object input);
|
||||
};
|
|
@ -7,13 +7,14 @@
|
|||
use dom::attr::AttrHelpers;
|
||||
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLScriptElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, TextCast, CommentCast};
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentTypeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLScriptElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast;
|
||||
use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
|
||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Root};
|
||||
use dom::bindings::js::RootedReference;
|
||||
use dom::bindings::trace::RootedVec;
|
||||
use dom::characterdata::CharacterDataHelpers;
|
||||
use dom::comment::Comment;
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::document::{DocumentSource, IsHTMLDocument};
|
||||
|
@ -234,22 +235,19 @@ impl<'a> Serializable for JSRef<'a, Node> {
|
|||
},
|
||||
|
||||
(IncludeNode, NodeTypeId::Text) => {
|
||||
let text: JSRef<Text> = TextCast::to_ref(node).unwrap();
|
||||
let data = text.characterdata().data();
|
||||
serializer.write_text(data.as_slice())
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
serializer.write_text(&cdata.data())
|
||||
},
|
||||
|
||||
(IncludeNode, NodeTypeId::Comment) => {
|
||||
let comment: JSRef<Comment> = CommentCast::to_ref(node).unwrap();
|
||||
let data = comment.characterdata().data();
|
||||
serializer.write_comment(data.as_slice())
|
||||
let cdata = CharacterDataCast::to_ref(node).unwrap();
|
||||
serializer.write_comment(&cdata.data())
|
||||
},
|
||||
|
||||
(IncludeNode, NodeTypeId::ProcessingInstruction) => {
|
||||
let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
|
||||
let data = pi.characterdata().data();
|
||||
serializer.write_processing_instruction(pi.target().as_slice(),
|
||||
data.as_slice())
|
||||
let data = CharacterDataCast::from_ref(pi).data();
|
||||
serializer.write_processing_instruction(&pi.target(), &data)
|
||||
},
|
||||
|
||||
(IncludeNode, NodeTypeId::DocumentFragment) => Ok(()),
|
||||
|
|
4
components/servo/Cargo.lock
generated
4
components/servo/Cargo.lock
generated
|
@ -479,7 +479,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "js"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-mozjs#879b256e6bc5b38f792b68da130eb7a70633769b"
|
||||
source = "git+https://github.com/servo/rust-mozjs#9512c3c770774ed73a2fdcc635eee178cbd02ab1"
|
||||
dependencies = [
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)",
|
||||
|
@ -617,7 +617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "mozjs_sys"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/servo/mozjs#40e0680008cb129ddf9ccf40c6b0095e14d1cd97"
|
||||
source = "git+https://github.com/servo/mozjs#19edb950930f03f0ad305ffbd9548b92fdb0a250"
|
||||
|
||||
[[package]]
|
||||
name = "msg"
|
||||
|
|
|
@ -39,7 +39,12 @@ pub fn null_str_as_empty_ref<'a>(s: &'a Option<DOMString>) -> &'a str {
|
|||
const WHITESPACE: &'static [char] = &[' ', '\t', '\x0a', '\x0c', '\x0d'];
|
||||
|
||||
pub fn is_whitespace(s: &str) -> bool {
|
||||
s.chars().all(|c| WHITESPACE.contains(&c))
|
||||
s.chars().all(char_is_whitespace)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn char_is_whitespace(c: char) -> bool {
|
||||
WHITESPACE.contains(&c)
|
||||
}
|
||||
|
||||
/// A "space character" according to:
|
||||
|
|
4
ports/cef/Cargo.lock
generated
4
ports/cef/Cargo.lock
generated
|
@ -482,7 +482,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "js"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-mozjs#879b256e6bc5b38f792b68da130eb7a70633769b"
|
||||
source = "git+https://github.com/servo/rust-mozjs#9512c3c770774ed73a2fdcc635eee178cbd02ab1"
|
||||
dependencies = [
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)",
|
||||
|
@ -620,7 +620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "mozjs_sys"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/servo/mozjs#40e0680008cb129ddf9ccf40c6b0095e14d1cd97"
|
||||
source = "git+https://github.com/servo/mozjs#19edb950930f03f0ad305ffbd9548b92fdb0a250"
|
||||
|
||||
[[package]]
|
||||
name = "msg"
|
||||
|
|
|
@ -32,9 +32,11 @@ use types::{cef_window_info_t, cef_xml_encoding_type_t, cef_xml_node_type_t};
|
|||
use unicode::str::Utf16Encoder;
|
||||
|
||||
use libc::{self, c_char, c_int, c_ushort, c_void};
|
||||
use std::boxed;
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::raw;
|
||||
|
||||
pub trait CefWrap<CObject> {
|
||||
fn to_c(rust_object: Self) -> CObject;
|
||||
|
@ -61,7 +63,7 @@ macro_rules! cef_pointer_wrapper(
|
|||
rust_object
|
||||
}
|
||||
unsafe fn to_rust(c_object: *const $ty) -> &'a $ty {
|
||||
mem::transmute::<*const $ty,&'a $ty>(c_object)
|
||||
&*c_object
|
||||
}
|
||||
}
|
||||
impl<'a> CefWrap<*mut $ty> for &'a mut $ty {
|
||||
|
@ -69,7 +71,7 @@ macro_rules! cef_pointer_wrapper(
|
|||
rust_object
|
||||
}
|
||||
unsafe fn to_rust(c_object: *mut $ty) -> &'a mut $ty {
|
||||
mem::transmute::<*mut $ty,&'a mut $ty>(c_object)
|
||||
&mut *c_object
|
||||
}
|
||||
}
|
||||
cef_noop_wrapper!(*const $ty);
|
||||
|
@ -187,19 +189,18 @@ impl<'a> CefWrap<*const cef_string_t> for &'a [u16] {
|
|||
|
||||
// FIXME(pcwalton): This leaks!! We should instead have the caller pass some scratch
|
||||
// stack space to create the object in. What a botch.
|
||||
let boxed_string = box cef_string_utf16 {
|
||||
boxed::into_raw(box cef_string_utf16 {
|
||||
str: ptr,
|
||||
length: buffer.len() as u64,
|
||||
dtor: Some(free_boxed_utf16_string as extern "C" fn(*mut c_ushort)),
|
||||
};
|
||||
let result: *const cef_string_utf16 = &*boxed_string;
|
||||
mem::forget(boxed_string);
|
||||
result
|
||||
}) as *const _
|
||||
}
|
||||
}
|
||||
unsafe fn to_rust(cef_string: *const cef_string_t) -> &'a [u16] {
|
||||
let (ptr, len): (*mut c_ushort, uint) = ((*cef_string).str, (*cef_string).length as uint);
|
||||
mem::transmute((ptr, len))
|
||||
mem::transmute(raw::Slice {
|
||||
data: (*cef_string).str,
|
||||
len: (*cef_string).length as usize,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,8 +215,7 @@ impl<'a> CefWrap<*mut cef_string_t> for &'a mut [u16] {
|
|||
panic!("unimplemented CEF type conversion: &'a str")
|
||||
}
|
||||
unsafe fn to_rust(_: *mut cef_string_t) -> &'a mut [u16] {
|
||||
mem::transmute::<(int,int),_>(panic!("unimplemented CEF type conversion: *mut \
|
||||
cef_string_t"))
|
||||
panic!("unimplemented CEF type conversion: *mut cef_string_t")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,19 +245,18 @@ impl<'a> CefWrap<cef_string_userfree_t> for String {
|
|||
|
||||
let boxed_string;
|
||||
unsafe {
|
||||
let buffer = libc::malloc((mem::size_of::<c_ushort>() as u64) *
|
||||
((utf16_chars.len() + 1) as u64 + 1)) as *mut u16;
|
||||
let buffer = libc::malloc((mem::size_of::<c_ushort>() as libc::size_t) *
|
||||
((utf16_chars.len() + 1) as libc::size_t)) as *mut u16;
|
||||
for (i, ch) in utf16_chars.iter().enumerate() {
|
||||
*buffer.offset(i as int) = *ch
|
||||
}
|
||||
*buffer.offset(utf16_chars.len() as int) = 0;
|
||||
|
||||
boxed_string = libc::malloc(mem::size_of::<cef_string_utf16>() as u64) as
|
||||
boxed_string = libc::malloc(mem::size_of::<cef_string_utf16>() as libc::size_t) as
|
||||
*mut cef_string_utf16;
|
||||
ptr::write(&mut (*boxed_string).str, buffer);
|
||||
ptr::write(&mut (*boxed_string).length, utf16_chars.len() as u64);
|
||||
ptr::write(&mut (*boxed_string).dtor, Some(free_utf16_buffer as extern "C" fn(*mut c_ushort)));
|
||||
mem::forget(utf16_chars);
|
||||
}
|
||||
boxed_string
|
||||
}
|
||||
|
|
4
ports/gonk/Cargo.lock
generated
4
ports/gonk/Cargo.lock
generated
|
@ -415,7 +415,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "js"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/rust-mozjs#879b256e6bc5b38f792b68da130eb7a70633769b"
|
||||
source = "git+https://github.com/servo/rust-mozjs#9512c3c770774ed73a2fdcc635eee178cbd02ab1"
|
||||
dependencies = [
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mozjs_sys 0.0.0 (git+https://github.com/servo/mozjs)",
|
||||
|
@ -545,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "mozjs_sys"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/servo/mozjs#40e0680008cb129ddf9ccf40c6b0095e14d1cd97"
|
||||
source = "git+https://github.com/servo/mozjs#19edb950930f03f0ad305ffbd9548b92fdb0a250"
|
||||
|
||||
[[package]]
|
||||
name = "msg"
|
||||
|
|
|
@ -114,6 +114,7 @@ flaky_cpu == append_style_a.html append_style_b.html
|
|||
== float_intrinsic_width_a.html float_intrinsic_width_ref.html
|
||||
== float_right_intrinsic_width_a.html float_right_intrinsic_width_ref.html
|
||||
== float_table_a.html float_table_ref.html
|
||||
== float_under_top_margin_a.html float_under_top_margin_ref.html
|
||||
== floated_generated_content_a.html floated_generated_content_b.html
|
||||
== floated_list_item_a.html floated_list_item_ref.html
|
||||
== floated_table_with_margin_a.html floated_table_with_margin_ref.html
|
||||
|
@ -151,6 +152,7 @@ flaky_cpu == append_style_a.html append_style_b.html
|
|||
!= img_simple.html img_simple_ref.html
|
||||
== img_size_a.html img_size_b.html
|
||||
== incremental_float_a.html incremental_float_ref.html
|
||||
== incremental_inline_layout_a.html incremental_inline_layout_ref.html
|
||||
!= inline_background_a.html inline_background_ref.html
|
||||
== inline_block_baseline_a.html inline_block_baseline_ref.html
|
||||
== inline_block_border_a.html inline_block_border_ref.html
|
||||
|
@ -184,6 +186,7 @@ flaky_cpu == append_style_a.html append_style_b.html
|
|||
== legacy_td_bgcolor_attribute_a.html legacy_td_bgcolor_attribute_ref.html
|
||||
== legacy_td_width_attribute_a.html legacy_td_width_attribute_ref.html
|
||||
== letter_spacing_a.html letter_spacing_ref.html
|
||||
== line_breaking_whitespace_collapse_a.html line_breaking_whitespace_collapse_ref.html
|
||||
== line_height_a.html line_height_ref.html
|
||||
!= linear_gradients_corners_a.html linear_gradients_corners_ref.html
|
||||
== linear_gradients_lengths_a.html linear_gradients_lengths_ref.html
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
<div class="otherprojects">
|
||||
<div class="otherprojects-item">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
29
tests/ref/float_under_top_margin_a.html
Normal file
29
tests/ref/float_under_top_margin_a.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin-top: 64px;
|
||||
}
|
||||
#foo, #bar {
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
}
|
||||
#foo {
|
||||
background: blue;
|
||||
float: right;
|
||||
}
|
||||
#bar {
|
||||
background: gold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=foo></div><div id=bar></div>
|
||||
</body>
|
||||
</html>
|
||||
|
29
tests/ref/float_under_top_margin_ref.html
Normal file
29
tests/ref/float_under_top_margin_ref.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
padding-top: 64px;
|
||||
}
|
||||
#foo, #bar {
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
}
|
||||
#foo {
|
||||
background: blue;
|
||||
float: right;
|
||||
}
|
||||
#bar {
|
||||
background: gold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id=foo></div><div id=bar></div>
|
||||
</body>
|
||||
</html>
|
||||
|
32
tests/ref/incremental_inline_layout_a.html
Normal file
32
tests/ref/incremental_inline_layout_a.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id=h1>
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
</h1>
|
||||
<script>
|
||||
document.getElementById('h1').getBoundingClientRect(); // Trigger one layout.
|
||||
document.getElementById('h1').getBoundingClientRect(); // Trigger another layout.
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
28
tests/ref/incremental_inline_layout_ref.html
Normal file
28
tests/ref/incremental_inline_layout_ref.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id=h1>
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
Incremental Inline Layout
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
19
tests/ref/line_breaking_whitespace_collapse_a.html
Normal file
19
tests/ref/line_breaking_whitespace_collapse_a.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/ahem.css">
|
||||
<style>
|
||||
p {
|
||||
font-size: 10px;
|
||||
font-family: Ahem, monospace;
|
||||
width: 300px;
|
||||
}
|
||||
a {
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>xxxxx xxxxx <a>xxxxx xxx xxxxx</a> xxxxxxxxxxx</p>
|
||||
</body>
|
||||
|
19
tests/ref/line_breaking_whitespace_collapse_ref.html
Normal file
19
tests/ref/line_breaking_whitespace_collapse_ref.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/ahem.css">
|
||||
<style>
|
||||
p {
|
||||
font-size: 10px;
|
||||
font-family: Ahem, monospace;
|
||||
width: 300px;
|
||||
}
|
||||
a {
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>xxxxx xxxxx <a>xxxxx xxx xxxxx</a><br>xxxxxxxxxxx</p>
|
||||
</body>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<div style="float: left;">
|
||||
<div style="margin-bottom: 64px;">Must be this tall</div>
|
||||
<div style="margin-top: 64px;">to write multi-threaded code.</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -18,9 +18,8 @@ fn test_transform_compress_none() {
|
|||
|
||||
let mode = CompressionMode::CompressNone;
|
||||
for &test in test_strs.iter() {
|
||||
let mut new_line_pos = vec![];
|
||||
let mut trimmed_str = String::new();
|
||||
transform_text(test, mode, true, &mut trimmed_str, &mut new_line_pos);
|
||||
transform_text(test, mode, true, &mut trimmed_str);
|
||||
assert_eq!(trimmed_str, test)
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +51,8 @@ fn test_transform_discard_newline() {
|
|||
|
||||
let mode = CompressionMode::DiscardNewline;
|
||||
for &(test, oracle) in test_strs.iter() {
|
||||
let mut new_line_pos = vec![];
|
||||
let mut trimmed_str = String::new();
|
||||
transform_text(test, mode, true, &mut trimmed_str, &mut new_line_pos);
|
||||
transform_text(test, mode, true, &mut trimmed_str);
|
||||
assert_eq!(trimmed_str, oracle)
|
||||
}
|
||||
}
|
||||
|
@ -86,9 +84,8 @@ fn test_transform_compress_whitespace() {
|
|||
|
||||
let mode = CompressionMode::CompressWhitespace;
|
||||
for &(test, oracle) in test_strs.iter() {
|
||||
let mut new_line_pos = vec![];
|
||||
let mut trimmed_str = String::new();
|
||||
transform_text(test, mode, true, &mut trimmed_str, &mut new_line_pos);
|
||||
transform_text(test, mode, true, &mut trimmed_str);
|
||||
assert_eq!(&*trimmed_str, oracle)
|
||||
}
|
||||
}
|
||||
|
@ -120,9 +117,8 @@ fn test_transform_compress_whitespace_newline() {
|
|||
|
||||
let mode = CompressionMode::CompressWhitespaceNewline;
|
||||
for &(test, oracle) in test_strs.iter() {
|
||||
let mut new_line_pos = vec![];
|
||||
let mut trimmed_str = String::new();
|
||||
transform_text(test, mode, true, &mut trimmed_str, &mut new_line_pos);
|
||||
transform_text(test, mode, true, &mut trimmed_str);
|
||||
assert_eq!(&*trimmed_str, oracle)
|
||||
}
|
||||
}
|
||||
|
@ -157,9 +153,8 @@ fn test_transform_compress_whitespace_newline_no_incoming() {
|
|||
|
||||
let mode = CompressionMode::CompressWhitespaceNewline;
|
||||
for &(test, oracle) in test_strs.iter() {
|
||||
let mut new_line_pos = vec![];
|
||||
let mut trimmed_str = String::new();
|
||||
transform_text(test, mode, false, &mut trimmed_str, &mut new_line_pos);
|
||||
transform_text(test, mode, false, &mut trimmed_str);
|
||||
assert_eq!(trimmed_str, oracle)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ first adding the following to the system's hosts file:
|
|||
127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test
|
||||
127.0.0.1 xn--lve-6lad.web-platform.test
|
||||
|
||||
and then running `python serve.py` from `tests/wpt/web-platform-tests`.
|
||||
and then running `python serve` from `tests/wpt/web-platform-tests`.
|
||||
Then navigate Servo to `http://web-platform.test:8000/path/to/test`.
|
||||
|
||||
Updating test expectations
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[2d.strokeRect.zero.4.html]
|
||||
type: testharness
|
||||
[strokeRect of Nx0 pixels draws a closed line with no caps]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.strokeRect.zero.5.html]
|
||||
type: testharness
|
||||
[strokeRect of Nx0 pixels draws a closed line with joins]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[2d.line.cap.closed.html]
|
||||
type: testharness
|
||||
[Line caps are not drawn at the corners of an unclosed rectangle]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[2d.line.join.bevel.html]
|
||||
type: testharness
|
||||
[lineJoin \'bevel\' is rendered correctly]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.join.closed.html]
|
||||
type: testharness
|
||||
[Line joins are drawn at the corner of a closed rectangle]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.join.miter.html]
|
||||
type: testharness
|
||||
[lineJoin \'miter\' is rendered correctly]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.miter.acute.html]
|
||||
type: testharness
|
||||
[Miter joins are drawn correctly with acute angles]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.miter.invalid.html]
|
||||
type: testharness
|
||||
[Setting miterLimit to invalid values is ignored]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.miter.obtuse.html]
|
||||
type: testharness
|
||||
[Miter joins are drawn correctly with obtuse angles]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.miter.valid.html]
|
||||
type: testharness
|
||||
[Setting miterLimit to valid values works]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[2d.line.miter.within.html]
|
||||
type: testharness
|
||||
[Miter joins are drawn when the miter limit is not quite exceeded]
|
||||
expected: FAIL
|
||||
|
|
@ -2,3 +2,4 @@
|
|||
type: testharness
|
||||
[Shadows are not drawn for transparent parts of canvases]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
type: testharness
|
||||
[Shadows are not drawn for transparent parts of images]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -8955,10 +8955,6 @@
|
|||
"path": "IndexedDB/key_invalid.htm",
|
||||
"url": "/IndexedDB/key_invalid.htm"
|
||||
},
|
||||
{
|
||||
"path": "IndexedDB/key_valid.html",
|
||||
"url": "/IndexedDB/key_valid.html"
|
||||
},
|
||||
{
|
||||
"path": "IndexedDB/keygenerator-constrainterror.htm",
|
||||
"url": "/IndexedDB/keygenerator-constrainterror.htm"
|
||||
|
@ -9819,38 +9815,6 @@
|
|||
"path": "content-security-policy/img-src/img-src-4_1.html",
|
||||
"url": "/content-security-policy/img-src/img-src-4_1.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_1.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_1.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_1_2.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_1_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_2.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_2_2.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_2_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_3.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_3.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_3_2.html",
|
||||
"url": "/content-security-policy/media-src/media-src-7_3_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/object-src/object-src-2_1.html",
|
||||
"url": "/content-security-policy/object-src/object-src-2_1.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/object-src/object-src-2_2.html",
|
||||
"url": "/content-security-policy/object-src/object-src-2_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/script-src/script-src-1_1.html",
|
||||
"url": "/content-security-policy/script-src/script-src-1_1.html"
|
||||
|
@ -10311,6 +10275,10 @@
|
|||
"path": "dom/nodes/CharacterData-replaceData.html",
|
||||
"url": "/dom/nodes/CharacterData-replaceData.html"
|
||||
},
|
||||
{
|
||||
"path": "dom/nodes/CharacterData-substringData.html",
|
||||
"url": "/dom/nodes/CharacterData-substringData.html"
|
||||
},
|
||||
{
|
||||
"path": "dom/nodes/Comment-constructor.html",
|
||||
"url": "/dom/nodes/Comment-constructor.html"
|
||||
|
@ -11271,6 +11239,30 @@
|
|||
"path": "ext-xhtml-pubid/the-xhtml-syntax/parsing-xhtml-documents/xhtml-pubid-1.html",
|
||||
"url": "/ext-xhtml-pubid/the-xhtml-syntax/parsing-xhtml-documents/xhtml-pubid-1.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/image.html",
|
||||
"url": "/fetch/nosniff/image.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/importscripts.html",
|
||||
"url": "/fetch/nosniff/importscripts.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/parsing-nosniff.html",
|
||||
"url": "/fetch/nosniff/parsing-nosniff.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/script.html",
|
||||
"url": "/fetch/nosniff/script.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/stylesheet.html",
|
||||
"url": "/fetch/nosniff/stylesheet.html"
|
||||
},
|
||||
{
|
||||
"path": "fetch/nosniff/worker.html",
|
||||
"url": "/fetch/nosniff/worker.html"
|
||||
},
|
||||
{
|
||||
"path": "gamepad/idlharness.html",
|
||||
"url": "/gamepad/idlharness.html"
|
||||
|
@ -18798,6 +18790,11 @@
|
|||
"timeout": "long",
|
||||
"url": "/IndexedDB/idbobjectstore_createIndex8-valid_keys.htm"
|
||||
},
|
||||
{
|
||||
"path": "IndexedDB/key_valid.html",
|
||||
"timeout": "long",
|
||||
"url": "/IndexedDB/key_valid.html"
|
||||
},
|
||||
{
|
||||
"path": "IndexedDB/keypath_maxsize.htm",
|
||||
"timeout": "long",
|
||||
|
@ -18823,6 +18820,46 @@
|
|||
"timeout": "long",
|
||||
"url": "/ambient-light/AmbientLight_tests.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_1.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_1.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_1_2.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_1_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_2.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_2_2.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_2_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_3.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_3.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/media-src/media-src-7_3_2.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/media-src/media-src-7_3_2.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/object-src/object-src-2_1.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/object-src/object-src-2_1.html"
|
||||
},
|
||||
{
|
||||
"path": "content-security-policy/object-src/object-src-2_2.html",
|
||||
"timeout": "long",
|
||||
"url": "/content-security-policy/object-src/object-src-2_2.html"
|
||||
},
|
||||
{
|
||||
"path": "cors/status-async.htm",
|
||||
"timeout": "long",
|
||||
|
@ -25034,7 +25071,7 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"rev": "0d318188757a9c996e20b82db201fd04de5aa255",
|
||||
"rev": "2a9fd810bb18610b422dbc3998ab74aa1bffae95",
|
||||
"url_base": "/",
|
||||
"version": 2
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
[getresponseheader-chunked-trailer.htm]
|
||||
type: testharness
|
||||
[XMLHttpRequest: getResponseHeader() and HTTP trailer]
|
||||
expected: FAIL
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
[timeout-cors-async.htm]
|
||||
type: testharness
|
||||
expected: OK
|
||||
[XMLHttpRequest: timeout event and cross-origin request]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -90,9 +90,6 @@
|
|||
[Document interface: operation importNode(Node,boolean)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: operation createAttributeNS(DOMString,DOMString)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: operation createNodeIterator(Node,unsigned long,NodeFilter)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -132,9 +129,6 @@
|
|||
[Document interface: xmlDoc must inherit property "origin" with the proper type (3)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: calling createAttributeNS(DOMString,DOMString) on xmlDoc with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: calling createNodeIterator(Node,unsigned long,NodeFilter) on xmlDoc with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -252,12 +246,6 @@
|
|||
[Element interface: operation queryAll(DOMString)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: attribute previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: attribute nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation before([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -321,12 +309,6 @@
|
|||
[Element interface: calling queryAll(DOMString) on element with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "previousElementSibling" with the proper type (37)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "nextElementSibling" with the proper type (38)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "before" with the proper type (39)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -345,12 +327,6 @@
|
|||
[NamedNodeMap interface: operation setNamedItemNS(Attr)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: attribute previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: attribute nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: operation before([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -375,12 +351,6 @@
|
|||
[Text interface: document.createTextNode("abc") must inherit property "wholeText" with the proper type (1)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createTextNode("abc") must inherit property "previousElementSibling" with the proper type (7)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createTextNode("abc") must inherit property "nextElementSibling" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createTextNode("abc") must inherit property "before" with the proper type (9)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -393,12 +363,6 @@
|
|||
[CharacterData interface: calling after([object Object\],[object Object\]) on document.createTextNode("abc") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "previousElementSibling" with the proper type (7)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "nextElementSibling" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: xmlDoc.createProcessingInstruction("abc", "def") must inherit property "before" with the proper type (9)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -414,12 +378,6 @@
|
|||
[Comment interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createComment("abc") must inherit property "previousElementSibling" with the proper type (7)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createComment("abc") must inherit property "nextElementSibling" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: document.createComment("abc") must inherit property "before" with the proper type (9)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -969,9 +927,6 @@
|
|||
[DOMTokenList interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: xmlDoc must inherit property "createAttributeNS" with the proper type (22)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: xmlDoc must inherit property "createNodeIterator" with the proper type (25)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[CharacterData-substringData.html]
|
||||
type: testharness
|
||||
expected: CRASH
|
|
@ -1,35 +0,0 @@
|
|||
[DOMImplementation-createDocument.html]
|
||||
type: testharness
|
||||
[createDocument test 23: null,"xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 41: undefined,"xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 64: "http://example.com/","xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 69: "http://example.com/","xmlns:foo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 108: "/","xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 111: "/","xmlns:foo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 121: "http://www.w3.org/XML/1998/namespace","xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 124: "http://www.w3.org/XML/1998/namespace","xmlns:foo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 141: "http://www.w3.org/2000/xmlns/","foo:xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 150: "foo:","xmlns",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createDocument test 153: "foo:","xmlns:foo",null,"NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
[Document-createElementNS.html]
|
||||
type: testharness
|
||||
[createElementNS test 23: null,"xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 41: undefined,"xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 64: "http://example.com/","xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 69: "http://example.com/","xmlns:foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 108: "/","xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 111: "/","xmlns:foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 121: "http://www.w3.org/XML/1998/namespace","xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 124: "http://www.w3.org/XML/1998/namespace","xmlns:foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 141: "http://www.w3.org/2000/xmlns/","foo:xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 150: "foo:","xmlns","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
||||
[createElementNS test 153: "foo:","xmlns:foo","NAMESPACE_ERR"]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[Element-nextElementSibling.html]
|
||||
type: testharness
|
||||
[nextElementSibling]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[Element-previousElementSibling.html]
|
||||
type: testharness
|
||||
[previousElementSibling]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[Element-siblingElement-null.html]
|
||||
type: testharness
|
||||
[Null test]
|
||||
expected: FAIL
|
||||
|
|
@ -1,50 +1,5 @@
|
|||
[Node-properties.html]
|
||||
type: testharness
|
||||
[testDiv.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedDiv.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedDiv.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedPara1.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedPara1.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedPara2.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedPara2.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[foreignPara1.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[foreignPara1.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[foreignPara2.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[foreignPara2.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[xmlElement.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[xmlElement.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedXmlElement.previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedXmlElement.nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[detachedTextNode.wholeText]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -60,32 +15,3 @@
|
|||
[detachedXmlTextNode.wholeText]
|
||||
expected: FAIL
|
||||
|
||||
[paras[0\].previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[0\].nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[1\].previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[1\].nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[2\].previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[2\].nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[3\].previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[3\].nextElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[4\].previousElementSibling]
|
||||
expected: FAIL
|
||||
|
||||
[paras[4\].nextElementSibling]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
[api-basics.html]
|
||||
type: testharness
|
||||
[Default encodings]
|
||||
expected: FAIL
|
||||
|
||||
[Default inputs]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
[api-surrogates-utf8.html]
|
||||
type: testharness
|
||||
[Invalid surrogates encoded into UTF-8: Sanity check]
|
||||
expected: FAIL
|
||||
|
||||
[Invalid surrogates encoded into UTF-8: Surrogate half (low)]
|
||||
expected: FAIL
|
||||
|
||||
[Invalid surrogates encoded into UTF-8: Surrogate half (high)]
|
||||
expected: FAIL
|
||||
|
||||
[Invalid surrogates encoded into UTF-8: Surrogate half (low), in a string]
|
||||
expected: FAIL
|
||||
|
||||
[Invalid surrogates encoded into UTF-8: Surrogate half (high), in a string]
|
||||
expected: FAIL
|
||||
|
||||
[Invalid surrogates encoded into UTF-8: Wrong order]
|
||||
expected: FAIL
|
||||
|
|
@ -1,50 +1,17 @@
|
|||
[idlharness.html]
|
||||
type: testharness
|
||||
[TextDecoder interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: existence and properties of interface prototype object\'s "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: attribute encoding]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: attribute fatal]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: attribute ignoreBOM]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: operation decode(BufferSource,TextDecodeOptions)]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder must be primary interface of new TextDecoder()]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of new TextDecoder()]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: new TextDecoder() must inherit property "encoding" with the proper type (0)]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: new TextDecoder() must inherit property "fatal" with the proper type (1)]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: new TextDecoder() must inherit property "ignoreBOM" with the proper type (2)]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: new TextDecoder() must inherit property "decode" with the proper type (3)]
|
||||
expected: FAIL
|
||||
|
||||
[TextDecoder interface: calling decode(BufferSource,TextDecodeOptions) on new TextDecoder() with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[TextEncoder interface object length]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -3,21 +3,12 @@
|
|||
[iso-2022-jp decoder: Error ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Error ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: ASCII ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Double ASCII ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, ASCII ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: characters]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: SO / SI]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -27,12 +18,6 @@
|
|||
[iso-2022-jp decoder: Roman ESC, SO / SI]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Roman ESC, error ESC, Katakana ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Katakana ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Katakana ESC, multibyte ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -42,18 +27,6 @@
|
|||
[iso-2022-jp decoder: Katakana ESC, error ESC #2, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Katakana ESC, character, Katakana ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Katakana ESC, SO / SI]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Multibyte ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Multibyte ESC #2, character]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Multibyte ESC, error ESC, character]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -75,30 +48,6 @@
|
|||
[iso-2022-jp decoder: Multibyte ESC, lead error byte]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: Multibyte ESC, trail error byte]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, error ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, error ESC #2]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, error ESC #3]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, ASCII ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, Roman ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, Katakana ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, Multibyte ESC]
|
||||
expected: FAIL
|
||||
|
||||
[iso-2022-jp decoder: character, Multibyte ESC #2]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
[textdecoder-fatal.html]
|
||||
type: testharness
|
||||
[Fatal flag: utf-8 - invalid code]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - ends early]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - ends early 2]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail 2]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail 3]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail 4]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail 5]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - invalid trail 6]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - > 0x10FFFF]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - obsolete lead byte]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+0000 - 2 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+0000 - 3 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+0000 - 4 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+0000 - 5 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+0000 - 6 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+007F - 2 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+007F - 3 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+007F - 4 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+007F - 5 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+007F - 6 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+07FF - 3 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+07FF - 4 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+07FF - 5 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+07FF - 6 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+FFFF - 4 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+FFFF - 5 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+FFFF - 6 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+10FFFF - 5 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - overlong U+10FFFF - 6 bytes]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - lead surrogate]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - trail surrogate]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-8 - surrogate pair]
|
||||
expected: FAIL
|
||||
|
||||
[Fatal flag: utf-16le - truncated code unit]
|
||||
expected: FAIL
|
||||
|
||||
[The fatal attribute of TextDecoder]
|
||||
expected: FAIL
|
||||
|
|
@ -1,515 +1,5 @@
|
|||
[textdecoder-labels.html]
|
||||
type: testharness
|
||||
[name=utf-8 label=unicode-1-1-utf-8]
|
||||
expected: FAIL
|
||||
|
||||
[name=utf-8 label=utf-8]
|
||||
expected: FAIL
|
||||
|
||||
[name=utf-8 label=utf8]
|
||||
expected: FAIL
|
||||
|
||||
[name=ibm866 label=866]
|
||||
expected: FAIL
|
||||
|
||||
[name=ibm866 label=cp866]
|
||||
expected: FAIL
|
||||
|
||||
[name=ibm866 label=csibm866]
|
||||
expected: FAIL
|
||||
|
||||
[name=ibm866 label=ibm866]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=csisolatin2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso-8859-2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso-ir-101]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso8859-2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso88592]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso_8859-2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=iso_8859-2:1987]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=l2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-2 label=latin2]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=csisolatin3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso-8859-3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso-ir-109]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso8859-3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso88593]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso_8859-3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=iso_8859-3:1988]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=l3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-3 label=latin3]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=csisolatin4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso-8859-4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso-ir-110]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso8859-4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso88594]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso_8859-4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=iso_8859-4:1988]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=l4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-4 label=latin4]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=csisolatincyrillic]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=cyrillic]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso-8859-5]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso-ir-144]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso8859-5]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso88595]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso_8859-5]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-5 label=iso_8859-5:1988]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=arabic]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=asmo-708]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=csiso88596e]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=csiso88596i]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=csisolatinarabic]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=ecma-114]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso-8859-6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso-8859-6-e]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso-8859-6-i]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso-ir-127]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso8859-6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso88596]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso_8859-6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-6 label=iso_8859-6:1987]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=csisolatingreek]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=ecma-118]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=elot_928]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=greek]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=greek8]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso-8859-7]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso-ir-126]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso8859-7]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso88597]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso_8859-7]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=iso_8859-7:1987]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-7 label=sun_eu_greek]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=csiso88598e]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=csisolatinhebrew]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=hebrew]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso-8859-8]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso-8859-8-e]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso-ir-138]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso8859-8]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso88598]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso_8859-8]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=iso_8859-8:1988]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8 label=visual]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8-i label=csiso88598i]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8-i label=iso-8859-8-i]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-8-i label=logical]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=csisolatin6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=iso-8859-10]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=iso-ir-157]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=iso8859-10]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=iso885910]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=l6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-10 label=latin6]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-13 label=iso-8859-13]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-13 label=iso8859-13]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-13 label=iso885913]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-14 label=iso-8859-14]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-14 label=iso8859-14]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-14 label=iso885914]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=csisolatin9]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=iso-8859-15]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=iso8859-15]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=iso885915]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=iso_8859-15]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-15 label=l9]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-8859-16 label=iso-8859-16]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-r label=cskoi8r]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-r label=koi]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-r label=koi8]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-r label=koi8-r]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-r label=koi8_r]
|
||||
expected: FAIL
|
||||
|
||||
[name=koi8-u label=koi8-u]
|
||||
expected: FAIL
|
||||
|
||||
[name=macintosh label=csmacintosh]
|
||||
expected: FAIL
|
||||
|
||||
[name=macintosh label=mac]
|
||||
expected: FAIL
|
||||
|
||||
[name=macintosh label=macintosh]
|
||||
expected: FAIL
|
||||
|
||||
[name=macintosh label=x-mac-roman]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=dos-874]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=iso-8859-11]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=iso8859-11]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=iso885911]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=tis-620]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-874 label=windows-874]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1250 label=cp1250]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1250 label=windows-1250]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1250 label=x-cp1250]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1251 label=cp1251]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1251 label=windows-1251]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1251 label=x-cp1251]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=ansi_x3.4-1968]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=ascii]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=cp1252]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=cp819]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=csisolatin1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=ibm819]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso-8859-1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso-ir-100]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso8859-1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso88591]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso_8859-1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=iso_8859-1:1987]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=l1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=latin1]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=us-ascii]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=windows-1252]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1252 label=x-cp1252]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1253 label=cp1253]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1253 label=windows-1253]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1253 label=x-cp1253]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=cp1254]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=csisolatin5]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso-8859-9]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso-ir-148]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso8859-9]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso88599]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso_8859-9]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=iso_8859-9:1989]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=l5]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=latin5]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=windows-1254]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1254 label=x-cp1254]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1255 label=cp1255]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1255 label=windows-1255]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1255 label=x-cp1255]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1256 label=cp1256]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1256 label=windows-1256]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1256 label=x-cp1256]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1257 label=cp1257]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1257 label=windows-1257]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1257 label=x-cp1257]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1258 label=cp1258]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1258 label=windows-1258]
|
||||
expected: FAIL
|
||||
|
||||
[name=windows-1258 label=x-cp1258]
|
||||
expected: FAIL
|
||||
|
||||
[name=x-mac-cyrillic label=x-mac-cyrillic]
|
||||
expected: FAIL
|
||||
|
||||
[name=x-mac-cyrillic label=x-mac-ukrainian]
|
||||
expected: FAIL
|
||||
|
||||
[name=gbk label=chinese]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -537,99 +27,9 @@
|
|||
[name=gbk label=x-gbk]
|
||||
expected: FAIL
|
||||
|
||||
[name=gb18030 label=gb18030]
|
||||
expected: FAIL
|
||||
|
||||
[name=big5 label=big5]
|
||||
expected: FAIL
|
||||
|
||||
[name=big5 label=big5-hkscs]
|
||||
expected: FAIL
|
||||
|
||||
[name=big5 label=cn-big5]
|
||||
expected: FAIL
|
||||
|
||||
[name=big5 label=csbig5]
|
||||
expected: FAIL
|
||||
|
||||
[name=big5 label=x-x-big5]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-jp label=cseucpkdfmtjapanese]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-jp label=euc-jp]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-jp label=x-euc-jp]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-2022-jp label=csiso2022jp]
|
||||
expected: FAIL
|
||||
|
||||
[name=iso-2022-jp label=iso-2022-jp]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=csshiftjis]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=ms_kanji]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=shift-jis]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=shift_jis]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=sjis]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=windows-31j]
|
||||
expected: FAIL
|
||||
|
||||
[name=shift_jis label=x-sjis]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=cseuckr]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=csksc56011987]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=euc-kr]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=iso-ir-149]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=korean]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=ks_c_5601-1987]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=ks_c_5601-1989]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=ksc5601]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=ksc_5601]
|
||||
expected: FAIL
|
||||
|
||||
[name=euc-kr label=windows-949]
|
||||
expected: FAIL
|
||||
|
||||
[name=utf-16be label=utf-16be]
|
||||
expected: FAIL
|
||||
|
||||
[name=utf-16le label=utf-16]
|
||||
expected: FAIL
|
||||
|
||||
[name=utf-16le label=utf-16le]
|
||||
expected: FAIL
|
||||
|
||||
[name=x-user-defined label=x-user-defined]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,47 +1,20 @@
|
|||
[textdecoder-streaming.html]
|
||||
type: testharness
|
||||
[Streaming decode: utf-8, 1 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 3 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 5 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 1 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 3 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 5 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 1 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 3 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 5 byte window]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
[textdecoder-utf16-surrogates.html]
|
||||
type: testharness
|
||||
[utf-16le - lone surrogate lead]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - lone surrogate lead (fatal flag set)]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - lone surrogate trail]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - lone surrogate trail (fatal flag set)]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - unmatched surrogate lead]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - unmatched surrogate lead (fatal flag set)]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - unmatched surrogate trail]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - unmatched surrogate trail (fatal flag set)]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - swapped surrogate pair]
|
||||
expected: FAIL
|
||||
|
||||
[utf-16le - swapped surrogate pair (fatal flag set)]
|
||||
expected: FAIL
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
[textencoder-constructor-non-utf.html]
|
||||
type: testharness
|
||||
[UTF encodings are supported for encode and decode: utf-8]
|
||||
expected: FAIL
|
||||
|
||||
[Non-UTF encodings supported only for decode, not encode: ibm866]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -108,9 +105,6 @@
|
|||
[Non-UTF encodings supported only for decode, not encode: euc-kr]
|
||||
expected: FAIL
|
||||
|
||||
[UTF encodings are supported for encode and decode: utf-16be]
|
||||
expected: FAIL
|
||||
|
||||
[UTF encodings are supported for encode and decode: utf-16le]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
[textencoder-utf16-surrogates.html]
|
||||
type: testharness
|
||||
[USVString handling: lone surrogate lead]
|
||||
expected: FAIL
|
||||
|
||||
[USVString handling: lone surrogate trail]
|
||||
expected: FAIL
|
||||
|
||||
[USVString handling: unmatched surrogate lead]
|
||||
expected: FAIL
|
||||
|
||||
[USVString handling: unmatched surrogate trail]
|
||||
expected: FAIL
|
||||
|
||||
[USVString handling: swapped surrogate pair]
|
||||
expected: FAIL
|
||||
|
||||
[USVString handling: properly encoded MUSICAL SYMBOL G CLEF (U+1D11E)]
|
||||
expected: FAIL
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
[frameElement.sub.html]
|
||||
type: testharness
|
||||
expected: OK
|
||||
[The window\'s frameElement attribute must return its container element if it is a nested browsing context]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1035,12 +1035,6 @@
|
|||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "origin" with the proper type (3)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "createAttributeNS" with the proper type (22)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: calling createAttributeNS(DOMString,DOMString) on document.implementation.createDocument(null, "", null) with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "createNodeIterator" with the proper type (25)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -2220,12 +2214,6 @@
|
|||
[Element interface: calling queryAll(DOMString) on document.createElement("noscript") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "previousElementSibling" with the proper type (37)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "nextElementSibling" with the proper type (38)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "before" with the proper type (39)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -7011,9 +6999,6 @@
|
|||
[CanvasRenderingContext2D interface: attribute lineJoin]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: attribute miterLimit]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: operation setLineDash([object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -7221,9 +7206,6 @@
|
|||
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "lineJoin" with the proper type (61)]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "miterLimit" with the proper type (62)]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "setLineDash" with the proper type (63)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -20,3 +20,4 @@
|
|||
|
||||
[A disabled <input[type=radio\]> should not be focusable]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -705,3 +705,6 @@
|
|||
["data:,a 1w \\x011h" (leading U+0001)]
|
||||
expected: FAIL
|
||||
|
||||
["data:,a 1w"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[WorkerGlobalScope_importScripts_NetworkErr.htm]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[ importScripts() with non-existent script file ]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
type: testharness
|
||||
[members of WorkerLocation]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- Submitted from TestTWF Paris -->
|
||||
<meta charset=utf-8">
|
||||
<meta name="timeout" content="long">
|
||||
<title>Valid key</title>
|
||||
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#key-construct">
|
||||
<link rel=assert title="A value is said to be a valid key if it is one of the following types: Array JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float [WEBIDL]. However Arrays are only valid keys if every item in the array is defined and is a valid key (i.e. sparse arrays can not be valid keys) and if the Array doesn't directly or indirectly contain itself. Any non-numeric properties are ignored, and thus does not affect whether the Array is a valid key. Additionally, if the value is of type float, it is only a valid key if it is not NaN, and if the value is of type Date it is only a valid key if its [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN. Conforming user agents must support all valid keys as keys.">
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
The Web Platform Tests Project [](http://irc.w3.org/?channels=testing)
|
||||
==============================
|
||||
|
||||
These are test suites for 60+ Web-platform specifications, along
|
||||
with test-infrastructure code for running the tests.
|
||||
The Web Platform Tests Project is a W3C-coordinated attempt to build a
|
||||
cross-browser testsuite for the Web-platform stack. Writing tests in a
|
||||
way that allows them to be run in all browsers gives browser projects
|
||||
confidence that they are shipping software that is compatible with other
|
||||
implementations, and that later implementations will be compatible with
|
||||
their implementations. This in turn gives Web authors/developers
|
||||
confidence that they can actually rely on the Web platform to deliver on
|
||||
the promise of working across browsers and devices without needing extra
|
||||
layers of abstraction to paper over the gaps left by specification
|
||||
editors and implementors.
|
||||
|
||||
Running the Tests
|
||||
=================
|
||||
|
|
|
@ -10,7 +10,7 @@ def main(request, response):
|
|||
response.write_status_headers()
|
||||
|
||||
for value in chunks:
|
||||
response.writer.write("%d\r\n" % len(value))
|
||||
response.writer.write("%x\r\n" % len(value))
|
||||
response.writer.write(value)
|
||||
response.writer.write("\r\n")
|
||||
response.writer.write("0\r\n")
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Video element src attribute must match src list - positive test</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Video element src attribute must match src list - negative test</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Audio element src attribute must match src list - positive test</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Audio element src attribute must match src list - negative test</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Video track src attribute must match src list - positive test</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
|
|
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