diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js
index d213ef3607127..4abecbc0409f9 100644
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -264,7 +264,9 @@ exports.CSS_PROPERTIES = {
"radio-label",
"radiomenuitem",
"range",
+ "range-progress",
"range-thumb",
+ "range-track",
"resizer",
"resizerpanel",
"revert",
@@ -1581,7 +1583,9 @@ exports.CSS_PROPERTIES = {
"radio-label",
"radiomenuitem",
"range",
+ "range-progress",
"range-thumb",
+ "range-track",
"resizer",
"resizerpanel",
"revert",
diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
index 4f0d0137240f7..10d7b3a491518 100644
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1628,28 +1628,23 @@ void nsPresContext::CountReflows(const char* aName, nsIFrame* aFrame) {
bool nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
uint32_t aRuleTypeMask) const {
- Element* elem = aFrame->GetContent()->AsElement();
-
- // We need to handle non-generated content pseudos too, so we use
- // the parent of generated content pseudo to be consistent.
- if (elem->GetPseudoElementType() != PseudoStyleType::NotPseudo) {
- MOZ_ASSERT(elem->GetParent(), "Pseudo element has no parent element?");
- elem = elem->GetParent()->AsElement();
- }
- if (MOZ_UNLIKELY(!elem->HasServoData())) {
- // Probably shouldn't happen, but does. See bug 1387953
- return false;
+ MOZ_ASSERT(aFrame->StyleDisplay()->HasAppearance(),
+ "This should only be used to disable native appearance");
+ const bool padding = aRuleTypeMask & NS_AUTHOR_SPECIFIED_PADDING;
+ const bool borderBackground =
+ aRuleTypeMask & NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND;
+ const auto& style = *aFrame->Style();
+
+ if (padding && style.HasAppearanceAndAuthorSpecifiedPadding()) {
+ return true;
}
- // Anonymous boxes are more complicated, and we just assume that they
- // cannot have any author-specified rules here.
- if (aFrame->Style()->IsAnonBox()) {
- return false;
+ if (borderBackground &&
+ style.HasAppearanceAndAuthorSpecifiedBorderOrBackground()) {
+ return true;
}
- auto* set = PresShell()->StyleSet()->RawSet();
- return Servo_HasAuthorSpecifiedRules(set, aFrame->Style(), elem,
- aRuleTypeMask);
+ return false;
}
gfxUserFontSet* nsPresContext::GetUserFontSet() {
diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
index 4300c078641b0..b59ca86e5960e 100644
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -117,9 +117,8 @@ enum class nsLayoutPhase : uint8_t {
#endif
/* Used by nsPresContext::HasAuthorSpecifiedRules */
-#define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
-#define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
-#define NS_AUTHOR_SPECIFIED_PADDING (1 << 2)
+#define NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND (1 << 0)
+#define NS_AUTHOR_SPECIFIED_PADDING (1 << 1)
class nsRootPresContext;
diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp
index 1d30294b0f62a..b85b3b5608f2d 100644
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -232,11 +232,9 @@ bool nsMeterFrame::ShouldUseNativeStyle() const {
// background.
return StyleDisplay()->mAppearance == StyleAppearance::Meter &&
!PresContext()->HasAuthorSpecifiedRules(
- this,
- NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
+ this, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND) &&
barFrame &&
barFrame->StyleDisplay()->mAppearance == StyleAppearance::Meterchunk &&
!PresContext()->HasAuthorSpecifiedRules(
- barFrame,
- NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
+ barFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
}
diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp
index a22eed6ccf64e..fd4330c6cd10d 100644
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -231,9 +231,8 @@ bool nsNumberControlFrame::SpinnerDownButtonIsDepressed() const {
->NumberSpinnerDownButtonIsDepressed();
}
-#define STYLES_DISABLING_NATIVE_THEMING \
- NS_AUTHOR_SPECIFIED_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING | \
- NS_AUTHOR_SPECIFIED_BORDER
+#define STYLES_DISABLING_NATIVE_THEMING \
+ NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING
bool nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const {
MOZ_ASSERT(mSpinUp && mSpinDown,
diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp
index 4371e45fd3be0..b3eff1c23da6d 100644
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -248,12 +248,10 @@ bool nsProgressFrame::ShouldUseNativeStyle() const {
// background.
return StyleDisplay()->mAppearance == StyleAppearance::ProgressBar &&
!PresContext()->HasAuthorSpecifiedRules(
- this,
- NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
+ this, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND) &&
barFrame &&
barFrame->StyleDisplay()->mAppearance ==
StyleAppearance::Progresschunk &&
!PresContext()->HasAuthorSpecifiedRules(
- barFrame,
- NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
+ barFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
}
diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp
index a4b7ad151db51..09bf372ded8a4 100644
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -800,17 +800,15 @@ double nsRangeFrame::GetValue() const {
.toDouble();
}
-#define STYLES_DISABLING_NATIVE_THEMING \
- NS_AUTHOR_SPECIFIED_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING | \
- NS_AUTHOR_SPECIFIED_BORDER
+#define STYLES_DISABLING_NATIVE_THEMING \
+ NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING
bool nsRangeFrame::ShouldUseNativeStyle() const {
nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame();
nsIFrame* progressFrame = mProgressDiv->GetPrimaryFrame();
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
- return (StyleDisplay()->mAppearance == StyleAppearance::Range) &&
- trackFrame &&
+ return StyleDisplay()->mAppearance == StyleAppearance::Range && trackFrame &&
!PresContext()->HasAuthorSpecifiedRules(
trackFrame, STYLES_DISABLING_NATIVE_THEMING) &&
progressFrame &&
diff --git a/layout/reftests/forms/button/appearance-revert-ref.html b/layout/reftests/forms/button/appearance-revert-ref.html
new file mode 100644
index 0000000000000..9e863880dfb45
--- /dev/null
+++ b/layout/reftests/forms/button/appearance-revert-ref.html
@@ -0,0 +1,2 @@
+
+
diff --git a/layout/reftests/forms/button/appearance-revert.html b/layout/reftests/forms/button/appearance-revert.html
new file mode 100644
index 0000000000000..06f1d045d2170
--- /dev/null
+++ b/layout/reftests/forms/button/appearance-revert.html
@@ -0,0 +1,2 @@
+
+
diff --git a/layout/reftests/forms/button/reftest.list b/layout/reftests/forms/button/reftest.list
index 14c23e6fd7805..3b397f2977ffd 100644
--- a/layout/reftests/forms/button/reftest.list
+++ b/layout/reftests/forms/button/reftest.list
@@ -50,3 +50,5 @@ fails-if(Android&&nativeThemePref) == disabled-1.html disabled-1-ref.html
== dynamic-text-indent.html dynamic-text-indent-ref.html
== 1349646.html 1349646-ref.html
+
+== appearance-revert.html appearance-revert-ref.html
diff --git a/layout/style/ComputedStyle.h b/layout/style/ComputedStyle.h
index 0ac0ba1ec9027..5ae45644daf46 100644
--- a/layout/style/ComputedStyle.h
+++ b/layout/style/ComputedStyle.h
@@ -122,6 +122,19 @@ class ComputedStyle {
return mPseudoType != PseudoStyleType::NotPseudo;
}
+ // Whether there are author-specified rules for padding properties.
+ // Only returns something meaningful if the appearance property is not `none`.
+ bool HasAppearanceAndAuthorSpecifiedPadding() const {
+ return bool(Flags() & Flag::HAS_AUTHOR_SPECIFIED_PADDING);
+ }
+
+ // Whether there are author-specified rules for border or background
+ // properties.
+ // Only returns something meaningful if the appearance property is not `none`.
+ bool HasAppearanceAndAuthorSpecifiedBorderOrBackground() const {
+ return bool(Flags() & Flag::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND);
+ }
+
// Does this ComputedStyle or any of its ancestors have text
// decoration lines?
// Differs from nsStyleTextReset::HasTextDecorationLines, which tests
diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml
index 3d550fe4439c1..7821e6c7cd8d3 100644
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -167,8 +167,6 @@ rusty-enums = [
"mozilla::StyleMaskComposite",
]
whitelist-vars = [
- "NS_AUTHOR_SPECIFIED_.*",
- "NS_THEME_.*",
"NS_ATTRVALUE_.*",
"NODE_.*",
"ELEMENT_.*",
diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css
index 7022c666104ba..f4a3b1a92c0f4 100644
--- a/layout/style/res/forms.css
+++ b/layout/style/res/forms.css
@@ -909,6 +909,7 @@ input[type=range]::-moz-focus-outer {
* set the width/height of this pseudo-element.
*/
input[type=range]::-moz-range-track {
+ -moz-appearance: range-track !important;
/* Prevent styling that would change the type of frame we construct. */
display: block !important;
float: none !important;
@@ -934,6 +935,7 @@ input[type=range][orient=vertical]::-moz-range-track {
* is ignored.
*/
input[type=range]::-moz-range-progress {
+ -moz-appearance: range-progress !important;
/* Prevent styling that would change the type of frame we construct. */
display: block !important;
float: none !important;
diff --git a/servo/components/style/properties/cascade.rs b/servo/components/style/properties/cascade.rs
index 9d3660730451a..415c8084d8562 100644
--- a/servo/components/style/properties/cascade.rs
+++ b/servo/components/style/properties/cascade.rs
@@ -13,7 +13,7 @@ use crate::media_queries::Device;
use crate::properties::{ComputedValues, StyleBuilder};
use crate::properties::{LonghandId, LonghandIdSet, CSSWideKeyword};
use crate::properties::{PropertyDeclaration, PropertyDeclarationId, DeclarationImportanceIterator};
-use crate::properties::CASCADE_PROPERTY;
+use crate::properties::{CASCADE_PROPERTY, ComputedValueFlags};
use crate::rule_cache::{RuleCache, RuleCacheConditions};
use crate::rule_tree::StrongRuleNode;
use crate::selector_parser::PseudoElement;
@@ -411,6 +411,7 @@ struct Cascade<'a, 'b: 'a> {
context: &'a mut computed::Context<'b>,
cascade_mode: CascadeMode<'a>,
seen: LonghandIdSet,
+ author_specified: LonghandIdSet,
reverted: PerOrigin,
}
@@ -420,6 +421,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
context,
cascade_mode,
seen: LonghandIdSet::default(),
+ author_specified: LonghandIdSet::default(),
reverted: Default::default(),
}
}
@@ -557,6 +559,9 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
}
self.seen.insert(physical_longhand_id);
+ if origin == Origin::Author {
+ self.author_specified.insert(physical_longhand_id);
+ }
let unset = css_wide_keyword.map_or(false, |css_wide_keyword| {
match css_wide_keyword {
@@ -679,6 +684,15 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
if let Some(svg) = builder.get_svg_if_mutated() {
svg.fill_arrays();
}
+
+ if !builder.get_box().clone__moz_appearance().is_none() {
+ if self.author_specified.contains_any(LonghandIdSet::border_background_properties()) {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND);
+ }
+ if self.author_specified.contains_any(LonghandIdSet::padding_properties()) {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_PADDING);
+ }
+ }
}
#[cfg(feature = "servo")]
@@ -699,12 +713,26 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
None => return false,
};
- let cached_style = match cache.find(guards, &self.context.builder) {
+ let builder = &mut self.context.builder;
+
+ let cached_style = match cache.find(guards, &builder) {
Some(style) => style,
None => return false,
};
- self.context.builder.copy_reset_from(cached_style);
+ builder.copy_reset_from(cached_style);
+
+ // We're using the same reset style as another element, and we'll skip
+ // applying the relevant properties. So we need to do the relevant
+ // bookkeeping here to keep these two bits correct.
+ //
+ // Note that all the properties involved are non-inherited, so we don't
+ // need to do anything else other than just copying the bits over.
+ let reset_props_bits =
+ ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND |
+ ComputedValueFlags::HAS_AUTHOR_SPECIFIED_PADDING;
+ builder.add_flags(cached_style.flags & reset_props_bits);
+
true
}
diff --git a/servo/components/style/properties/computed_value_flags.rs b/servo/components/style/properties/computed_value_flags.rs
index b5294093adfe9..221363ba4b147 100644
--- a/servo/components/style/properties/computed_value_flags.rs
+++ b/servo/components/style/properties/computed_value_flags.rs
@@ -70,6 +70,20 @@ bitflags! {
/// Whether this element is inside an `opacity: 0` subtree.
const IS_IN_OPACITY_ZERO_SUBTREE = 1 << 12;
+
+ /// Whether there are author-specified rules for border-* properties
+ /// (except border-image-*), background-color, or background-image.
+ ///
+ /// TODO(emilio): Maybe do include border-image, see:
+ ///
+ /// https://github.com/w3c/csswg-drafts/issues/4777#issuecomment-604424845
+ const HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND = 1 << 13;
+
+ /// Whether there are author-specified rules for padding-* properties.
+ ///
+ /// FIXME(emilio): Try to merge this with BORDER_BACKGROUND, see
+ /// https://github.com/w3c/csswg-drafts/issues/4777
+ const HAS_AUTHOR_SPECIFIED_PADDING = 1 << 14;
}
}
diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs
index c39dc6f23da10..b739ca63173ac 100644
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -750,6 +750,52 @@ static ${name}: LonghandIdSet = LonghandIdSet {
};
%def>
+<%
+ logical_groups = defaultdict(list)
+ for prop in data.longhands:
+ if prop.logical_group:
+ logical_groups[prop.logical_group].append(prop)
+
+ for group, props in logical_groups.iteritems():
+ logical_count = sum(1 for p in props if p.logical)
+ if logical_count * 2 != len(props):
+ raise RuntimeError("Logical group {} has ".format(group) +
+ "unbalanced logical / physical properties")
+
+ FIRST_LINE_RESTRICTIONS = PropertyRestrictions.first_line(data)
+ FIRST_LETTER_RESTRICTIONS = PropertyRestrictions.first_letter(data)
+ MARKER_RESTRICTIONS = PropertyRestrictions.marker(data)
+ PLACEHOLDER_RESTRICTIONS = PropertyRestrictions.placeholder(data)
+ CUE_RESTRICTIONS = PropertyRestrictions.cue(data)
+
+ def restriction_flags(property):
+ name = property.name
+ flags = []
+ if name in FIRST_LINE_RESTRICTIONS:
+ flags.append("APPLIES_TO_FIRST_LINE")
+ if name in FIRST_LETTER_RESTRICTIONS:
+ flags.append("APPLIES_TO_FIRST_LETTER")
+ if name in PLACEHOLDER_RESTRICTIONS:
+ flags.append("APPLIES_TO_PLACEHOLDER")
+ if name in MARKER_RESTRICTIONS:
+ flags.append("APPLIES_TO_MARKER")
+ if name in CUE_RESTRICTIONS:
+ flags.append("APPLIES_TO_CUE")
+ return flags
+
+%>
+
+/// A group for properties which may override each other
+/// via logical resolution.
+#[derive(Clone, Copy, Eq, Hash, PartialEq)]
+pub enum LogicalGroup {
+ % for group in logical_groups.iterkeys():
+ /// ${group}
+ ${to_camel_case(group)},
+ % endfor
+}
+
+
/// A set of longhand properties
#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)]
pub struct LonghandIdSet {
@@ -837,6 +883,29 @@ impl LonghandIdSet {
&HAS_NO_EFFECT_ON_SCROLLBARS
}
+ /// Returns the set of padding properties for the purpose of disabling
+ /// native appearance.
+ #[inline]
+ pub fn padding_properties() -> &'static Self {
+ <% assert "padding" in logical_groups %>
+ ${static_longhand_id_set(
+ "PADDING_PROPERTIES",
+ lambda p: p.logical_group == "padding"
+ )}
+ &PADDING_PROPERTIES
+ }
+
+ /// Returns the set of border properties for the purpose of disabling native
+ /// appearance.
+ #[inline]
+ pub fn border_background_properties() -> &'static Self {
+ ${static_longhand_id_set(
+ "BORDER_BACKGROUND_PROPERTIES",
+ lambda p: (p.logical_group and p.logical_group.startswith("border")) or p.name in ["background-color", "background-image"]
+ )}
+ &BORDER_BACKGROUND_PROPERTIES
+ }
+
/// Iterate over the current longhand id set.
pub fn iter(&self) -> LonghandIdSetIterator {
LonghandIdSetIterator { longhands: self, cur: 0, }
@@ -998,51 +1067,6 @@ bitflags! {
}
}
-<%
- logical_groups = defaultdict(list)
- for prop in data.longhands:
- if prop.logical_group:
- logical_groups[prop.logical_group].append(prop)
-
- for group, props in logical_groups.iteritems():
- logical_count = sum(1 for p in props if p.logical)
- if logical_count * 2 != len(props):
- raise RuntimeError("Logical group {} has ".format(group) +
- "unbalanced logical / physical properties")
-
- FIRST_LINE_RESTRICTIONS = PropertyRestrictions.first_line(data)
- FIRST_LETTER_RESTRICTIONS = PropertyRestrictions.first_letter(data)
- MARKER_RESTRICTIONS = PropertyRestrictions.marker(data)
- PLACEHOLDER_RESTRICTIONS = PropertyRestrictions.placeholder(data)
- CUE_RESTRICTIONS = PropertyRestrictions.cue(data)
-
- def restriction_flags(property):
- name = property.name
- flags = []
- if name in FIRST_LINE_RESTRICTIONS:
- flags.append("APPLIES_TO_FIRST_LINE")
- if name in FIRST_LETTER_RESTRICTIONS:
- flags.append("APPLIES_TO_FIRST_LETTER")
- if name in PLACEHOLDER_RESTRICTIONS:
- flags.append("APPLIES_TO_PLACEHOLDER")
- if name in MARKER_RESTRICTIONS:
- flags.append("APPLIES_TO_MARKER")
- if name in CUE_RESTRICTIONS:
- flags.append("APPLIES_TO_CUE")
- return flags
-
-%>
-
-/// A group for properties which may override each other
-/// via logical resolution.
-#[derive(Clone, Copy, Eq, Hash, PartialEq)]
-pub enum LogicalGroup {
- % for group in logical_groups.iterkeys():
- /// ${group}
- ${to_camel_case(group)},
- % endfor
-}
-
/// An identifier for a given longhand property.
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
#[repr(u16)]
diff --git a/servo/components/style/rule_tree/mod.rs b/servo/components/style/rule_tree/mod.rs
index ddac85a807500..484cdee518348 100644
--- a/servo/components/style/rule_tree/mod.rs
+++ b/servo/components/style/rule_tree/mod.rs
@@ -7,8 +7,6 @@
//! The rule tree.
use crate::applicable_declarations::ApplicableDeclarationList;
-#[cfg(feature = "gecko")]
-use crate::gecko::selector_parser::PseudoElement;
use crate::hash::{self, FxHashMap};
use crate::properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
@@ -1418,198 +1416,6 @@ impl StrongRuleNode {
}
}
- /// Returns true if any properties specified by `rule_type_mask` was set by
- /// an author rule.
- #[cfg(feature = "gecko")]
- pub fn has_author_specified_rules(
- &self,
- mut element: E,
- mut pseudo: Option,
- guards: &StylesheetGuards,
- rule_type_mask: u32,
- author_colors_allowed: bool,
- ) -> bool
- where
- E: crate::dom::TElement,
- {
- use crate::gecko_bindings::structs::NS_AUTHOR_SPECIFIED_BACKGROUND;
- use crate::gecko_bindings::structs::NS_AUTHOR_SPECIFIED_BORDER;
- use crate::gecko_bindings::structs::NS_AUTHOR_SPECIFIED_PADDING;
- use crate::properties::{CSSWideKeyword, LonghandId};
- use crate::properties::{PropertyDeclaration, PropertyDeclarationId};
- use std::borrow::Cow;
-
- // Reset properties:
- const BACKGROUND_PROPS: &'static [LonghandId] =
- &[LonghandId::BackgroundColor, LonghandId::BackgroundImage];
-
- const BORDER_PROPS: &'static [LonghandId] = &[
- LonghandId::BorderTopColor,
- LonghandId::BorderTopStyle,
- LonghandId::BorderTopWidth,
- LonghandId::BorderRightColor,
- LonghandId::BorderRightStyle,
- LonghandId::BorderRightWidth,
- LonghandId::BorderBottomColor,
- LonghandId::BorderBottomStyle,
- LonghandId::BorderBottomWidth,
- LonghandId::BorderLeftColor,
- LonghandId::BorderLeftStyle,
- LonghandId::BorderLeftWidth,
- LonghandId::BorderTopLeftRadius,
- LonghandId::BorderTopRightRadius,
- LonghandId::BorderBottomRightRadius,
- LonghandId::BorderBottomLeftRadius,
- LonghandId::BorderInlineStartColor,
- LonghandId::BorderInlineStartStyle,
- LonghandId::BorderInlineStartWidth,
- LonghandId::BorderInlineEndColor,
- LonghandId::BorderInlineEndStyle,
- LonghandId::BorderInlineEndWidth,
- LonghandId::BorderBlockStartColor,
- LonghandId::BorderBlockStartStyle,
- LonghandId::BorderBlockStartWidth,
- LonghandId::BorderBlockEndColor,
- LonghandId::BorderBlockEndStyle,
- LonghandId::BorderBlockEndWidth,
- ];
-
- const PADDING_PROPS: &'static [LonghandId] = &[
- LonghandId::PaddingTop,
- LonghandId::PaddingRight,
- LonghandId::PaddingBottom,
- LonghandId::PaddingLeft,
- LonghandId::PaddingInlineStart,
- LonghandId::PaddingInlineEnd,
- LonghandId::PaddingBlockStart,
- LonghandId::PaddingBlockEnd,
- ];
-
- // Set of properties that we are currently interested in.
- let mut properties = LonghandIdSet::new();
-
- if rule_type_mask & NS_AUTHOR_SPECIFIED_BACKGROUND != 0 {
- for id in BACKGROUND_PROPS {
- properties.insert(*id);
- }
- }
- if rule_type_mask & NS_AUTHOR_SPECIFIED_BORDER != 0 {
- for id in BORDER_PROPS {
- properties.insert(*id);
- }
- }
- if rule_type_mask & NS_AUTHOR_SPECIFIED_PADDING != 0 {
- for id in PADDING_PROPS {
- properties.insert(*id);
- }
- }
-
- // If author colors are not allowed, don't look at those properties
- // (except for background-color which is special and we handle below).
- if !author_colors_allowed {
- properties.remove_all(LonghandIdSet::ignored_when_colors_disabled());
- if rule_type_mask & NS_AUTHOR_SPECIFIED_BACKGROUND != 0 {
- properties.insert(LonghandId::BackgroundColor);
- }
- }
-
- let mut element_rule_node = Cow::Borrowed(self);
-
- loop {
- // We need to be careful not to count styles covered up by
- // user-important or UA-important declarations. But we do want to
- // catch explicit inherit styling in those and check our parent
- // element to see whether we have user styling for those properties.
- // Note that we don't care here about inheritance due to lack of a
- // specified value, since all the properties we care about are reset
- // properties.
-
- let mut inherited_properties = LonghandIdSet::new();
- let mut have_explicit_ua_inherit = false;
-
- for node in element_rule_node.self_and_ancestors() {
- let source = node.style_source();
- let declarations = if source.is_some() {
- source
- .as_ref()
- .unwrap()
- .read(node.cascade_level().guard(guards))
- .declaration_importance_iter()
- } else {
- continue;
- };
-
- // Iterate over declarations of the longhands we care about.
- let node_importance = node.importance();
- let longhands = declarations.rev().filter_map(|(declaration, importance)| {
- if importance != node_importance {
- return None;
- }
- match declaration.id() {
- PropertyDeclarationId::Longhand(id) => Some((id, declaration)),
- _ => None,
- }
- });
-
- let is_author = node.cascade_level().origin() == Origin::Author;
- for (id, declaration) in longhands {
- if !properties.contains(id) {
- continue;
- }
-
- if is_author {
- if !author_colors_allowed {
- if let PropertyDeclaration::BackgroundColor(ref color) = *declaration {
- if color.is_transparent() {
- return true;
- }
- continue;
- }
- }
- return true;
- }
-
- // This property was set by a non-author rule.
- // Stop looking for it in this element's rule
- // nodes.
- properties.remove(id);
-
- // However, if it is inherited, then it might be
- // inherited from an author rule from an
- // ancestor element's rule nodes.
- if declaration.get_css_wide_keyword() == Some(CSSWideKeyword::Inherit) {
- have_explicit_ua_inherit = true;
- inherited_properties.insert(id);
- }
- }
- }
-
- if !have_explicit_ua_inherit {
- break;
- }
-
- // Continue to the parent element and search for the inherited properties.
- if let Some(pseudo) = pseudo.take() {
- if pseudo.inherits_from_default_values() {
- break;
- }
- } else {
- element = match element.inheritance_parent() {
- Some(parent) => parent,
- None => break,
- };
-
- let parent_data = element.mutate_data().unwrap();
- let parent_rule_node = parent_data.styles.primary().rules().clone();
- element_rule_node = Cow::Owned(parent_rule_node);
- }
-
- properties = inherited_properties;
- }
-
- false
- }
-
/// Returns true if there is either animation or transition level rule.
pub fn has_animation_or_transition_rules(&self) -> bool {
self.self_and_ancestors()
diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs
index 75da811f08d4d..f546e1a3d92a3 100644
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -1630,7 +1630,11 @@ pub enum Appearance {
RadioLabel,
/// nsRangeFrame and its subparts
Range,
- RangeThumb,
+ RangeThumb, // FIXME: This should not be exposed to content.
+ #[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
+ RangeProgress,
+ #[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
+ RangeTrack,
/// The resizer background area in a status bar for the resizer widget in
/// the corner of a window.
#[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
@@ -1856,6 +1860,14 @@ pub enum Appearance {
Count,
}
+impl Appearance {
+ /// Returns whether we're the `none` value.
+ #[inline]
+ pub fn is_none(self) -> bool {
+ self == Appearance::None
+ }
+}
+
/// A kind of break between two boxes.
///
/// https://drafts.csswg.org/css-break/#break-between
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
index 4eccf5f3c99c7..ad137b061ad01 100644
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3723,31 +3723,6 @@ pub extern "C" fn Servo_SetExplicitStyle(element: &RawGeckoElement, style: &Comp
data.styles.primary = Some(unsafe { ArcBorrow::from_ref(style) }.clone_arc());
}
-#[no_mangle]
-pub extern "C" fn Servo_HasAuthorSpecifiedRules(
- raw_data: &RawServoStyleSet,
- style: &ComputedValues,
- element: &RawGeckoElement,
- rule_type_mask: u32,
-) -> bool {
- let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
- let element = GeckoElement(element);
-
- let guard = (*GLOBAL_STYLE_DATA).shared_lock.read();
- let guards = StylesheetGuards::same(&guard);
-
- let pseudo = style.pseudo();
- let author_colors_allowed = data.stylist.device().use_document_colors();
-
- style.rules().has_author_specified_rules(
- element,
- pseudo,
- &guards,
- rule_type_mask,
- author_colors_allowed,
- )
-}
-
fn get_pseudo_style(
guard: &SharedRwLockReadGuard,
element: GeckoElement,
diff --git a/widget/nsNativeTheme.cpp b/widget/nsNativeTheme.cpp
index 8a9afd876b062..b0a6a83992bec 100644
--- a/widget/nsNativeTheme.cpp
+++ b/widget/nsNativeTheme.cpp
@@ -292,8 +292,7 @@ bool nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext,
aAppearance == StyleAppearance::MenulistButton) &&
aFrame->GetContent()->IsHTMLElement() &&
aPresContext->HasAuthorSpecifiedRules(
- aFrame,
- NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
+ aFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
}
bool nsNativeTheme::IsDisabled(nsIFrame* aFrame, EventStates aEventStates) {