mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Layout: Implement innerText/outerText (#33312)
* Implement outerText on HtmlElement Signed-off-by: Shane Handley <shanehandley@fastmail.com> * Fixed some innerText/outerText bugs Signed-off-by: Benjamin Vincent Schulenburg <bennyschulenburg@gmx.de> * Unified innerText/outerText handling outside of Layout Before these 2 were treated separately and only within Layout would they end up calling the same method, now they are already unified within HTMLElement Signed-off-by: Benjamin Vincent Schulenburg <bennyschulenburg@gmx.de> * Address a few nits Signed-off-by: Martin Robinson <mrobinson@igalia.com> * Added innerText support for `inline-flex` Signed-off-by: Benjamin Vincent Schulenburg <bennyschulenburg@gmx.de> --------- Signed-off-by: Shane Handley <shanehandley@fastmail.com> Signed-off-by: Benjamin Vincent Schulenburg <bennyschulenburg@gmx.de> Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Shane Handley <shanehandley@fastmail.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
88ffe9f7a5
commit
dbd1666b17
26 changed files with 617 additions and 1625 deletions
|
@ -972,8 +972,8 @@ enum InnerTextItem {
|
|||
RequiredLineBreakCount(u32),
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute
|
||||
pub fn process_element_inner_text_query<'dom>(
|
||||
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
||||
pub fn get_the_text_steps<'dom>(
|
||||
node: impl LayoutNode<'dom>,
|
||||
indexable_text: &IndexableText,
|
||||
) -> String {
|
||||
|
|
|
@ -12,10 +12,13 @@ use log::warn;
|
|||
use script_layout_interface::wrapper_traits::{
|
||||
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
||||
};
|
||||
use script_layout_interface::OffsetParentResponse;
|
||||
use script_layout_interface::{LayoutElementType, LayoutNodeType, OffsetParentResponse};
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use servo_url::ServoUrl;
|
||||
use style::computed_values::display::T as Display;
|
||||
use style::computed_values::position::T as Position;
|
||||
use style::computed_values::visibility::T as Visibility;
|
||||
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapseValue;
|
||||
use style::context::{QuirksMode, SharedStyleContext, StyleContext, ThreadLocalStyleContext};
|
||||
use style::dom::{OpaqueNode, TElement};
|
||||
use style::properties::style_structs::Font;
|
||||
|
@ -28,9 +31,11 @@ use style::shared_lock::SharedRwLock;
|
|||
use style::stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||
use style::stylist::RuleInclusion;
|
||||
use style::traversal::resolve_style;
|
||||
use style::values::computed::Float;
|
||||
use style::values::generics::font::LineHeight;
|
||||
use style_traits::{ParsingMode, ToCss};
|
||||
|
||||
use crate::flow::inline::construct::{TextTransformation, WhitespaceCollapse};
|
||||
use crate::fragment_tree::{BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag};
|
||||
|
||||
pub fn process_content_box_request(
|
||||
|
@ -507,9 +512,430 @@ fn is_eligible_parent(fragment: &BoxFragment) -> bool {
|
|||
.contains(FragmentFlags::IS_TABLE_TH_OR_TD_ELEMENT)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute
|
||||
pub fn process_element_inner_text_query<'dom>(_node: impl LayoutNode<'dom>) -> String {
|
||||
"".to_owned()
|
||||
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
||||
pub fn get_the_text_steps<'dom>(node: impl LayoutNode<'dom>) -> String {
|
||||
// Step 1: If element is not being rendered or if the user agent is a non-CSS user agent, then
|
||||
// return element's descendant text content.
|
||||
// This is taken care of in HTMLElemnent code
|
||||
|
||||
// Step 2: Let results be a new empty list.
|
||||
let mut results = Vec::new();
|
||||
let mut max_req_line_break_count = 0;
|
||||
|
||||
// Step 3: For each child node node of element:
|
||||
let mut state = Default::default();
|
||||
for child in node.dom_children() {
|
||||
// Step 1: Let current be the list resulting in running the rendered text collection steps with node.
|
||||
let mut current = rendered_text_collection_steps(child, &mut state);
|
||||
// Step 2: For each item item in current, append item to results.
|
||||
results.append(&mut current);
|
||||
}
|
||||
|
||||
let mut output = Vec::new();
|
||||
for item in results {
|
||||
match item {
|
||||
InnerOrOuterTextItem::Text(s) => {
|
||||
// Step 3.
|
||||
if !s.is_empty() {
|
||||
if max_req_line_break_count > 0 {
|
||||
// Step 5.
|
||||
output.push("\u{000A}".repeat(max_req_line_break_count));
|
||||
max_req_line_break_count = 0;
|
||||
}
|
||||
output.push(s);
|
||||
}
|
||||
},
|
||||
InnerOrOuterTextItem::RequiredLineBreakCount(count) => {
|
||||
// Step 4.
|
||||
if output.is_empty() {
|
||||
// Remove required line break count at the start.
|
||||
continue;
|
||||
}
|
||||
// Store the count if it's the max of this run, but it may be ignored if no text
|
||||
// item is found afterwards, which means that these are consecutive line breaks at
|
||||
// the end.
|
||||
if count > max_req_line_break_count {
|
||||
max_req_line_break_count = count;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
output.into_iter().collect()
|
||||
}
|
||||
|
||||
enum InnerOrOuterTextItem {
|
||||
Text(String),
|
||||
RequiredLineBreakCount(usize),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct RenderedTextCollectionState {
|
||||
/// Used to make sure we don't add a `\n` before the first row
|
||||
first_table_row: bool,
|
||||
/// Used to make sure we don't add a `\t` before the first column
|
||||
first_table_cell: bool,
|
||||
/// Keeps track of whether we're inside a table, since there are special rules like ommiting everything that's not
|
||||
/// inside a TableCell/TableCaption
|
||||
within_table: bool,
|
||||
/// Determines whether we truncate leading whitespaces for normal nodes or not
|
||||
may_start_with_whitespace: bool,
|
||||
/// Is set whenever we truncated a white space char, used to prepend a single space before the next element,
|
||||
/// that way we truncate trailing white space without having to look ahead
|
||||
did_truncate_trailing_white_space: bool,
|
||||
/// Is set to true when we're rendering the children of TableCell/TableCaption elements, that way we render
|
||||
/// everything inside those as normal, while omitting everything that's in a Table but NOT in a Cell/Caption
|
||||
within_table_content: bool,
|
||||
}
|
||||
|
||||
impl Default for RenderedTextCollectionState {
|
||||
fn default() -> Self {
|
||||
RenderedTextCollectionState {
|
||||
first_table_row: true,
|
||||
first_table_cell: true,
|
||||
may_start_with_whitespace: true,
|
||||
did_truncate_trailing_white_space: false,
|
||||
within_table: false,
|
||||
within_table_content: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#rendered-text-collection-steps>
|
||||
fn rendered_text_collection_steps<'dom>(
|
||||
node: impl LayoutNode<'dom>,
|
||||
state: &mut RenderedTextCollectionState,
|
||||
) -> Vec<InnerOrOuterTextItem> {
|
||||
// Step 1. Let items be the result of running the rendered text collection
|
||||
// steps with each child node of node in tree order,
|
||||
// and then concatenating the results to a single list.
|
||||
let mut items = vec![];
|
||||
if !node.is_connected() || !(node.is_element() || node.is_text_node()) {
|
||||
return items;
|
||||
}
|
||||
|
||||
match node.type_id() {
|
||||
LayoutNodeType::Text => {
|
||||
if let Some(element) = node.parent_node() {
|
||||
match element.type_id() {
|
||||
// Any text contained in these elements must be ignored.
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLImageElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLObjectElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLInputElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLMediaElement) => {
|
||||
return items;
|
||||
},
|
||||
// Select/Option/OptGroup elements are handled a bit differently.
|
||||
// Basically: a Select can only contain Options or OptGroups, while
|
||||
// OptGroups may also contain Options. Everything else gets ignored.
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLOptGroupElement) => {
|
||||
if let Some(element) = element.parent_node() {
|
||||
if !matches!(
|
||||
element.type_id(),
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLSelectElement)
|
||||
) {
|
||||
return items;
|
||||
}
|
||||
} else {
|
||||
return items;
|
||||
}
|
||||
},
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLSelectElement) => return items,
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// Tables are also a bit special, mainly by only allowing
|
||||
// content within TableCell or TableCaption elements once
|
||||
// we're inside a Table.
|
||||
if state.within_table && !state.within_table_content {
|
||||
return items;
|
||||
}
|
||||
|
||||
let Some(style_data) = element.style_data() else {
|
||||
return items;
|
||||
};
|
||||
|
||||
let element_data = style_data.element_data.borrow();
|
||||
let Some(style) = element_data.styles.get_primary() else {
|
||||
return items;
|
||||
};
|
||||
|
||||
// Step 2: If node's computed value of 'visibility' is not 'visible', then return items.
|
||||
//
|
||||
// We need to do this check here on the Text fragment, if we did it on the element and
|
||||
// just skipped rendering all child nodes then there'd be no way to override the
|
||||
// visibility in a child node.
|
||||
if style.get_inherited_box().visibility != Visibility::Visible {
|
||||
return items;
|
||||
}
|
||||
|
||||
// Step 3: If node is not being rendered, then return items. For the purpose of this step,
|
||||
// the following elements must act as described if the computed value of the 'display'
|
||||
// property is not 'none':
|
||||
let display = style.get_box().display;
|
||||
if display == Display::None {
|
||||
match element.type_id() {
|
||||
// Even if set to Display::None, Option/OptGroup elements need to
|
||||
// be rendered.
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLOptGroupElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLOptionElement) => {},
|
||||
_ => {
|
||||
return items;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let text_content = node.to_threadsafe().node_text_content();
|
||||
|
||||
let white_space_collapse = style.clone_white_space_collapse();
|
||||
let preserve_whitespace = white_space_collapse == WhiteSpaceCollapseValue::Preserve;
|
||||
let is_inline = matches!(
|
||||
display,
|
||||
Display::InlineBlock | Display::InlineFlex | Display::InlineGrid
|
||||
);
|
||||
// Now we need to decide on whether to remove beginning white space or not, this
|
||||
// is mainly decided by the elements we rendered before, but may be overwritten by the white-space
|
||||
// property.
|
||||
let trim_beginning_white_space =
|
||||
!preserve_whitespace && (state.may_start_with_whitespace || is_inline);
|
||||
let with_white_space_rules_applied = WhitespaceCollapse::new(
|
||||
text_content.chars(),
|
||||
white_space_collapse,
|
||||
trim_beginning_white_space,
|
||||
);
|
||||
|
||||
// Step 4: If node is a Text node, then for each CSS text box produced by node, in
|
||||
// content order, compute the text of the box after application of the CSS
|
||||
// 'white-space' processing rules and 'text-transform' rules, set items to the list
|
||||
// of the resulting strings, and return items. The CSS 'white-space' processing
|
||||
// rules are slightly modified: collapsible spaces at the end of lines are always
|
||||
// collapsed, but they are only removed if the line is the last line of the block,
|
||||
// or it ends with a br element. Soft hyphens should be preserved.
|
||||
let mut transformed_text: String = TextTransformation::new(
|
||||
with_white_space_rules_applied,
|
||||
style.clone_text_transform().case(),
|
||||
)
|
||||
.collect();
|
||||
|
||||
let is_preformatted_element =
|
||||
white_space_collapse == WhiteSpaceCollapseValue::Preserve;
|
||||
|
||||
let is_final_character_whitespace = transformed_text
|
||||
.chars()
|
||||
.next_back()
|
||||
.filter(char::is_ascii_whitespace)
|
||||
.is_some();
|
||||
|
||||
let is_first_character_whitespace = transformed_text
|
||||
.chars()
|
||||
.next()
|
||||
.filter(char::is_ascii_whitespace)
|
||||
.is_some();
|
||||
|
||||
// By truncating trailing white space and then adding it back in once we
|
||||
// encounter another text node we can ensure no trailing white space for
|
||||
// normal text without having to look ahead
|
||||
if state.did_truncate_trailing_white_space && !is_first_character_whitespace {
|
||||
items.push(InnerOrOuterTextItem::Text(String::from(" ")));
|
||||
};
|
||||
|
||||
if transformed_text.len() > 0 {
|
||||
// Here we decide whether to keep or truncate the final white
|
||||
// space character, if there is one.
|
||||
if is_final_character_whitespace && !is_preformatted_element {
|
||||
state.may_start_with_whitespace = false;
|
||||
state.did_truncate_trailing_white_space = true;
|
||||
transformed_text.pop();
|
||||
} else {
|
||||
state.may_start_with_whitespace = is_final_character_whitespace;
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
}
|
||||
items.push(InnerOrOuterTextItem::Text(transformed_text));
|
||||
}
|
||||
} else {
|
||||
// If we don't have a parent element then there's no style data available,
|
||||
// in this (pretty unlikely) case we just return the Text fragment as is.
|
||||
items.push(InnerOrOuterTextItem::Text(
|
||||
node.to_threadsafe().node_text_content().into(),
|
||||
));
|
||||
}
|
||||
},
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLBRElement) => {
|
||||
// Step 5: If node is a br element, then append a string containing a single U+000A
|
||||
// LF code point to items.
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
state.may_start_with_whitespace = true;
|
||||
items.push(InnerOrOuterTextItem::Text(String::from("\u{000A}")));
|
||||
},
|
||||
_ => {
|
||||
// First we need to gather some infos to setup the various flags
|
||||
// before rendering the child nodes
|
||||
let Some(style_data) = node.style_data() else {
|
||||
return items;
|
||||
};
|
||||
|
||||
let element_data = style_data.element_data.borrow();
|
||||
let Some(style) = element_data.styles.get_primary() else {
|
||||
return items;
|
||||
};
|
||||
let inherited_box = style.get_inherited_box();
|
||||
|
||||
if inherited_box.visibility != Visibility::Visible {
|
||||
// If the element is not visible then we'll immediatly render all children,
|
||||
// skipping all other processing.
|
||||
// We can't just stop here since a child can override a parents visibility.
|
||||
for child in node.dom_children() {
|
||||
items.append(&mut rendered_text_collection_steps(child, state));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
let style_box = style.get_box();
|
||||
let display = style_box.display;
|
||||
let mut surrounding_line_breaks = 0;
|
||||
|
||||
// Treat absolutely positioned or floated elements like Block elements
|
||||
if style_box.position == Position::Absolute || style_box.float != Float::None {
|
||||
surrounding_line_breaks = 1;
|
||||
}
|
||||
|
||||
// Depending on the display property we have to do various things
|
||||
// before we can render the child nodes.
|
||||
match display {
|
||||
Display::Table => {
|
||||
surrounding_line_breaks = 1;
|
||||
state.within_table = true;
|
||||
},
|
||||
// Step 6: If node's computed value of 'display' is 'table-cell',
|
||||
// and node's CSS box is not the last 'table-cell' box of its
|
||||
// enclosing 'table-row' box, then append a string containing
|
||||
// a single U+0009 TAB code point to items.
|
||||
Display::TableCell => {
|
||||
if !state.first_table_cell {
|
||||
items.push(InnerOrOuterTextItem::Text(String::from(
|
||||
"\u{0009}", /* tab */
|
||||
)));
|
||||
// Make sure we don't add a white-space we removed from the previous node
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
}
|
||||
state.first_table_cell = false;
|
||||
state.within_table_content = true;
|
||||
},
|
||||
// Step 7: If node's computed value of 'display' is 'table-row',
|
||||
// and node's CSS box is not the last 'table-row' box of the nearest
|
||||
// ancestor 'table' box, then append a string containing a single U+000A
|
||||
// LF code point to items.
|
||||
Display::TableRow => {
|
||||
if !state.first_table_row {
|
||||
items.push(InnerOrOuterTextItem::Text(String::from(
|
||||
"\u{000A}", /* Line Feed */
|
||||
)));
|
||||
// Make sure we don't add a white-space we removed from the previous node
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
}
|
||||
state.first_table_row = false;
|
||||
state.first_table_cell = true;
|
||||
},
|
||||
// Step 9: If node's used value of 'display' is block-level or 'table-caption',
|
||||
// then append 1 (a required line break count) at the beginning and end of items.
|
||||
Display::Block => {
|
||||
surrounding_line_breaks = 1;
|
||||
},
|
||||
Display::TableCaption => {
|
||||
surrounding_line_breaks = 1;
|
||||
state.within_table_content = true;
|
||||
},
|
||||
Display::InlineFlex | Display::InlineGrid | Display::InlineBlock => {
|
||||
// InlineBlock's are a bit strange, in that they don't produce a Linebreak, yet
|
||||
// disable white space truncation before and after it, making it one of the few
|
||||
// cases where one can have multiple white space characters following one another.
|
||||
if state.did_truncate_trailing_white_space {
|
||||
items.push(InnerOrOuterTextItem::Text(String::from(" ")));
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
state.may_start_with_whitespace = true;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
match node.type_id() {
|
||||
// Step 8: If node is a p element, then append 2 (a required line break count) at
|
||||
// the beginning and end of items.
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLParagraphElement) => {
|
||||
surrounding_line_breaks = 2;
|
||||
},
|
||||
// Option/OptGroup elements should go on separate lines, by treating them like
|
||||
// Block elements we can achieve that.
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLOptionElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLOptGroupElement) => {
|
||||
surrounding_line_breaks = 1;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
if surrounding_line_breaks > 0 {
|
||||
items.push(InnerOrOuterTextItem::RequiredLineBreakCount(
|
||||
surrounding_line_breaks,
|
||||
));
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
state.may_start_with_whitespace = true;
|
||||
}
|
||||
|
||||
match node.type_id() {
|
||||
// Any text/content contained in these elements is ignored.
|
||||
// However we still need to check whether we have to prepend a
|
||||
// space, since for example <span>asd <input> qwe</span> must
|
||||
// product "asd qwe" (note the 2 spaces)
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLImageElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLObjectElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLInputElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement) |
|
||||
LayoutNodeType::Element(LayoutElementType::HTMLMediaElement) => {
|
||||
if display != Display::Block && state.did_truncate_trailing_white_space {
|
||||
items.push(InnerOrOuterTextItem::Text(String::from(" ")));
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
};
|
||||
state.may_start_with_whitespace = false;
|
||||
},
|
||||
_ => {
|
||||
// Now we can finally iterate over all children, appending whatever
|
||||
// they produce to items.
|
||||
for child in node.dom_children() {
|
||||
items.append(&mut rendered_text_collection_steps(child, state));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Depending on the display property we still need to do some
|
||||
// cleanup after rendering all child nodes
|
||||
match display {
|
||||
Display::InlineFlex | Display::InlineGrid | Display::InlineBlock => {
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
state.may_start_with_whitespace = false;
|
||||
},
|
||||
Display::Table => {
|
||||
state.within_table = false;
|
||||
},
|
||||
Display::TableCell | Display::TableCaption => {
|
||||
state.within_table_content = false;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
if surrounding_line_breaks > 0 {
|
||||
items.push(InnerOrOuterTextItem::RequiredLineBreakCount(
|
||||
surrounding_line_breaks,
|
||||
));
|
||||
state.did_truncate_trailing_white_space = false;
|
||||
state.may_start_with_whitespace = true;
|
||||
}
|
||||
},
|
||||
};
|
||||
items
|
||||
}
|
||||
|
||||
pub fn process_text_index_request(_node: OpaqueNode, _point: Point2D<Au>) -> Option<usize> {
|
||||
|
|
|
@ -37,8 +37,8 @@ use layout::flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils, MutableOwne
|
|||
use layout::flow_ref::FlowRef;
|
||||
use layout::incremental::{RelayoutMode, SpecialRestyleDamage};
|
||||
use layout::query::{
|
||||
process_client_rect_query, process_content_box_request, process_content_boxes_request,
|
||||
process_element_inner_text_query, process_offset_parent_query,
|
||||
get_the_text_steps, process_client_rect_query, process_content_box_request,
|
||||
process_content_boxes_request, process_offset_parent_query,
|
||||
process_resolved_font_style_request, process_resolved_style_request,
|
||||
process_scrolling_area_request,
|
||||
};
|
||||
|
@ -325,12 +325,12 @@ impl Layout for LayoutThread {
|
|||
process_client_rect_query(node, root_flow_ref)
|
||||
}
|
||||
|
||||
fn query_element_inner_text(
|
||||
fn query_element_inner_outer_text(
|
||||
&self,
|
||||
node: script_layout_interface::TrustedNodeAddress,
|
||||
) -> String {
|
||||
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||
process_element_inner_text_query(node, &self.indexable_text.borrow())
|
||||
get_the_text_steps(node, &self.indexable_text.borrow())
|
||||
}
|
||||
|
||||
fn query_inner_window_dimension(
|
||||
|
|
|
@ -30,7 +30,7 @@ use ipc_channel::ipc::IpcSender;
|
|||
use layout::context::LayoutContext;
|
||||
use layout::display_list::{DisplayList, WebRenderImageInfo};
|
||||
use layout::query::{
|
||||
process_content_box_request, process_content_boxes_request, process_element_inner_text_query,
|
||||
get_the_text_steps, process_content_box_request, process_content_boxes_request,
|
||||
process_node_geometry_request, process_node_scroll_area_request, process_offset_parent_query,
|
||||
process_resolved_font_style_query, process_resolved_style_request, process_text_index_request,
|
||||
};
|
||||
|
@ -299,12 +299,12 @@ impl Layout for LayoutThread {
|
|||
}
|
||||
|
||||
#[tracing::instrument(skip(self), fields(servo_profiling = true))]
|
||||
fn query_element_inner_text(
|
||||
fn query_element_inner_outer_text(
|
||||
&self,
|
||||
node: script_layout_interface::TrustedNodeAddress,
|
||||
) -> String {
|
||||
let node = unsafe { ServoLayoutNode::new(&node) };
|
||||
process_element_inner_text_query(node)
|
||||
get_the_text_steps(node)
|
||||
}
|
||||
|
||||
fn query_inner_window_dimension(
|
||||
|
|
|
@ -15,6 +15,7 @@ use style_dom::ElementState;
|
|||
|
||||
use crate::dom::activation::Activatable;
|
||||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterData_Binding::CharacterDataMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::{
|
||||
EventHandlerNonNull, OnErrorEventHandlerNonNull,
|
||||
};
|
||||
|
@ -26,6 +27,7 @@ use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
|
|||
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::characterdata::CharacterData;
|
||||
use crate::dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration, CSSStyleOwner};
|
||||
use crate::dom::customelementregistry::CallbackReaction;
|
||||
use crate::dom::document::{Document, FocusType};
|
||||
|
@ -104,6 +106,30 @@ impl HTMLElement {
|
|||
let eventtarget = self.upcast::<EventTarget>();
|
||||
eventtarget.is::<HTMLBodyElement>() || eventtarget.is::<HTMLFrameSetElement>()
|
||||
}
|
||||
|
||||
/// Calls into the layout engine to generate a plain text representation
|
||||
/// of a [`HTMLElement`] as specified when getting the `.innerText` or
|
||||
/// `.outerText` in JavaScript.`
|
||||
///
|
||||
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
|
||||
fn get_inner_outer_text(&self) -> DOMString {
|
||||
let node = self.upcast::<Node>();
|
||||
let window = window_from_node(node);
|
||||
let element = self.as_element();
|
||||
|
||||
// Step 1.
|
||||
let element_not_rendered = !node.is_connected() || !element.has_css_layout_box();
|
||||
if element_not_rendered {
|
||||
return node.GetTextContent().unwrap();
|
||||
}
|
||||
|
||||
window.layout_reflow(QueryMsg::ElementInnerOuterTextQuery);
|
||||
let text = window
|
||||
.layout()
|
||||
.query_element_inner_outer_text(node.to_trusted_node_address());
|
||||
|
||||
DOMString::from(text)
|
||||
}
|
||||
}
|
||||
|
||||
impl HTMLElementMethods for HTMLElement {
|
||||
|
@ -448,71 +474,69 @@ impl HTMLElementMethods for HTMLElement {
|
|||
rect.size.height.to_nearest_px()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute>
|
||||
fn InnerText(&self) -> DOMString {
|
||||
let node = self.upcast::<Node>();
|
||||
let window = window_from_node(node);
|
||||
let element = self.as_element();
|
||||
|
||||
// Step 1.
|
||||
let element_not_rendered = !node.is_connected() || !element.has_css_layout_box();
|
||||
if element_not_rendered {
|
||||
return node.GetTextContent().unwrap();
|
||||
self.get_inner_outer_text()
|
||||
}
|
||||
|
||||
window.layout_reflow(QueryMsg::ElementInnerTextQuery);
|
||||
let text = window
|
||||
.layout()
|
||||
.query_element_inner_text(node.to_trusted_node_address());
|
||||
DOMString::from(text)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute
|
||||
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
|
||||
fn SetInnerText(&self, input: DOMString) {
|
||||
// Step 1.
|
||||
// Step 1: Let fragment be the rendered text fragment for value given element's node
|
||||
// document.
|
||||
let fragment = self.rendered_text_fragment(input);
|
||||
|
||||
// Step 2: Replace all with fragment within element.
|
||||
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>());
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
|
||||
fn GetOuterText(&self) -> Fallible<DOMString> {
|
||||
Ok(self.get_inner_outer_text())
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2>
|
||||
fn SetOuterText(&self, input: DOMString) -> Fallible<()> {
|
||||
// Step 1: If this's parent is null, then throw a "NoModificationAllowedError" DOMException.
|
||||
let Some(parent) = self.upcast::<Node>().GetParentNode() else {
|
||||
return Err(Error::NoModificationAllowed);
|
||||
};
|
||||
|
||||
let node = self.upcast::<Node>();
|
||||
let document = document_from_node(self);
|
||||
|
||||
// Step 2.
|
||||
let fragment = DocumentFragment::new(&document);
|
||||
// Step 2: Let next be this's next sibling.
|
||||
let next = node.GetNextSibling();
|
||||
|
||||
// Step 3. The given value is already named 'input'.
|
||||
// Step 3: Let previous be this's previous sibling.
|
||||
let previous = node.GetPreviousSibling();
|
||||
|
||||
// Step 4.
|
||||
let mut position = input.chars().peekable();
|
||||
// Step 4: Let fragment be the rendered text fragment for the given value given this's node
|
||||
// document.
|
||||
let fragment = self.rendered_text_fragment(input);
|
||||
|
||||
// Step 5.
|
||||
let mut text = String::new();
|
||||
// Step 5: If fragment has no children, then append a new Text node whose data is the empty
|
||||
// string and node document is this's node document to fragment.
|
||||
if fragment.upcast::<Node>().children_count() == 0 {
|
||||
let text_node = Text::new(DOMString::from("".to_owned()), &document);
|
||||
|
||||
// Step 6.
|
||||
while let Some(ch) = position.next() {
|
||||
match ch {
|
||||
'\u{000A}' | '\u{000D}' => {
|
||||
if ch == '\u{000D}' && position.peek() == Some(&'\u{000A}') {
|
||||
// a \r\n pair should only generate one <br>,
|
||||
// so just skip the \r.
|
||||
position.next();
|
||||
fragment.upcast::<Node>().AppendChild(text_node.upcast())?;
|
||||
}
|
||||
|
||||
if !text.is_empty() {
|
||||
append_text_node_to_fragment(&document, &fragment, text);
|
||||
text = String::new();
|
||||
}
|
||||
// Step 6: Replace this with fragment within this's parent.
|
||||
parent.ReplaceChild(fragment.upcast(), node)?;
|
||||
|
||||
let br = HTMLBRElement::new(local_name!("br"), None, &document, None);
|
||||
fragment.upcast::<Node>().AppendChild(br.upcast()).unwrap();
|
||||
},
|
||||
_ => {
|
||||
text.push(ch);
|
||||
},
|
||||
// Step 7: If next is non-null and next's previous sibling is a Text node, then merge with
|
||||
// the next text node given next's previous sibling.
|
||||
if let Some(next_sibling) = next {
|
||||
if let Some(node) = next_sibling.GetPreviousSibling() {
|
||||
Self::merge_with_the_next_text_node(node);
|
||||
}
|
||||
}
|
||||
|
||||
if !text.is_empty() {
|
||||
append_text_node_to_fragment(&document, &fragment, text);
|
||||
}
|
||||
// Step 8: If previous is a Text node, then merge with the next text node given previous.
|
||||
previous.map(Self::merge_with_the_next_text_node);
|
||||
|
||||
// Step 7.
|
||||
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-translate
|
||||
|
@ -897,6 +921,88 @@ impl HTMLElement {
|
|||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#rendered-text-fragment>
|
||||
fn rendered_text_fragment(&self, input: DOMString) -> DomRoot<DocumentFragment> {
|
||||
// Step 1: Let fragment be a new DocumentFragment whose node document is document.
|
||||
let document = document_from_node(self);
|
||||
let fragment = DocumentFragment::new(&document);
|
||||
|
||||
// Step 2: Let position be a position variable for input, initially pointing at the start
|
||||
// of input.
|
||||
let mut position = input.chars().peekable();
|
||||
|
||||
// Step 3: Let text be the empty string.
|
||||
let mut text = String::new();
|
||||
|
||||
// Step 4
|
||||
while let Some(ch) = position.next() {
|
||||
match ch {
|
||||
// While position is not past the end of input, and the code point at position is
|
||||
// either U+000A LF or U+000D CR:
|
||||
'\u{000A}' | '\u{000D}' => {
|
||||
if ch == '\u{000D}' && position.peek() == Some(&'\u{000A}') {
|
||||
// a \r\n pair should only generate one <br>,
|
||||
// so just skip the \r.
|
||||
position.next();
|
||||
}
|
||||
|
||||
if !text.is_empty() {
|
||||
append_text_node_to_fragment(&document, &fragment, text);
|
||||
text = String::new();
|
||||
}
|
||||
|
||||
let br = HTMLBRElement::new(local_name!("br"), None, &document, None);
|
||||
fragment.upcast::<Node>().AppendChild(br.upcast()).unwrap();
|
||||
},
|
||||
_ => {
|
||||
// Collect a sequence of code points that are not U+000A LF or U+000D CR from
|
||||
// input given position, and set text to the result.
|
||||
text.push(ch);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// If text is not the empty string, then append a new Text node whose data is text and node
|
||||
// document is document to fragment.
|
||||
if !text.is_empty() {
|
||||
append_text_node_to_fragment(&document, &fragment, text);
|
||||
}
|
||||
|
||||
fragment
|
||||
}
|
||||
|
||||
/// Checks whether a given [`DomRoot<Node>`] and its next sibling are
|
||||
/// of type [`Text`], and if so merges them into a single [`Text`]
|
||||
/// node.
|
||||
///
|
||||
/// <https://html.spec.whatwg.org/multipage/#merge-with-the-next-text-node>
|
||||
fn merge_with_the_next_text_node(node: DomRoot<Node>) {
|
||||
// Make sure node is a Text node
|
||||
if !node.is::<Text>() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1: Let next be node's next sibling.
|
||||
let next = match node.GetNextSibling() {
|
||||
Some(next) => next,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Step 2: If next is not a Text node, then return.
|
||||
if !next.is::<Text>() {
|
||||
return;
|
||||
}
|
||||
// Step 3: Replace data with node, node's data's length, 0, and next's data.
|
||||
let node_chars = node.downcast::<CharacterData>().expect("Node is Text");
|
||||
let next_chars = next.downcast::<CharacterData>().expect("Next node is Text");
|
||||
node_chars
|
||||
.ReplaceData(node_chars.Length(), 0, next_chars.Data())
|
||||
.expect("Got chars from Text");
|
||||
|
||||
// Step 4:Remove next.
|
||||
next.remove_self();
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLElement {
|
||||
|
|
|
@ -3506,12 +3506,24 @@ impl From<ElementTypeId> for LayoutElementType {
|
|||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement) => {
|
||||
LayoutElementType::HTMLInputElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptGroupElement) => {
|
||||
LayoutElementType::HTMLOptGroupElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement) => {
|
||||
LayoutElementType::HTMLOptionElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement) => {
|
||||
LayoutElementType::HTMLObjectElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLParagraphElement) => {
|
||||
LayoutElementType::HTMLParagraphElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLPreElement) => {
|
||||
LayoutElementType::HTMLPreElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement) => {
|
||||
LayoutElementType::HTMLSelectElement
|
||||
},
|
||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableCellElement) => {
|
||||
LayoutElementType::HTMLTableCellElement
|
||||
},
|
||||
|
|
|
@ -48,7 +48,8 @@ interface HTMLElement : Element {
|
|||
// attribute boolean spellcheck;
|
||||
// void forceSpellCheck();
|
||||
|
||||
attribute [LegacyNullToEmptyString] DOMString innerText;
|
||||
[CEReactions] attribute [LegacyNullToEmptyString] DOMString innerText;
|
||||
[CEReactions, Throws] attribute [LegacyNullToEmptyString] DOMString outerText;
|
||||
|
||||
[Throws] ElementInternals attachInternals();
|
||||
|
||||
|
|
|
@ -2737,7 +2737,7 @@ fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &Reflow
|
|||
QueryMsg::OffsetParentQuery => "\tOffsetParentQuery",
|
||||
QueryMsg::StyleQuery => "\tStyleQuery",
|
||||
QueryMsg::TextIndexQuery => "\tTextIndexQuery",
|
||||
QueryMsg::ElementInnerTextQuery => "\tElementInnerTextQuery",
|
||||
QueryMsg::ElementInnerOuterTextQuery => "\tElementInnerOuterTextQuery",
|
||||
QueryMsg::InnerWindowDimensionsQuery => "\tInnerWindowDimensionsQuery",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -104,7 +104,11 @@ pub enum LayoutElementType {
|
|||
HTMLInputElement,
|
||||
HTMLMediaElement,
|
||||
HTMLObjectElement,
|
||||
HTMLOptGroupElement,
|
||||
HTMLOptionElement,
|
||||
HTMLParagraphElement,
|
||||
HTMLPreElement,
|
||||
HTMLSelectElement,
|
||||
HTMLTableCellElement,
|
||||
HTMLTableColElement,
|
||||
HTMLTableElement,
|
||||
|
@ -239,7 +243,7 @@ pub trait Layout {
|
|||
fn query_content_box(&self, node: OpaqueNode) -> Option<Rect<Au>>;
|
||||
fn query_content_boxes(&self, node: OpaqueNode) -> Vec<Rect<Au>>;
|
||||
fn query_client_rect(&self, node: OpaqueNode) -> Rect<i32>;
|
||||
fn query_element_inner_text(&self, node: TrustedNodeAddress) -> String;
|
||||
fn query_element_inner_outer_text(&self, node: TrustedNodeAddress) -> String;
|
||||
fn query_inner_window_dimension(
|
||||
&self,
|
||||
context: BrowsingContextId,
|
||||
|
@ -305,7 +309,7 @@ pub enum QueryMsg {
|
|||
NodesFromPointQuery,
|
||||
ResolvedStyleQuery,
|
||||
StyleQuery,
|
||||
ElementInnerTextQuery,
|
||||
ElementInnerOuterTextQuery,
|
||||
ResolvedFontStyleQuery,
|
||||
InnerWindowDimensionsQuery,
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ impl ReflowGoal {
|
|||
match *self {
|
||||
ReflowGoal::Full | ReflowGoal::TickAnimations | ReflowGoal::UpdateScrollNode(_) => true,
|
||||
ReflowGoal::LayoutQuery(ref querymsg) => match *querymsg {
|
||||
QueryMsg::ElementInnerTextQuery |
|
||||
QueryMsg::ElementInnerOuterTextQuery |
|
||||
QueryMsg::InnerWindowDimensionsQuery |
|
||||
QueryMsg::NodesFromPointQuery |
|
||||
QueryMsg::ResolvedStyleQuery |
|
||||
|
@ -353,7 +357,7 @@ impl ReflowGoal {
|
|||
ReflowGoal::LayoutQuery(ref querymsg) => match *querymsg {
|
||||
QueryMsg::NodesFromPointQuery |
|
||||
QueryMsg::TextIndexQuery |
|
||||
QueryMsg::ElementInnerTextQuery => true,
|
||||
QueryMsg::ElementInnerOuterTextQuery => true,
|
||||
QueryMsg::ContentBox |
|
||||
QueryMsg::ContentBoxes |
|
||||
QueryMsg::ClientRectQuery |
|
||||
|
|
|
@ -36,12 +36,6 @@
|
|||
[spellcheck on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute]
|
||||
expected: FAIL
|
||||
|
||||
[innerText on HTMLElement must enqueue a disconnected reaction]
|
||||
expected: FAIL
|
||||
|
||||
[outerText on HTMLElement must enqueue a disconnected reaction]
|
||||
expected: FAIL
|
||||
|
||||
[popover on HTMLElement must enqueue an attributeChanged reaction when adding popover content attribute]
|
||||
expected: PRECONDITION_FAILED
|
||||
|
||||
|
|
|
@ -1,21 +1,3 @@
|
|||
[dynamic-getter.html]
|
||||
[text-transform applied to child element ("<div id='target'><div id='child'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform applied to parent element ("<div id='parent'><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display: none applied to child element ("<div id='target'>abc<div id='child'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[display: none applied to parent element ("<div id='parent'>invisible<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[insert node into sub-tree ("<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[remove node from sub-tree ("<div id='target'>abc<div id='remove'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[insert whole sub-tree ("<div id='target'>")]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[getter-first-letter-marker-multicol.html]
|
||||
[Test innerText/outerText for a combination of a list item with ::first-letter in multicol]
|
||||
expected: FAIL
|
|
@ -1,106 +1,10 @@
|
|||
[getter.html]
|
||||
[Simplest possible test ("<div>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace removed ("<div> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace removed ("<div>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace compressed ("<div>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n converted to space ("<div>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to space ("<div>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t converted to space ("<div>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace before hard line break removed ("<div>abc <br>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace after hard line break removed ("<div>abc<br> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<pre> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<pre>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<pre>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<pre>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<pre>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<pre>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Two <pre> siblings ("<div><pre>abc</pre><pre>def</pre>")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<div style='white-space:pre'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<div style='white-space:pre'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<div style='white-space:pre'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<div style='white-space:pre'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<div style='white-space:pre'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<div style='white-space:pre'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<span style='white-space:pre'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<span style='white-space:pre'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<span style='white-space:pre'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<span style='white-space:pre'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<span style='white-space:pre'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<span style='white-space:pre'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace removed ("<div style='white-space:pre-line'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace removed ("<div style='white-space:pre-line'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace collapsed ("<div style='white-space:pre-line'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<div style='white-space:pre-line'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<div style='white-space:pre-line'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t converted to space ("<div style='white-space:pre-line'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries ("<div><span>abc </span> def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -119,39 +23,12 @@
|
|||
[Trailing space at end of inline-block should be collapsed ("<div>abc <span style='display:inline-block'> def </span> ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between <input> and block should be collapsed ("<div><input> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between inline-block and block should be collapsed ("<div><span style='inline-block'></span> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around <img> should not be collapsed ("<div>abc <img> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around <img> should not be collapsed ("<div>abc <img width=1 height=1> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitesapce should not be collapsed ("<div><img> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitesapce should not be collapsed ("<div>abc <img>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around empty span should be collapsed ("<div>abc <b></b> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around empty spans should be collapsed ("<div>abc <b><i></i></b> def")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> should not collapse following space ("<div><canvas></canvas> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Replaced element <img> with display:block should be treated as block-level ("<div>abc <img style='display:block'> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Replaced element <canvas> with display:block should be treated as block-level ("<div>abc <canvas style='display:block'></canvas> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Soft line breaks ignored ("<div style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -212,48 +89,12 @@
|
|||
[::first-letter float ignored ("<div class='first-letter-float' style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[ preserved ("<div> ")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none container ("<div style='display:none'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[No whitespace compression in display:none container ("<div style='display:none'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[No removal of leading/trailing whitespace in display:none container ("<div style='display:none'> abc def ")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none child not rendered ("<div>123<span style='display:none'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none container with non-display-none target child ("<div style='display:none'><span id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[non-display-none child of svg ("<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none child of svg ("<div style='display:none' id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[child of display:none child of svg ("<div style='display:none'><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden container ("<div style='visibility:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden child not rendered ("<div>123<span style='visibility:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:visible child rendered ("<div style='visibility:hidden'>123<span style='visibility:visible'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row-group ("<table><tbody style='visibility:collapse'><tr><td>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row ("<table><tr style='visibility:collapse'><td>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse cell ("<table><tr><td style='visibility:collapse'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -263,117 +104,33 @@
|
|||
[visibility:collapse row with visible cell ("<table><tr style='visibility:collapse'><td style='visibility:visible'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse honored on flex item ("<div style='display:flex'><span style='visibility:collapse'>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse honored on grid item ("<div style='display:grid'><span style='visibility:collapse'>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[opacity:0 container ("<div style='opacity:0'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace compression in opacity:0 container ("<div style='opacity:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[Remove leading/trailing whitespace in opacity:0 container ("<div style='opacity:0'> abc def ")]
|
||||
expected: FAIL
|
||||
|
||||
[opacity:0 child rendered ("<div>123<span style='opacity:0'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Generated content not included ("<div class='before'>")]
|
||||
expected: FAIL
|
||||
|
||||
[Generated content on child not included ("<div><div class='before'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<button> contents preserved ("<button>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> contents preserved ("<fieldset>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> <legend> contents preserved ("<fieldset><legend>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<input> contents ignored ("<input type='text' value='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<textarea> contents ignored ("<textarea>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<iframe>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<iframe><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> subdocument ignored ("<iframe src='data:text/html,abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ignored ("<audio style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:block'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:none'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ignored ("<video>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ok for element not being rendered ("<video style='display:block'><source id='target' class='poke' style='display:block'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ok for element not being rendered ("<video style='display:block'><source id='target' class='poke' style='display:none'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> contents ignored ("<canvas>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas><div id='target'> contents ok for element not being rendered ("<canvas><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> alt text ignored ("<img alt='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> contents ignored ("<img src='about:blank' class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg> text contents preserved ("<div><svg><text>abc</text></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg><defs> text contents ignored ("<div><svg><defs><text>abc</text></defs></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg> non-rendered text ignored ("<div><svg><stop>abc</stop></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<foreignObject> contents preserved ("<svg><foreignObject><span id='target'>abc</span></foreignObject></svg>")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of options preserved ("<select size='1'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of options preserved ("<select size='2'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of target option preserved ("<select size='1'><option id='target'>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of target option preserved ("<select size='2'><option id='target'>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <select> ("<div>a<select></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <optgroup> in <select> ("<div>a<select><optgroup></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <option> in <select> ("<div>a<select><option></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<select> containing text node child ("<select class='poke'></select>")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -398,96 +155,21 @@
|
|||
[<option> in <div> ("<div>a<option>123</option>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<button> contents preserved ("<div><button>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> contents preserved ("<div><fieldset>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> <legend> contents preserved ("<div><fieldset><legend>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<input> contents ignored ("<div><input type='text' value='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<textarea> contents ignored ("<div><textarea>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of options preserved ("<div><select size='1'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of options preserved ("<div><select size='2'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<div><iframe>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[ <iframe> subdocument ignored ("<div><iframe src='data:text/html,abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ignored ("<div><audio>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ignored ("<div><video>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> contents ignored ("<div><canvas>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> alt text ignored ("<div><img alt='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline at block boundary ("<div>123<div>abc</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline at display:block boundary ("<div>123<span style='display:block'>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Empty block induces single line break ("<div>abc<div></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Consecutive empty blocks ignored ("<div>abc<div></div><div></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> alone ("<div><p>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> followed by only collapsible whitespace ("<div><p>abc</p> ")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> preceded by only collapsible whitespace ("<div> <p>abc</p>")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s ("<div><p>abc<p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s separated only by collapsible whitespace ("<div><p>abc</p> <p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s separated only by empty block ("<div><p>abc</p><div></div><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank lines between <p>s separated by non-empty block ("<div><p>abc</p><div>123</div><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank lines around a <p> in its own block ("<div>abc<div><p>123</p></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line before <p> ("<div>abc<p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line after <p> ("<div><p>abc</p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[One blank line between <p>s, ignoring empty <p>s ("<div><p>abc<p></p><p></p><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Invisible <p> doesn't induce extra line breaks ("<div style='visibility:hidden'><p><span style='visibility:visible'>abc</span></p>\\n<div style='visibility:visible'>def</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <div> with margin ("<div>abc<div style='margin:2em'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No newlines at display:inline-block boundary ("<div>123<span style='display:inline-block'>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -497,24 +179,6 @@
|
|||
[Blank lines around <p> even without margin ("<div>123<p style='margin:0px'>abc</p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h1> ("<div>123<h1>abc</h1>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h2> ("<div>123<h2>abc</h2>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h3> ("<div>123<h3>abc</h3>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h4> ("<div>123<h4>abc</h4>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h5> ("<div>123<h5>abc</h5>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h6> ("<div>123<h6>abc</h6>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<span> boundaries are irrelevant ("<div>123<span>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -542,9 +206,6 @@
|
|||
[<code> gets no special treatment ("<div>123<code>abc</code>def")]
|
||||
expected: FAIL
|
||||
|
||||
[soft hyphen preserved ("<div>abc­def")]
|
||||
expected: FAIL
|
||||
|
||||
[soft hyphen preserved ("<div style='width:0'>abc­def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -569,9 +230,6 @@
|
|||
[Tab-separated table cells in a border-collapse table ("<div><table style='border-collapse:collapse'><tr><td>abc<td>def</table>")]
|
||||
expected: FAIL
|
||||
|
||||
[tfoot not reordered ("<div><table><tfoot>x</tfoot><tbody>y</tbody></table>")]
|
||||
expected: FAIL
|
||||
|
||||
[ ("<table><tfoot><tr><td>footer</tfoot><thead><tr><td style='visibility:collapse'>thead</thead><tbody><tr><td>tbody</tbody></table>")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -611,27 +269,6 @@
|
|||
[display:table-cell on the element itself ("<div style='display:table-cell'>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:table-caption on the element itself ("<div style='display:table-caption'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<ol> list items get no special treatment ("<div><ol><li>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<ul> list items get no special treatment ("<div><ul><li>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <script> is rendered ("<div><script style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <style> is rendered ("<div><style style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <noscript> is not rendered (it's not parsed!) ("<div><noscript style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <template> contents are not rendered (the contents are in a different document) ("<div><template style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> induces line break ("<div>abc<br>def")]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -641,117 +278,30 @@
|
|||
[<br> content ignored ("<div><br class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr> induces line break ("<div>abc<hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr><hr> induces just one line break ("<div>abc<hr><hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr><hr><hr> induces just one line break ("<div>abc<hr><hr><hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr> content rendered ("<div><hr class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[comment ignored ("<div>abc<!--comment-->def")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> ("<br>")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <p> ("<p>")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <div> ("<div>")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform is applied ("<div><div style='text-transform:uppercase'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform handles es-zet ("<div><div style='text-transform:uppercase'>Maß")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform handles Turkish casing ("<div><div lang='tr' style='text-transform:uppercase'>i ı")]
|
||||
expected: FAIL
|
||||
|
||||
[block-in-inline doesn't add unnecessary newlines ("<div>abc<span>123<div>456</div>789</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[floats induce a block boundary ("<div>abc<div style='float:left'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[floats induce a block boundary ("<div>abc<span style='float:left'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[float on the element itself ("<div style='float:left'>123")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute induces a block boundary ("<div>abc<div style='position:absolute'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute induces a block boundary ("<div>abc<span style='position:absolute'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute on the element itself ("<div style='position:absolute'>123")]
|
||||
expected: FAIL
|
||||
|
||||
[position:relative has no effect ("<div>abc<div style='position:relative'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:relative has no effect ("<div>abc<span style='position:relative'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored ("<div style='overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored even with zero width ("<div style='width:0; overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored even with zero height ("<div style='height:0; overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-overflow:ellipsis ignored ("<div style='width:0; overflow:hidden; text-overflow:ellipsis'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[innerText not supported on SVG elements ("<svg>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[innerText not supported on MathML elements ("<math>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<rt> and no <rp> ("<div><ruby>abc<rt>def</rt></ruby>")]
|
||||
expected: FAIL
|
||||
|
||||
[<rp> ("<div><ruby>abc<rp>(</rp><rt>def</rt><rp>)</rp></ruby>")]
|
||||
expected: FAIL
|
||||
|
||||
[Lone <rp> ("<div><rp>abc</rp>")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden <rp> ("<div><rp style='visibility:hidden'>abc</rp>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <rp> ("<div><rp style='display:block'>abc</rp>def")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <rp> with whitespace ("<div><rp style='display:block'> abc </rp>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<rp> in a <select> ("<div><select class='poke-rp'></select>")]
|
||||
expected: FAIL
|
||||
|
||||
[CSS 'order' property ignored ("<div style='display:flex'><div style='order:1'>1</div><div>2</div></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Flex items blockified ("<div style='display:flex'><span>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents container ("<div style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents container ("<div><div style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents rendered ("<div>123<span style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[multiple-text-nodes.window.html]
|
||||
[Ensure multiple text nodes get rendered properly]
|
||||
expected: FAIL
|
|
@ -1,123 +0,0 @@
|
|||
[outertext-setter.html]
|
||||
[Replacing a node and merging with the previous text node]
|
||||
expected: FAIL
|
||||
|
||||
[Replacing a node and merging with the following text node]
|
||||
expected: FAIL
|
||||
|
||||
[Replacing a node and merging with the previous and following text node]
|
||||
expected: FAIL
|
||||
|
||||
[Only merges with the previous and following text nodes, does not completely normalize]
|
||||
expected: FAIL
|
||||
|
||||
[Removing a node]
|
||||
expected: FAIL
|
||||
|
||||
[Detached node]
|
||||
expected: FAIL
|
||||
|
||||
[Simplest possible test]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in non-white-space:pre elements]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in <pre> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in <textarea> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in non-white-space:pre elements]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in <pre> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newline/CR pair converts to <br> in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[Newline/newline pair converts to two <br>s in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CR/CR pair converts to two <br>s in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[< preserved]
|
||||
expected: FAIL
|
||||
|
||||
[> preserved]
|
||||
expected: FAIL
|
||||
|
||||
[& preserved]
|
||||
expected: FAIL
|
||||
|
||||
[" preserved]
|
||||
expected: FAIL
|
||||
|
||||
[' preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Null characters preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Tabs preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace not compressed]
|
||||
expected: FAIL
|
||||
|
||||
[Existing text deleted]
|
||||
expected: FAIL
|
||||
|
||||
[Existing <br> deleted]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning the empty string]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning null]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning undefined]
|
||||
expected: FAIL
|
||||
|
||||
[Start with CR]
|
||||
expected: FAIL
|
||||
|
||||
[Start with LF]
|
||||
expected: FAIL
|
||||
|
||||
[Start with CRLF]
|
||||
expected: FAIL
|
||||
|
||||
[End with CR]
|
||||
expected: FAIL
|
||||
|
||||
[End with LF]
|
||||
expected: FAIL
|
||||
|
||||
[End with CRLF]
|
||||
expected: FAIL
|
||||
|
||||
[Empty string]
|
||||
expected: FAIL
|
||||
|
||||
[Empty string with surrounding text nodes]
|
||||
expected: FAIL
|
||||
|
||||
[Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes]
|
||||
expected: FAIL
|
|
@ -4518,12 +4518,6 @@
|
|||
[HTMLSourceElement interface: document.createElement("source") must inherit property "height" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: attribute outerText]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "outerText" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: document.createElement("iframe") must inherit property "allow" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -23,12 +23,6 @@
|
|||
[spellcheck on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute]
|
||||
expected: FAIL
|
||||
|
||||
[innerText on HTMLElement must enqueue a disconnected reaction]
|
||||
expected: FAIL
|
||||
|
||||
[outerText on HTMLElement must enqueue a disconnected reaction]
|
||||
expected: FAIL
|
||||
|
||||
[popover on HTMLElement must enqueue an attributeChanged reaction when adding popover content attribute]
|
||||
expected: PRECONDITION_FAILED
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[iso2022jp-encode-form-errors-stateful.html]
|
||||
[Form submission using ISO-2022-JP correctly replaces unencodables]
|
||||
expected: FAIL
|
|
@ -1,21 +0,0 @@
|
|||
[dynamic-getter.html]
|
||||
[text-transform applied to child element ("<div id='target'><div id='child'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform applied to parent element ("<div id='parent'><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display: none applied to child element ("<div id='target'>abc<div id='child'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[display: none applied to parent element ("<div id='parent'>invisible<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[insert node into sub-tree ("<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[remove node from sub-tree ("<div id='target'>abc<div id='remove'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[insert whole sub-tree ("<div id='target'>")]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[getter-first-letter-marker-multicol.html]
|
||||
[Test innerText/outerText for a combination of a list item with ::first-letter in multicol]
|
||||
expected: FAIL
|
|
@ -1,801 +1,24 @@
|
|||
[getter.html]
|
||||
[Simplest possible test ("<div>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace removed ("<div> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace removed ("<div>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace compressed ("<div>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n converted to space ("<div>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to space ("<div>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t converted to space ("<div>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace before hard line break removed ("<div>abc <br>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace after hard line break removed ("<div>abc<br> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<pre> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<pre>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<pre>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<pre>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<pre>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<pre>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Two <pre> siblings ("<div><pre>abc</pre><pre>def</pre>")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<div style='white-space:pre'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<div style='white-space:pre'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<div style='white-space:pre'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<div style='white-space:pre'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<div style='white-space:pre'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<div style='white-space:pre'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved ("<span style='white-space:pre'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved ("<span style='white-space:pre'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace preserved ("<span style='white-space:pre'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<span style='white-space:pre'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<span style='white-space:pre'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t preserved ("<span style='white-space:pre'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace removed ("<div style='white-space:pre-line'> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace removed ("<div style='white-space:pre-line'>abc ")]
|
||||
expected: FAIL
|
||||
|
||||
[Internal whitespace collapsed ("<div style='white-space:pre-line'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[\\n preserved ("<div style='white-space:pre-line'>abc\\ndef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\r converted to newline ("<div style='white-space:pre-line'>abc\\rdef")]
|
||||
expected: FAIL
|
||||
|
||||
[\\t converted to space ("<div style='white-space:pre-line'>abc\\tdef")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries ("<div><span>abc </span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries ("<div><span>abc </span><span></span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries ("<div><span>abc </span><span style='white-space:pre'></span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around <input> should not be collapsed ("<div>abc <input> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around inline-block should not be collapsed ("<div>abc <span style='display:inline-block'></span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing space at end of inline-block should be collapsed ("<div>abc <span style='display:inline-block'> def </span> ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between <input> and block should be collapsed ("<div><input> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between inline-block and block should be collapsed ("<div><span style='inline-block'></span> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around <img> should not be collapsed ("<div>abc <img> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around <img> should not be collapsed ("<div>abc <img width=1 height=1> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitesapce should not be collapsed ("<div><img> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitesapce should not be collapsed ("<div>abc <img>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around empty span should be collapsed ("<div>abc <b></b> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around empty spans should be collapsed ("<div>abc <b><i></i></b> def")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> should not collapse following space ("<div><canvas></canvas> abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Replaced element <img> with display:block should be treated as block-level ("<div>abc <img style='display:block'> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Replaced element <canvas> with display:block should be treated as block-level ("<div>abc <canvas style='display:block'></canvas> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Soft line breaks ignored ("<div style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[Soft line break at hyphen ignored ("<div style='width:0'>abc-def")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace text node preserved ("<div style='width:0'><span>abc</span> <span>def</span>")]
|
||||
expected: FAIL
|
||||
|
||||
[Soft breaks ignored in presence of word-break:break-word ("<div style='width:1px; word-break:break-word'>Hello Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Element boundaries ignored for soft break handling (1) ("<div style='width:1px; word-break:break-word'><x>Hello</x> <x>Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries at soft break (1) ("<div style='width:1px; word-break:break-word'><x>Hello</x> <x> Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Element boundaries ignored for soft break handling (2) ("<div style='width:1px; word-break:break-word'><x>Hello</x><x> Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries at soft break (2) ("<div style='width:1px; word-break:break-word'><x>Hello </x> <x>Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Element boundaries ignored for soft break handling (3) ("<div style='width:1px; word-break:break-word'><x>Hello </x><x>Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries at soft break (3) ("<div style='width:1px; word-break:break-word'><x>Hello </x><x> Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace collapses across element boundaries at soft break (4) ("<div style='width:1px; word-break:break-word'><x>Hello </x> <x> Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Element boundaries ignored for soft break handling (4) ("<div style='width:1px; word-break:break-word'><x>Hello</x> Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Element boundaries ignored for soft break handling (5) ("<div style='width:1px; word-break:break-word'><x>Hello </x>Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Soft breaks ignored, text-transform applied ("<div style='width:1px; word-break:break-word; text-transform:uppercase'>Hello Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> returned as newline, following space collapsed ("<div style='width:1px; word-break:break-word'>Hello<br> Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> returned as newline, preceding space collapsed ("<div style='width:1px; word-break:break-word'>Hello <br>Kitty</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> returned as newline, adjacent spaces collapsed across element boundaries ("<div style='width:1px; word-break:break-word'><x>Hello </x> <br> <x> Kitty</x></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[::first-line styles applied ("<div class='first-line-uppercase' style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[::first-letter styles applied ("<div class='first-letter-uppercase' style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[::first-letter float ignored ("<div class='first-letter-float' style='width:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[ preserved ("<div> ")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none container ("<div style='display:none'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[No whitespace compression in display:none container ("<div style='display:none'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[No removal of leading/trailing whitespace in display:none container ("<div style='display:none'> abc def ")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none child not rendered ("<div>123<span style='display:none'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none container with non-display-none target child ("<div style='display:none'><span id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[non-display-none child of svg ("<div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:none child of svg ("<div style='display:none' id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[child of display:none child of svg ("<div style='display:none'><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden container ("<div style='visibility:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden child not rendered ("<div>123<span style='visibility:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:visible child rendered ("<div style='visibility:hidden'>123<span style='visibility:visible'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row-group ("<table><tbody style='visibility:collapse'><tr><td>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row ("<table><tr style='visibility:collapse'><td>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse cell ("<table><tr><td style='visibility:collapse'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row-group with visible cell ("<table><tbody style='visibility:collapse'><tr><td style='visibility:visible'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse row with visible cell ("<table><tr style='visibility:collapse'><td style='visibility:visible'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse honored on flex item ("<div style='display:flex'><span style='visibility:collapse'>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:collapse honored on grid item ("<div style='display:grid'><span style='visibility:collapse'>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[opacity:0 container ("<div style='opacity:0'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace compression in opacity:0 container ("<div style='opacity:0'>abc def")]
|
||||
expected: FAIL
|
||||
|
||||
[Remove leading/trailing whitespace in opacity:0 container ("<div style='opacity:0'> abc def ")]
|
||||
expected: FAIL
|
||||
|
||||
[opacity:0 child rendered ("<div>123<span style='opacity:0'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[Generated content not included ("<div class='before'>")]
|
||||
expected: FAIL
|
||||
|
||||
[Generated content on child not included ("<div><div class='before'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<button> contents preserved ("<button>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> contents preserved ("<fieldset>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> <legend> contents preserved ("<fieldset><legend>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<input> contents ignored ("<input type='text' value='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<textarea> contents ignored ("<textarea>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<iframe>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<iframe><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> subdocument ignored ("<iframe src='data:text/html,abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ignored ("<audio style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:block'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ok for element not being rendered ("<audio style='display:block'><source id='target' class='poke' style='display:none'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ignored ("<video>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ok for element not being rendered ("<video style='display:block'><source id='target' class='poke' style='display:block'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ok for element not being rendered ("<video style='display:block'><source id='target' class='poke' style='display:none'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> contents ignored ("<canvas>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas><div id='target'> contents ok for element not being rendered ("<canvas><div id='target'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> alt text ignored ("<img alt='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> contents ignored ("<img src='about:blank' class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg> text contents preserved ("<div><svg><text>abc</text></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg><defs> text contents ignored ("<div><svg><defs><text>abc</text></defs></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<svg> non-rendered text ignored ("<div><svg><stop>abc</stop></svg></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[<foreignObject> contents preserved ("<svg><foreignObject><span id='target'>abc</span></foreignObject></svg>")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of options preserved ("<select size='1'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of options preserved ("<select size='2'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of target option preserved ("<select size='1'><option id='target'>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of target option preserved ("<select size='2'><option id='target'>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <select> ("<div>a<select></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <optgroup> in <select> ("<div>a<select><optgroup></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <option> in <select> ("<div>a<select><option></select>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<select> containing text node child ("<select class='poke'></select>")]
|
||||
expected: FAIL
|
||||
|
||||
[<optgroup> containing <optgroup> ("<select><optgroup class='poke-optgroup'></select>")]
|
||||
expected: FAIL
|
||||
|
||||
[<optgroup> containing <option> ("<select><optgroup><option>abc</select>")]
|
||||
expected: FAIL
|
||||
|
||||
[<div> in <option> ("<select><option class='poke-div'>123</select>")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <optgroup> in <div> ("<div>a<optgroup></optgroup>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<optgroup> in <div> ("<div>a<optgroup>123</optgroup>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <option> in <div> ("<div>a<option></option>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<option> in <div> ("<div>a<option>123</option>bc")]
|
||||
expected: FAIL
|
||||
|
||||
[<button> contents preserved ("<div><button>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> contents preserved ("<div><fieldset>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<fieldset> <legend> contents preserved ("<div><fieldset><legend>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<input> contents ignored ("<div><input type='text' value='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<textarea> contents ignored ("<div><textarea>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='1'> contents of options preserved ("<div><select size='1'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<select size='2'> contents of options preserved ("<div><select size='2'><option>abc</option><option>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe> contents ignored ("<div><iframe>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[ <iframe> subdocument ignored ("<div><iframe src='data:text/html,abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<audio> contents ignored ("<div><audio>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<video> contents ignored ("<div><video>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<canvas> contents ignored ("<div><canvas>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<img> alt text ignored ("<div><img alt='abc'>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline at block boundary ("<div>123<div>abc</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline at display:block boundary ("<div>123<span style='display:block'>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Empty block induces single line break ("<div>abc<div></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Consecutive empty blocks ignored ("<div>abc<div></div><div></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> alone ("<div><p>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> followed by only collapsible whitespace ("<div><p>abc</p> ")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <p> preceded by only collapsible whitespace ("<div> <p>abc</p>")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s ("<div><p>abc<p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s separated only by collapsible whitespace ("<div><p>abc</p> <p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line between consecutive <p>s separated only by empty block ("<div><p>abc</p><div></div><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank lines between <p>s separated by non-empty block ("<div><p>abc</p><div>123</div><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank lines around a <p> in its own block ("<div>abc<div><p>123</p></div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line before <p> ("<div>abc<p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank line after <p> ("<div><p>abc</p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[One blank line between <p>s, ignoring empty <p>s ("<div><p>abc<p></p><p></p><p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Invisible <p> doesn't induce extra line breaks ("<div style='visibility:hidden'><p><span style='visibility:visible'>abc</span></p>\\n<div style='visibility:visible'>def</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <div> with margin ("<div>abc<div style='margin:2em'>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No newlines at display:inline-block boundary ("<div>123<span style='display:inline-block'>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading/trailing space removal at display:inline-block boundary ("<div>123<span style='display:inline-block'> abc </span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Blank lines around <p> even without margin ("<div>123<p style='margin:0px'>abc</p>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h1> ("<div>123<h1>abc</h1>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h2> ("<div>123<h2>abc</h2>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h3> ("<div>123<h3>abc</h3>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h4> ("<div>123<h4>abc</h4>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h5> ("<div>123<h5>abc</h5>def")]
|
||||
expected: FAIL
|
||||
|
||||
[No blank lines around <h6> ("<div>123<h6>abc</h6>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<span> boundaries are irrelevant ("<div>123<span>abc</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<span> boundaries are irrelevant ("<div>123 <span>abc</span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[<span> boundaries are irrelevant ("<div style='width:0'>123 <span>abc</span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[<em> gets no special treatment ("<div>123<em>abc</em>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<b> gets no special treatment ("<div>123<b>abc</b>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<i> gets no special treatment ("<div>123<i>abc</i>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<strong> gets no special treatment ("<div>123<strong>abc</strong>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<tt> gets no special treatment ("<div>123<tt>abc</tt>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<code> gets no special treatment ("<div>123<code>abc</code>def")]
|
||||
expected: FAIL
|
||||
|
||||
[soft hyphen preserved ("<div>abc­def")]
|
||||
expected: FAIL
|
||||
|
||||
[soft hyphen preserved ("<div style='width:0'>abc­def")]
|
||||
expected: FAIL
|
||||
|
||||
[Ignoring non-rendered table whitespace ("<div><table style='white-space:pre'> <td>abc</td> </table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells ("<div><table><tr><td>abc<td>def</table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells including empty cells ("<div><table><tr><td>abc<td><td>def</table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells including trailing empty cells ("<div><table><tr><td>abc<td><td></table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline-separated table rows ("<div><table><tr><td>abc<tr><td>def</table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines around table ("<div>abc<table><td>def</table>ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells in a border-collapse table ("<div><table style='border-collapse:collapse'><tr><td>abc<td>def</table>")]
|
||||
expected: FAIL
|
||||
|
||||
[tfoot not reordered ("<div><table><tfoot>x</tfoot><tbody>y</tbody></table>")]
|
||||
expected: FAIL
|
||||
|
||||
[ ("<table><tfoot><tr><td>footer</tfoot><thead><tr><td style='visibility:collapse'>thead</thead><tbody><tr><td>tbody</tbody></table>")]
|
||||
expected: FAIL
|
||||
|
||||
[No tab on table-cell itself ("<table><tr><td id=target>abc</td><td>def</td>")]
|
||||
expected: FAIL
|
||||
|
||||
[No newline on table-row itself ("<table><tr id=target><td>abc</td><td>def</td></tr><tr id=target><td>ghi</td><td>jkl</td></tr>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline between cells and caption ("<div><table><tr><td>abc<caption>def</caption></table>")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells ("<div><div class='table'><span class='cell'>abc</span>\\n<span class='cell'>def</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline-separated table rows ("<div><div class='table'><span class='row'><span class='cell'>abc</span></span>\\n<span class='row'><span class='cell'>def</span></span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines around table ("<div>abc<div class='table'><span class='cell'>def</span></div>ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Tab-separated table cells ("<div><div class='itable'><span class='cell'>abc</span>\\n<span class='cell'>def</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Newline-separated table rows ("<div><div class='itable'><span class='row'><span class='cell'>abc</span></span>\\n<span class='row'><span class='cell'>def</span></span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[No newlines around inline-table ("<div>abc<div class='itable'><span class='cell'>def</span></div>ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Single newline in two-row inline-table ("<div>abc<div class='itable'><span class='row'><span class='cell'>def</span></span>\\n<span class='row'><span class='cell'>123</span></span></div>ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[display:table-row on the element itself ("<div style='display:table-row'>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:table-cell on the element itself ("<div style='display:table-cell'>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:table-caption on the element itself ("<div style='display:table-caption'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<ol> list items get no special treatment ("<div><ol><li>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<ul> list items get no special treatment ("<div><ul><li>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <script> is rendered ("<div><script style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <style> is rendered ("<div><style style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <noscript> is not rendered (it's not parsed!) ("<div><noscript style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <template> contents are not rendered (the contents are in a different document) ("<div><template style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> induces line break ("<div>abc<br>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> induces line break even at end of block ("<div>abc<br>")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> content ignored ("<div><br class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr> induces line break ("<div>abc<hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr><hr> induces just one line break ("<div>abc<hr><hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr><hr><hr> induces just one line break ("<div>abc<hr><hr><hr>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<hr> content rendered ("<div><hr class='poke'>")]
|
||||
expected: FAIL
|
||||
|
||||
[comment ignored ("<div>abc<!--comment-->def")]
|
||||
expected: FAIL
|
||||
|
||||
[<br> ("<br>")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <p> ("<p>")]
|
||||
expected: FAIL
|
||||
|
||||
[empty <div> ("<div>")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform is applied ("<div><div style='text-transform:uppercase'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform handles es-zet ("<div><div style='text-transform:uppercase'>Maß")]
|
||||
expected: FAIL
|
||||
|
||||
[text-transform handles Turkish casing ("<div><div lang='tr' style='text-transform:uppercase'>i ı")]
|
||||
expected: FAIL
|
||||
|
||||
[block-in-inline doesn't add unnecessary newlines ("<div>abc<span>123<div>456</div>789</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[floats induce a block boundary ("<div>abc<div style='float:left'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[floats induce a block boundary ("<div>abc<span style='float:left'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[float on the element itself ("<div style='float:left'>123")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute induces a block boundary ("<div>abc<div style='position:absolute'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute induces a block boundary ("<div>abc<span style='position:absolute'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:absolute on the element itself ("<div style='position:absolute'>123")]
|
||||
expected: FAIL
|
||||
|
||||
[position:relative has no effect ("<div>abc<div style='position:relative'>123</div>def")]
|
||||
expected: FAIL
|
||||
|
||||
[position:relative has no effect ("<div>abc<span style='position:relative'>123</span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored ("<div style='overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored even with zero width ("<div style='width:0; overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[overflow:hidden ignored even with zero height ("<div style='height:0; overflow:hidden'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[text-overflow:ellipsis ignored ("<div style='width:0; overflow:hidden; text-overflow:ellipsis'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[innerText not supported on SVG elements ("<svg>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[innerText not supported on MathML elements ("<math>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[<rt> and no <rp> ("<div><ruby>abc<rt>def</rt></ruby>")]
|
||||
expected: FAIL
|
||||
|
||||
[<rp> ("<div><ruby>abc<rp>(</rp><rt>def</rt><rp>)</rp></ruby>")]
|
||||
expected: FAIL
|
||||
|
||||
[Lone <rp> ("<div><rp>abc</rp>")]
|
||||
expected: FAIL
|
||||
|
||||
[visibility:hidden <rp> ("<div><rp style='visibility:hidden'>abc</rp>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <rp> ("<div><rp style='display:block'>abc</rp>def")]
|
||||
expected: FAIL
|
||||
|
||||
[display:block <rp> with whitespace ("<div><rp style='display:block'> abc </rp>def")]
|
||||
expected: FAIL
|
||||
|
||||
[<rp> in a <select> ("<div><select class='poke-rp'></select>")]
|
||||
expected: FAIL
|
||||
|
||||
[CSS 'order' property ignored ("<div style='display:flex'><div style='order:1'>1</div><div>2</div></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Flex items blockified ("<div style='display:flex'><span>1</span><span>2</span></div>")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents container ("<div style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents container ("<div><div style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents rendered ("<div>123<span style='display:contents'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents not processed via textContent ("<div style='display:contents'> ")]
|
||||
expected: FAIL
|
||||
|
||||
[display:contents not processed via textContent ("<div><div style='display:contents'> ")]
|
||||
expected: FAIL
|
||||
|
||||
[<object> contents ignored ("<div><object>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[2 blank lines around <p> even when display:block ("<div>123<p style='display:block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[2 blank lines around <p> even when display:inline-block ("<div>123<p style='display:inline-block'>abc")]
|
||||
expected: FAIL
|
||||
|
||||
[unopened <details> ignored ("<div><details><summary>abc</summary>123")]
|
||||
expected: FAIL
|
||||
|
||||
[opened <details> content shown ("<div><details open><summary>abc</summary>123")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around inline-flex should not be collapsed ("<div>abc <span style='display:inline-flex'></span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing space at end of inline-flex should be collapsed ("<div>abc <span style='display:inline-flex'> def </span> ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace around inline-grid should not be collapsed ("<div>abc <span style='display:inline-grid'></span> def")]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing space at end of grid-flex should be collapsed ("<div>abc <span style='display:inline-grid'> def </span> ghi")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between inline-flex and block should be collapsed ("<div><span style='inline-flex'></span> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace between inline-grid and block should be collapsed ("<div><span style='inline-grid'></span> <div>abc</div>")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading/trailing space removal at display:inline-flex boundary ("<div>123<span style='display:inline-flex'> abc </span>def")]
|
||||
expected: FAIL
|
||||
|
||||
[Leading/trailing space removal at display:inline-grid boundary ("<div>123<span style='display:inline-grid'> abc </span>def")]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[multiple-text-nodes.window.html]
|
||||
[Ensure multiple text nodes get rendered properly]
|
||||
expected: FAIL
|
|
@ -1,123 +0,0 @@
|
|||
[outertext-setter.html]
|
||||
[Replacing a node and merging with the previous text node]
|
||||
expected: FAIL
|
||||
|
||||
[Replacing a node and merging with the following text node]
|
||||
expected: FAIL
|
||||
|
||||
[Replacing a node and merging with the previous and following text node]
|
||||
expected: FAIL
|
||||
|
||||
[Only merges with the previous and following text nodes, does not completely normalize]
|
||||
expected: FAIL
|
||||
|
||||
[Removing a node]
|
||||
expected: FAIL
|
||||
|
||||
[Detached node]
|
||||
expected: FAIL
|
||||
|
||||
[Simplest possible test]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in non-white-space:pre elements]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in <pre> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in <textarea> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newlines convert to <br> in white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in non-white-space:pre elements]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in <pre> element]
|
||||
expected: FAIL
|
||||
|
||||
[Newline/CR pair converts to <br> in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[Newline/newline pair converts to two <br>s in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CR/CR pair converts to two <br>s in non-white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[CRs convert to <br> in white-space:pre element]
|
||||
expected: FAIL
|
||||
|
||||
[< preserved]
|
||||
expected: FAIL
|
||||
|
||||
[> preserved]
|
||||
expected: FAIL
|
||||
|
||||
[& preserved]
|
||||
expected: FAIL
|
||||
|
||||
[" preserved]
|
||||
expected: FAIL
|
||||
|
||||
[' preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Null characters preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Tabs preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Leading whitespace preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Trailing whitespace preserved]
|
||||
expected: FAIL
|
||||
|
||||
[Whitespace not compressed]
|
||||
expected: FAIL
|
||||
|
||||
[Existing text deleted]
|
||||
expected: FAIL
|
||||
|
||||
[Existing <br> deleted]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning the empty string]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning null]
|
||||
expected: FAIL
|
||||
|
||||
[Assigning undefined]
|
||||
expected: FAIL
|
||||
|
||||
[Start with CR]
|
||||
expected: FAIL
|
||||
|
||||
[Start with LF]
|
||||
expected: FAIL
|
||||
|
||||
[Start with CRLF]
|
||||
expected: FAIL
|
||||
|
||||
[End with CR]
|
||||
expected: FAIL
|
||||
|
||||
[End with LF]
|
||||
expected: FAIL
|
||||
|
||||
[End with CRLF]
|
||||
expected: FAIL
|
||||
|
||||
[Empty string]
|
||||
expected: FAIL
|
||||
|
||||
[Empty string with surrounding text nodes]
|
||||
expected: FAIL
|
||||
|
||||
[Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes]
|
||||
expected: FAIL
|
|
@ -4245,12 +4245,6 @@
|
|||
[HTMLSourceElement interface: document.createElement("source") must inherit property "height" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: attribute outerText]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLElement interface: document.createElement("noscript") must inherit property "outerText" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLIFrameElement interface: document.createElement("iframe") must inherit property "allow" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[srcdoc-anchor.html]
|
||||
[Verify srcdoc content loads when src is about:srcdoc#foo.]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[srcdoc-attribute-reset.html]
|
||||
[Verify that the frame reloads with empty body after we remove srcdoc.]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue