diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 20c5b0b44d2..aa6a50f0545 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -195,14 +195,17 @@ impl InlineFragmentsAccumulator { mut fragments, enclosing_style } = self; + if let Some(enclosing_style) = enclosing_style { + let frag_len = fragments.len(); + for (idx, frag) in fragments.iter_mut().enumerate() { - match enclosing_style { - Some(enclosing_style) => { - for frag in fragments.iter_mut() { - frag.add_inline_context_style(enclosing_style.clone()); - } + // frag is first inline fragment in the inline node + let is_first = idx == 0; + // frag is the last inline fragment in the inline node + let is_last = idx == frag_len - 1; + + frag.add_inline_context_style(enclosing_style.clone(), is_first, is_last); } - None => {} } fragments } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index dcfc408970c..89b6d743fd1 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -23,6 +23,7 @@ use text; use util::OpaqueNodeMethods; use wrapper::{TLayoutNode, ThreadSafeLayoutNode}; +use geom::num::Zero; use geom::{Point2D, Rect, Size2D}; use gfx::display_list::{BOX_SHADOW_INFLATION_FACTOR, OpaqueNode}; use gfx::text::glyph::CharIndex; @@ -46,7 +47,7 @@ use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; use string_cache::Atom; -use style::properties::{ComputedValues, cascade_anonymous}; +use style::properties::{ComputedValues, cascade_anonymous, make_border}; use style::node::{TElement, TNode}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::computed_values::{clear, mix_blend_mode, overflow_wrap}; @@ -877,11 +878,31 @@ impl Fragment { /// Adds a style to the inline context for this fragment. If the inline /// context doesn't exist yet, it will be created. - pub fn add_inline_context_style(&mut self, style: Arc) { + pub fn add_inline_context_style(&mut self, + style: Arc, + first_frag: bool, + last_frag: bool) { + if self.inline_context.is_none() { self.inline_context = Some(InlineFragmentContext::new()); } - self.inline_context.as_mut().unwrap().styles.push(style.clone()); + let frag_style = if first_frag && last_frag { + style.clone() + } else { + // Set the border width to zero and the border style to none on + // border sides that are not the outermost for a node container. + // Because with multiple inline fragments they don't have interior + // borders separating each other. + let mut border_width = style.logical_border_width(); + if !last_frag { + border_width.set_right(style.writing_mode, Zero::zero()); + } + if !first_frag { + border_width.set_left(style.writing_mode, Zero::zero()); + } + Arc::new(make_border(&*style, border_width)) + }; + self.inline_context.as_mut().unwrap().styles.push(frag_style); } /// Determines which quantities (border/padding/margin/specified) should be included in the diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index 9318aae871f..b9049a0a30c 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -17,6 +17,7 @@ use util::geometry::Au; use url::Url; use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser, DeclarationListParser, parse_important, ToCss}; +use geom::num::Zero; use geom::SideOffsets2D; use values::specified::BorderStyle; @@ -3534,6 +3535,21 @@ pub fn make_inline(style: &ComputedValues) -> ComputedValues { style } +/// Sets `border_${side}_width` to the passed in values. +/// If `border_${side}_width` == 0 also sets `border_${side}_style` = none. +#[inline] +pub fn make_border(style: &ComputedValues, border_width: LogicalMargin) -> ComputedValues { + let mut style = (*style).clone(); + let physical_border = LogicalMargin::to_physical(&border_width, style.writing_mode); + % for side in ["top", "right", "bottom", "left"]: + style.border.make_unique().border_${side}_width = physical_border.${side}; + if physical_border.${side} == Zero::zero() { + style.border.make_unique().border_${side}_style = BorderStyle::none; + } + % endfor + style +} + pub fn is_supported_property(property: &str) -> bool { match property { % for property in SHORTHANDS + LONGHANDS: diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 30296dc44a4..9f25fa7af1d 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -31,6 +31,7 @@ == img_dynamic_remove.html img_dynamic_remove_ref.html == upper_id_attr.html upper_id_attr_ref.html # inline_border_a.html inline_border_b.html +== border_code_tag.html border_code_tag_ref.html == anon_block_inherit_a.html anon_block_inherit_b.html == attr_exists_selector.html attr_exists_selector_ref.html == attr_selector_case_sensitivity.html attr_selector_case_sensitivity_ref.html diff --git a/tests/ref/border_code_tag.html b/tests/ref/border_code_tag.html new file mode 100644 index 00000000000..9e5a6479969 --- /dev/null +++ b/tests/ref/border_code_tag.html @@ -0,0 +1,12 @@ + + + + + +Quotes: "". + + diff --git a/tests/ref/border_code_tag_ref.html b/tests/ref/border_code_tag_ref.html new file mode 100644 index 00000000000..393a96c3723 --- /dev/null +++ b/tests/ref/border_code_tag_ref.html @@ -0,0 +1,12 @@ + + + + + +Quotes: "". + +