--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -578,18 +578,21 @@ public:
float EffectiveTextZoom() const { return mEffectiveTextZoom; }
/**
* Get the minimum font size for the specified language. If aLanguage
* is nullptr, then the document's language is used. This combines
* the language-specific global preference with the per-presentation
* base minimum font size.
*/
- int32_t MinFontSize(nsIAtom *aLanguage) const {
- const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage);
+ int32_t MinFontSize(nsIAtom *aLanguage, bool* aNeedsToCache = nullptr) const {
+ const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage, aNeedsToCache);
+ if (aNeedsToCache && *aNeedsToCache) {
+ return 0;
+ }
return std::max(mBaseMinFontSize, prefs->mMinimumFontSize);
}
/**
* Get the per-presentation base minimum font size. This size is
* independent of the language-specific global preference.
*/
int32_t BaseMinFontSize() const {
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -364,17 +364,17 @@ fuzzy-if(OSX,1,100) fuzzy-if(skiaContent
== mfrac-C-4.html mfrac-C-4-ref.html
fuzzy-if(OSX,1,100) fuzzy-if(skiaContent,1,14) == mfrac-D-1.html mfrac-D-1-ref.html
== mfrac-D-2.html mfrac-D-2-ref.html
== mfrac-D-3.html mfrac-D-3-ref.html
== mfrac-D-4.html mfrac-D-4-ref.html
== mfrac-E-1.html mfrac-E-1-ref.html
test-pref(dom.webcomponents.enabled,true) == shadow-dom-1.html shadow-dom-1-ref.html
pref(font.size.inflation.emPerLine,25) == font-inflation-1.html font-inflation-1-ref.html
-test-pref(font.minimum-size.x-math,40) fails-if(styloVsGecko) == default-font.html default-font-ref.html
+test-pref(font.minimum-size.x-math,40) == default-font.html default-font-ref.html
!= radicalbar-1.html about:blank
!= radicalbar-1a.html about:blank
!= radicalbar-1b.html about:blank
!= radicalbar-1c.html about:blank
!= radicalbar-1d.html about:blank
!= radicalbar-2.html about:blank
!= radicalbar-2a.html about:blank
!= radicalbar-2b.html about:blank
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -2000,16 +2000,36 @@ Gecko_nsStyleFont_FixupNoneGeneric(nsSty
RawGeckoPresContextBorrowed aPresContext)
{
const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage);
nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext,
aFont->mGenericID, defaultVariableFont);
}
void
+Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* aFont,
+ RawGeckoPresContextBorrowed aPresContext)
+{
+ nscoord minFontSize;
+ bool needsCache = false;
+
+ {
+ AutoReadLock guard(*sServoLangFontPrefsLock);
+ minFontSize = aPresContext->MinFontSize(aFont->mLanguage, &needsCache);
+ }
+
+ if (needsCache) {
+ AutoWriteLock guard(*sServoLangFontPrefsLock);
+ minFontSize = aPresContext->MinFontSize(aFont->mLanguage, nullptr);
+ }
+
+ nsRuleNode::ApplyMinFontSize(aFont, aPresContext, minFontSize);
+}
+
+void
FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs)
{
mDefaultVariableSize = prefs.mDefaultVariableFont.size;
mDefaultFixedSize = prefs.mDefaultFixedFont.size;
mDefaultSerifSize = prefs.mDefaultSerifFont.size;
mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -494,16 +494,18 @@ void Gecko_CSSValue_SetPairList(nsCSSVal
void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsIAtom* atom);
void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource);
void Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* font,
RawGeckoPresContextBorrowed pres_context);
+void Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* font,
+ RawGeckoPresContextBorrowed pres_context);
FontSizePrefs Gecko_GetBaseSize(nsIAtom* lang);
struct GeckoFontMetrics
{
nscoord mChSize;
nscoord mXSize;
};
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -438,16 +438,40 @@ nsRuleNode::FixupNoneGeneric(nsFont* aFo
}
}
}
} else {
aFont->fontlist.SetDefaultFontType(eFamily_none);
}
}
+/* static */
+void
+nsRuleNode::ApplyMinFontSize(nsStyleFont* aFont,
+ const nsPresContext* aPresContext,
+ nscoord aMinFontSize)
+{
+ nscoord fontSize = aFont->mSize;
+
+ // enforce the user' specified minimum font-size on the value that we expose
+ // (but don't change font-size:0, since that would unhide hidden text)
+ if (fontSize > 0) {
+ if (aMinFontSize < 0) {
+ aMinFontSize = 0;
+ } else {
+ aMinFontSize = (aMinFontSize * aFont->mMinFontSizeRatio) / 100;
+ }
+ if (fontSize < aMinFontSize && !aPresContext->IsChrome()) {
+ // override the minimum font-size constraint
+ fontSize = aMinFontSize;
+ }
+ }
+ aFont->mFont.size = fontSize;
+}
+
static nsSize CalcViewportUnitsScale(nsPresContext* aPresContext)
{
// The caller is making use of viewport units, so notify the pres context
// that it will need to rebuild the rule tree if the size of the viewport
// changes.
aPresContext->SetUsesViewportUnits(true);
// The default (when we have 'overflow: auto' on the root element, or
@@ -4036,33 +4060,18 @@ nsRuleNode::SetFont(nsPresContext* aPres
&aFont->mScriptUnconstrainedSize,
systemFont, aParentFont->mScriptUnconstrainedSize,
scriptLevelAdjustedUnconstrainedParentSize,
aUsedStartStruct, atRoot, unconstrainedConditions);
}
NS_ASSERTION(aFont->mScriptUnconstrainedSize <= aFont->mSize,
"scriptminsize should never be making things bigger");
- nscoord fontSize = aFont->mSize;
-
- // enforce the user' specified minimum font-size on the value that we expose
- // (but don't change font-size:0, since that would unhide hidden text)
- if (fontSize > 0) {
- nscoord minFontSize = aPresContext->MinFontSize(aFont->mLanguage);
- if (minFontSize < 0) {
- minFontSize = 0;
- } else {
- minFontSize = (minFontSize * aFont->mMinFontSizeRatio) / 100;
- }
- if (fontSize < minFontSize && !aPresContext->IsChrome()) {
- // override the minimum font-size constraint
- fontSize = minFontSize;
- }
- }
- aFont->mFont.size = fontSize;
+ nsRuleNode::ApplyMinFontSize(aFont, aPresContext,
+ aPresContext->MinFontSize(aFont->mLanguage));
// font-size-adjust: number, none, inherit, initial, -moz-system-font
const nsCSSValue* sizeAdjustValue = aRuleData->ValueForFontSizeAdjust();
if (eCSSUnit_System_Font == sizeAdjustValue->GetUnit()) {
aFont->mFont.sizeAdjust = systemFont.sizeAdjust;
} else
SetFactor(*sizeAdjustValue, aFont->mFont.sizeAdjust,
aConditions, aParentFont->mFont.sizeAdjust, -1.0f,
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -815,16 +815,24 @@ public:
* Appropriately add the correct font if we are using DocumentFonts or
* overriding for XUL
*/
static void FixupNoneGeneric(nsFont* aFont,
const nsPresContext* aPresContext,
uint8_t aGenericFontID,
const nsFont* aDefaultVariableFont);
+ /**
+ * For an nsStyleFont with mSize set, apply minimum font size constraints
+ * from preferences, as well as -moz-min-font-size-ratio.
+ */
+ static void ApplyMinFontSize(nsStyleFont* aFont,
+ const nsPresContext* aPresContext,
+ nscoord aMinFontSize);
+
// Transition never returns null; on out of memory it'll just return |this|.
nsRuleNode* Transition(nsIStyleRule* aRule, mozilla::SheetType aLevel,
bool aIsImportantRule);
nsRuleNode* GetParent() const { return mParent; }
bool IsRoot() const { return mParent == nullptr; }
// Return the root of the rule tree that this rule node is in.
nsRuleNode* RuleTree();
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -1300,16 +1300,21 @@ extern "C" {
aSource: *const nsStyleFont);
}
extern "C" {
pub fn Gecko_nsStyleFont_FixupNoneGeneric(font: *mut nsStyleFont,
pres_context:
RawGeckoPresContextBorrowed);
}
extern "C" {
+ pub fn Gecko_nsStyleFont_FixupMinFontSize(font: *mut nsStyleFont,
+ pres_context:
+ RawGeckoPresContextBorrowed);
+}
+extern "C" {
pub fn Gecko_GetBaseSize(lang: *mut nsIAtom) -> FontSizePrefs;
}
extern "C" {
pub fn Gecko_GetFontMetrics(pres_context: RawGeckoPresContextBorrowed,
is_vertical: bool, font: *const nsStyleFont,
font_size: nscoord, use_user_font_set: bool)
-> GeckoFontMetrics;
}
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -1501,17 +1501,18 @@ fn static_assert() {
}
</%self:impl_trait>
<%
skip_font_longhands = """font-family font-size font-size-adjust font-weight
font-synthesis -x-lang font-variant-alternates
font-variant-east-asian font-variant-ligatures
font-variant-numeric font-language-override
- font-feature-settings font-variation-settings"""
+ font-feature-settings font-variation-settings
+ -moz-min-font-size-ratio"""
%>
<%self:impl_trait style_struct_name="Font"
skip_longhands="${skip_font_longhands}"
skip_additionals="*">
pub fn set_font_feature_settings(&mut self, v: longhands::font_feature_settings::computed_value::T) {
use values::generics::FontSettings;
@@ -1644,39 +1645,44 @@ fn static_assert() {
unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); }
self.gecko.mGenericID = other.gecko.mGenericID;
}
// FIXME(bholley): Gecko has two different sizes, one of which (mSize) is the
// actual computed size, and the other of which (mFont.size) is the 'display
// size' which takes font zooming into account. We don't handle font zooming yet.
pub fn set_font_size(&mut self, v: longhands::font_size::computed_value::T) {
- self.gecko.mFont.size = v.0;
self.gecko.mSize = v.0;
self.gecko.mScriptUnconstrainedSize = v.0;
}
/// Set font size, taking into account scriptminsize and scriptlevel
/// Returns Some(size) if we have to recompute the script unconstrained size
pub fn apply_font_size(&mut self, v: longhands::font_size::computed_value::T,
- parent: &Self) -> Option<Au> {
+ parent: &Self,
+ device: &Device) -> Option<Au> {
let (adjusted_size, adjusted_unconstrained_size)
= self.calculate_script_level_size(parent);
// In this case, we have been unaffected by scriptminsize, ignore it
if parent.gecko.mSize == parent.gecko.mScriptUnconstrainedSize &&
adjusted_size == adjusted_unconstrained_size {
self.set_font_size(v);
+ self.fixup_font_min_size(device);
None
} else {
- self.gecko.mFont.size = v.0;
self.gecko.mSize = v.0;
+ self.fixup_font_min_size(device);
Some(Au(parent.gecko.mScriptUnconstrainedSize))
}
}
+ pub fn fixup_font_min_size(&mut self, device: &Device) {
+ unsafe { bindings::Gecko_nsStyleFont_FixupMinFontSize(&mut self.gecko, &*device.pres_context) }
+ }
+
pub fn apply_unconstrained_font_size(&mut self, v: Au) {
self.gecko.mScriptUnconstrainedSize = v.0;
}
/// Calculates the constrained and unconstrained font sizes to be inherited
/// from the parent.
///
/// See ComputeScriptLevelSize in Gecko's nsRuleNode.cpp
@@ -1775,17 +1781,18 @@ fn static_assert() {
}
/// This function will also handle scriptminsize and scriptlevel
/// so should not be called when you just want the font sizes to be copied.
/// Hence the different name.
///
/// Returns true if the inherited keyword size was actually used
pub fn inherit_font_size_from(&mut self, parent: &Self,
- kw_inherited_size: Option<Au>) -> bool {
+ kw_inherited_size: Option<Au>,
+ device: &Device) -> bool {
let (adjusted_size, adjusted_unconstrained_size)
= self.calculate_script_level_size(parent);
if adjusted_size.0 != parent.gecko.mSize ||
adjusted_unconstrained_size.0 != parent.gecko.mScriptUnconstrainedSize {
// This is incorrect. When there is both a keyword size being inherited
// and a scriptlevel change, we must handle the keyword size the same
// way we handle em units. This complicates things because we now have
// to keep track of the adjusted and unadjusted ratios in the kw font size.
@@ -1794,33 +1801,33 @@ fn static_assert() {
// If we were to fix this I would prefer doing it by removing the
// ruletree walk on the Gecko side in nsRuleNode::SetGenericFont
// and instead using extra bookkeeping in the mSize and mScriptUnconstrainedSize
// values, and reusing those instead of font_size_keyword.
// In the case that MathML has given us an adjusted size, apply it.
// Keep track of the unconstrained adjusted size.
- self.gecko.mFont.size = adjusted_size.0;
self.gecko.mSize = adjusted_size.0;
self.gecko.mScriptUnconstrainedSize = adjusted_unconstrained_size.0;
+ self.fixup_font_min_size(device);
false
} else if let Some(size) = kw_inherited_size {
// Parent element was a keyword-derived size.
- self.gecko.mFont.size = size.0;
self.gecko.mSize = size.0;
// MathML constraints didn't apply here, so we can ignore this.
self.gecko.mScriptUnconstrainedSize = size.0;
+ self.fixup_font_min_size(device);
true
} else {
// MathML isn't affecting us, and our parent element does not
// have a keyword-derived size. Set things normally.
- self.gecko.mFont.size = parent.gecko.mFont.size;
self.gecko.mSize = parent.gecko.mSize;
self.gecko.mScriptUnconstrainedSize = parent.gecko.mScriptUnconstrainedSize;
+ self.fixup_font_min_size(device);
false
}
}
pub fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
Au(self.gecko.mSize)
}
@@ -1913,16 +1920,31 @@ fn static_assert() {
${impl_simple_copy('font_variant_east_asian', 'mFont.variantEastAsian')}
pub fn set_font_variant_numeric(&mut self, v: longhands::font_variant_numeric::computed_value::T) {
self.gecko.mFont.variantNumeric = v.to_gecko_keyword()
}
${impl_simple_copy('font_variant_numeric', 'mFont.variantNumeric')}
+
+ #[allow(non_snake_case)]
+ pub fn set__moz_min_font_size_ratio(&mut self, v: longhands::_moz_min_font_size_ratio::computed_value::T) {
+ let percentage = if v.0 > 255. {
+ 255.
+ } else if v.0 < 0. {
+ 0.
+ } else {
+ v.0
+ };
+
+ self.gecko.mMinFontSizeRatio = percentage as u8;
+ }
+
+ ${impl_simple_copy('_moz_min_font_size_ratio', 'mMinFontSizeRatio')}
</%self:impl_trait>
<%def name="impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name)">
#[allow(non_snake_case)]
pub fn copy_${type}_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.m${type.capitalize()}s.ensure_len(other.gecko.m${type.capitalize()}s.len()) };
let count = other.gecko.m${type.capitalize()}${gecko_ffi_name}Count;
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -920,20 +920,22 @@
context.style().get_font().gecko().mGenericID !=
context.inherited_style().get_font().gecko().mGenericID {
if let Some((kw, ratio)) = context.style().font_size_keyword {
computed = kw.to_computed_value(context).scale_by(ratio);
}
}
% endif
- let parent_unconstrained = context.mutate_style()
- .mutate_font()
- .apply_font_size(computed,
- parent);
+ let parent_unconstrained = {
+ let (style, device) = context.mutate_style_with_device();
+
+ style.mutate_font().apply_font_size(computed, parent, device)
+ };
+
if let Some(parent) = parent_unconstrained {
let new_unconstrained = specified_value
.to_computed_value_against(context, FontBaseSize::Custom(parent));
context.mutate_style()
.mutate_font()
.apply_unconstrained_font_size(new_unconstrained);
}
@@ -941,34 +943,36 @@
pub fn cascade_inherit_font_size(context: &mut Context, parent: &Font) {
// If inheriting, we must recompute font-size in case of language changes
// using the font_size_keyword. We also need to do this to handle
// mathml scriptlevel changes
let kw_inherited_size = context.style().font_size_keyword.map(|(kw, ratio)| {
SpecifiedValue::Keyword(kw, ratio).to_computed_value(context)
});
- let used_kw = context.mutate_style().mutate_font()
- .inherit_font_size_from(parent, kw_inherited_size);
+ let parent_kw = context.inherited_style.font_size_keyword;
+ let (style, device) = context.mutate_style_with_device();
+ let used_kw = style.mutate_font()
+ .inherit_font_size_from(parent, kw_inherited_size, device);
if used_kw {
- context.mutate_style().font_size_keyword =
- context.inherited_style.font_size_keyword;
+ style.font_size_keyword = parent_kw;
} else {
- context.mutate_style().font_size_keyword = None;
+ style.font_size_keyword = None;
}
}
pub fn cascade_initial_font_size(context: &mut Context) {
// font-size's default ("medium") does not always
// compute to the same value and depends on the font
let computed = longhands::font_size::get_initial_specified_value()
.to_computed_value(context);
- context.mutate_style().mutate_${data.current_style_struct.name_lower}()
- .set_font_size(computed);
- context.mutate_style().font_size_keyword = Some((Default::default(), 1.));
+ let (style, device) = context.mutate_style_with_device();
+ style.mutate_font().set_font_size(computed);
+ style.mutate_font().fixup_font_min_size(device);
+ style.font_size_keyword = Some((Default::default(), 1.));
}
</%helpers:longhand>
<%helpers:longhand products="gecko" name="font-size-adjust" animation_value_type="ComputedValue"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust">
use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
@@ -2376,8 +2380,16 @@ macro_rules! exclusive_value {
${helpers.single_keyword("-moz-osx-font-smoothing",
"auto grayscale",
gecko_constant_prefix="NS_FONT_SMOOTHING",
gecko_ffi_name="mFont.smoothing",
products="gecko",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)",
animation_value_type="none",
need_clone=True)}
+
+${helpers.predefined_type("-moz-min-font-size-ratio",
+ "Percentage",
+ "computed::Percentage::hundred()",
+ animation_value_type="none",
+ products="gecko",
+ internal=True,
+ spec="Nonstandard (Internal-only)")}
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -613,16 +613,17 @@ impl LonghandId {
fn is_early_property(&self) -> bool {
matches!(*self,
% if product == 'gecko':
LonghandId::TextOrientation |
LonghandId::AnimationName |
LonghandId::TransitionProperty |
LonghandId::XLang |
LonghandId::MozScriptLevel |
+ LonghandId::MozMinFontSizeRatio |
% endif
LonghandId::FontSize |
LonghandId::FontFamily |
LonghandId::Color |
LonghandId::TextDecorationLine |
LonghandId::WritingMode |
LonghandId::Direction
)
@@ -1640,24 +1641,25 @@ pub mod style_structs {
hasher.write_u16(self.font_weight as u16);
self.font_stretch.hash(&mut hasher);
self.font_family.hash(&mut hasher);
self.hash = hasher.finish()
}
/// (Servo does not handle MathML, so this just calls copy_font_size_from)
pub fn inherit_font_size_from(&mut self, parent: &Self,
- _: Option<Au>) -> bool {
+ _: Option<Au>, _: &Device) -> bool {
self.copy_font_size_from(parent);
false
}
/// (Servo does not handle MathML, so this just calls set_font_size)
pub fn apply_font_size(&mut self,
v: longhands::font_size::computed_value::T,
- _: &Self) -> Option<Au> {
+ _: &Self,
+ _: &Device) -> Option<Au> {
self.set_font_size(v);
None
}
/// (Servo does not handle MathML, so this does nothing)
pub fn apply_unconstrained_font_size(&mut self, _: Au) {
}
% elif style_struct.name == "Outline":
@@ -2638,27 +2640,16 @@ pub fn apply_declarations<'a, F, I>(devi
// Only a few properties are allowed to depend on the visited state
// of links. When cascading visited styles, we can save time by
// only processing these properties.
if flags.contains(VISITED_DEPENDENT_ONLY) &&
!longhand_id.is_visited_dependent() {
continue
}
- // The computed value of some properties depends on the
- // (sometimes computed) value of *other* properties.
- //
- // So we classify properties into "early" and "other", such that
- // the only dependencies can be from "other" to "early".
- //
- // We iterate applicable_declarations twice, first cascading
- // "early" properties then "other".
- //
- // Unfortunately, it’s not easy to check that this
- // classification is correct.
if
% if category_to_cascade_now == "early":
!
% endif
longhand_id.is_early_property()
{
continue
}
@@ -2728,16 +2719,17 @@ pub fn apply_declarations<'a, F, I>(devi
&mut cacheable,
&mut cascade_info,
error_reporter);
% if product == "gecko":
// Font size must be explicitly inherited to handle lang changes and
// scriptlevel changes.
} else if seen.contains(LonghandId::XLang) ||
seen.contains(LonghandId::MozScriptLevel) ||
+ seen.contains(LonghandId::MozMinFontSizeRatio) ||
font_family.is_some() {
let discriminant = LonghandId::FontSize as usize;
let size = PropertyDeclaration::CSSWideKeyword(
LonghandId::FontSize, CSSWideKeyword::Inherit);
(CASCADE_PROPERTY[discriminant])(&size,
inherited_style,
default_style,
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -99,16 +99,18 @@ impl<'a> Context<'a> {
pub fn viewport_size(&self) -> Size2D<Au> { self.device.au_viewport_size() }
/// The style we're inheriting from.
pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
/// The current style. Note that only "eager" properties should be accessed
/// from here, see the comment in the member.
pub fn style(&self) -> &StyleBuilder { &self.style }
/// A mutable reference to the current style.
pub fn mutate_style(&mut self) -> &mut StyleBuilder<'a> { &mut self.style }
+ /// Get a mutable reference to the current style as well as the device
+ pub fn mutate_style_with_device(&mut self) -> (&mut StyleBuilder<'a>, &Device) { (&mut self.style, &self.device) }
}
/// An iterator over a slice of computed values
#[derive(Clone)]
pub struct ComputedVecIter<'a, 'cx, 'cx_a: 'cx, S: ToComputedValue + 'a> {
cx: &'cx Context<'cx_a>,
values: &'a [S],
}
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -729,16 +729,22 @@ impl Percentage {
_ => Err(())
}
}
/// Parses a percentage token, but rejects it if it's negative.
pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
Self::parse_with_clamping_mode(input, AllowedNumericType::NonNegative)
}
+
+ /// 100%
+ #[inline]
+ pub fn hundred() -> Self {
+ Percentage(1.)
+ }
}
impl Parse for Percentage {
#[inline]
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
Self::parse_with_clamping_mode(input, AllowedNumericType::All)
}
}