зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset ac0d06c0ca93 (bug 1624080) for assertion failures. CLOSED TREE
This commit is contained in:
Родитель
91b8ae8f57
Коммит
7155f2665a
|
@ -264,9 +264,7 @@ exports.CSS_PROPERTIES = {
|
||||||
"radio-label",
|
"radio-label",
|
||||||
"radiomenuitem",
|
"radiomenuitem",
|
||||||
"range",
|
"range",
|
||||||
"range-progress",
|
|
||||||
"range-thumb",
|
"range-thumb",
|
||||||
"range-track",
|
|
||||||
"resizer",
|
"resizer",
|
||||||
"resizerpanel",
|
"resizerpanel",
|
||||||
"revert",
|
"revert",
|
||||||
|
@ -1583,9 +1581,7 @@ exports.CSS_PROPERTIES = {
|
||||||
"radio-label",
|
"radio-label",
|
||||||
"radiomenuitem",
|
"radiomenuitem",
|
||||||
"range",
|
"range",
|
||||||
"range-progress",
|
|
||||||
"range-thumb",
|
"range-thumb",
|
||||||
"range-track",
|
|
||||||
"resizer",
|
"resizer",
|
||||||
"resizerpanel",
|
"resizerpanel",
|
||||||
"revert",
|
"revert",
|
||||||
|
|
|
@ -1628,23 +1628,28 @@ void nsPresContext::CountReflows(const char* aName, nsIFrame* aFrame) {
|
||||||
|
|
||||||
bool nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
|
bool nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
|
||||||
uint32_t aRuleTypeMask) const {
|
uint32_t aRuleTypeMask) const {
|
||||||
MOZ_ASSERT(aFrame->StyleDisplay()->HasAppearance(),
|
Element* elem = aFrame->GetContent()->AsElement();
|
||||||
"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()) {
|
// We need to handle non-generated content pseudos too, so we use
|
||||||
return true;
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (borderBackground &&
|
// Anonymous boxes are more complicated, and we just assume that they
|
||||||
style.HasAppearanceAndAuthorSpecifiedBorderOrBackground()) {
|
// cannot have any author-specified rules here.
|
||||||
return true;
|
if (aFrame->Style()->IsAnonBox()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
auto* set = PresShell()->StyleSet()->RawSet();
|
||||||
|
return Servo_HasAuthorSpecifiedRules(set, aFrame->Style(), elem,
|
||||||
|
aRuleTypeMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxUserFontSet* nsPresContext::GetUserFontSet() {
|
gfxUserFontSet* nsPresContext::GetUserFontSet() {
|
||||||
|
|
|
@ -117,8 +117,9 @@ enum class nsLayoutPhase : uint8_t {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used by nsPresContext::HasAuthorSpecifiedRules */
|
/* Used by nsPresContext::HasAuthorSpecifiedRules */
|
||||||
#define NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND (1 << 0)
|
#define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
|
||||||
#define NS_AUTHOR_SPECIFIED_PADDING (1 << 1)
|
#define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
|
||||||
|
#define NS_AUTHOR_SPECIFIED_PADDING (1 << 2)
|
||||||
|
|
||||||
class nsRootPresContext;
|
class nsRootPresContext;
|
||||||
|
|
||||||
|
|
|
@ -232,9 +232,11 @@ bool nsMeterFrame::ShouldUseNativeStyle() const {
|
||||||
// background.
|
// background.
|
||||||
return StyleDisplay()->mAppearance == StyleAppearance::Meter &&
|
return StyleDisplay()->mAppearance == StyleAppearance::Meter &&
|
||||||
!PresContext()->HasAuthorSpecifiedRules(
|
!PresContext()->HasAuthorSpecifiedRules(
|
||||||
this, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND) &&
|
this,
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
|
||||||
barFrame &&
|
barFrame &&
|
||||||
barFrame->StyleDisplay()->mAppearance == StyleAppearance::Meterchunk &&
|
barFrame->StyleDisplay()->mAppearance == StyleAppearance::Meterchunk &&
|
||||||
!PresContext()->HasAuthorSpecifiedRules(
|
!PresContext()->HasAuthorSpecifiedRules(
|
||||||
barFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
|
barFrame,
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,8 +231,9 @@ bool nsNumberControlFrame::SpinnerDownButtonIsDepressed() const {
|
||||||
->NumberSpinnerDownButtonIsDepressed();
|
->NumberSpinnerDownButtonIsDepressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STYLES_DISABLING_NATIVE_THEMING \
|
#define STYLES_DISABLING_NATIVE_THEMING \
|
||||||
NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING
|
NS_AUTHOR_SPECIFIED_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING | \
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER
|
||||||
|
|
||||||
bool nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const {
|
bool nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const {
|
||||||
MOZ_ASSERT(mSpinUp && mSpinDown,
|
MOZ_ASSERT(mSpinUp && mSpinDown,
|
||||||
|
|
|
@ -248,10 +248,12 @@ bool nsProgressFrame::ShouldUseNativeStyle() const {
|
||||||
// background.
|
// background.
|
||||||
return StyleDisplay()->mAppearance == StyleAppearance::ProgressBar &&
|
return StyleDisplay()->mAppearance == StyleAppearance::ProgressBar &&
|
||||||
!PresContext()->HasAuthorSpecifiedRules(
|
!PresContext()->HasAuthorSpecifiedRules(
|
||||||
this, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND) &&
|
this,
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
|
||||||
barFrame &&
|
barFrame &&
|
||||||
barFrame->StyleDisplay()->mAppearance ==
|
barFrame->StyleDisplay()->mAppearance ==
|
||||||
StyleAppearance::Progresschunk &&
|
StyleAppearance::Progresschunk &&
|
||||||
!PresContext()->HasAuthorSpecifiedRules(
|
!PresContext()->HasAuthorSpecifiedRules(
|
||||||
barFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
|
barFrame,
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -800,15 +800,17 @@ double nsRangeFrame::GetValue() const {
|
||||||
.toDouble();
|
.toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STYLES_DISABLING_NATIVE_THEMING \
|
#define STYLES_DISABLING_NATIVE_THEMING \
|
||||||
NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING
|
NS_AUTHOR_SPECIFIED_BACKGROUND | NS_AUTHOR_SPECIFIED_PADDING | \
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER
|
||||||
|
|
||||||
bool nsRangeFrame::ShouldUseNativeStyle() const {
|
bool nsRangeFrame::ShouldUseNativeStyle() const {
|
||||||
nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame();
|
nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame();
|
||||||
nsIFrame* progressFrame = mProgressDiv->GetPrimaryFrame();
|
nsIFrame* progressFrame = mProgressDiv->GetPrimaryFrame();
|
||||||
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
|
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
|
||||||
|
|
||||||
return StyleDisplay()->mAppearance == StyleAppearance::Range && trackFrame &&
|
return (StyleDisplay()->mAppearance == StyleAppearance::Range) &&
|
||||||
|
trackFrame &&
|
||||||
!PresContext()->HasAuthorSpecifiedRules(
|
!PresContext()->HasAuthorSpecifiedRules(
|
||||||
trackFrame, STYLES_DISABLING_NATIVE_THEMING) &&
|
trackFrame, STYLES_DISABLING_NATIVE_THEMING) &&
|
||||||
progressFrame &&
|
progressFrame &&
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<button>Foo</button>
|
|
|
@ -1,2 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<button style="border: revert">Foo</button>
|
|
|
@ -50,5 +50,3 @@ fails-if(Android&&nativeThemePref) == disabled-1.html disabled-1-ref.html
|
||||||
== dynamic-text-indent.html dynamic-text-indent-ref.html
|
== dynamic-text-indent.html dynamic-text-indent-ref.html
|
||||||
|
|
||||||
== 1349646.html 1349646-ref.html
|
== 1349646.html 1349646-ref.html
|
||||||
|
|
||||||
== appearance-revert.html appearance-revert-ref.html
|
|
||||||
|
|
|
@ -122,19 +122,6 @@ class ComputedStyle {
|
||||||
return mPseudoType != PseudoStyleType::NotPseudo;
|
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
|
// Does this ComputedStyle or any of its ancestors have text
|
||||||
// decoration lines?
|
// decoration lines?
|
||||||
// Differs from nsStyleTextReset::HasTextDecorationLines, which tests
|
// Differs from nsStyleTextReset::HasTextDecorationLines, which tests
|
||||||
|
|
|
@ -167,6 +167,8 @@ rusty-enums = [
|
||||||
"mozilla::StyleMaskComposite",
|
"mozilla::StyleMaskComposite",
|
||||||
]
|
]
|
||||||
whitelist-vars = [
|
whitelist-vars = [
|
||||||
|
"NS_AUTHOR_SPECIFIED_.*",
|
||||||
|
"NS_THEME_.*",
|
||||||
"NS_ATTRVALUE_.*",
|
"NS_ATTRVALUE_.*",
|
||||||
"NODE_.*",
|
"NODE_.*",
|
||||||
"ELEMENT_.*",
|
"ELEMENT_.*",
|
||||||
|
|
|
@ -909,7 +909,6 @@ input[type=range]::-moz-focus-outer {
|
||||||
* set the width/height of this pseudo-element.
|
* set the width/height of this pseudo-element.
|
||||||
*/
|
*/
|
||||||
input[type=range]::-moz-range-track {
|
input[type=range]::-moz-range-track {
|
||||||
-moz-appearance: range-track !important;
|
|
||||||
/* Prevent styling that would change the type of frame we construct. */
|
/* Prevent styling that would change the type of frame we construct. */
|
||||||
display: block !important;
|
display: block !important;
|
||||||
float: none !important;
|
float: none !important;
|
||||||
|
@ -935,7 +934,6 @@ input[type=range][orient=vertical]::-moz-range-track {
|
||||||
* is ignored.
|
* is ignored.
|
||||||
*/
|
*/
|
||||||
input[type=range]::-moz-range-progress {
|
input[type=range]::-moz-range-progress {
|
||||||
-moz-appearance: range-progress !important;
|
|
||||||
/* Prevent styling that would change the type of frame we construct. */
|
/* Prevent styling that would change the type of frame we construct. */
|
||||||
display: block !important;
|
display: block !important;
|
||||||
float: none !important;
|
float: none !important;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::media_queries::Device;
|
||||||
use crate::properties::{ComputedValues, StyleBuilder};
|
use crate::properties::{ComputedValues, StyleBuilder};
|
||||||
use crate::properties::{LonghandId, LonghandIdSet, CSSWideKeyword};
|
use crate::properties::{LonghandId, LonghandIdSet, CSSWideKeyword};
|
||||||
use crate::properties::{PropertyDeclaration, PropertyDeclarationId, DeclarationImportanceIterator};
|
use crate::properties::{PropertyDeclaration, PropertyDeclarationId, DeclarationImportanceIterator};
|
||||||
use crate::properties::{CASCADE_PROPERTY, ComputedValueFlags};
|
use crate::properties::CASCADE_PROPERTY;
|
||||||
use crate::rule_cache::{RuleCache, RuleCacheConditions};
|
use crate::rule_cache::{RuleCache, RuleCacheConditions};
|
||||||
use crate::rule_tree::StrongRuleNode;
|
use crate::rule_tree::StrongRuleNode;
|
||||||
use crate::selector_parser::PseudoElement;
|
use crate::selector_parser::PseudoElement;
|
||||||
|
@ -411,7 +411,6 @@ struct Cascade<'a, 'b: 'a> {
|
||||||
context: &'a mut computed::Context<'b>,
|
context: &'a mut computed::Context<'b>,
|
||||||
cascade_mode: CascadeMode<'a>,
|
cascade_mode: CascadeMode<'a>,
|
||||||
seen: LonghandIdSet,
|
seen: LonghandIdSet,
|
||||||
author_specified: LonghandIdSet,
|
|
||||||
reverted: PerOrigin<LonghandIdSet>,
|
reverted: PerOrigin<LonghandIdSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +420,6 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
context,
|
context,
|
||||||
cascade_mode,
|
cascade_mode,
|
||||||
seen: LonghandIdSet::default(),
|
seen: LonghandIdSet::default(),
|
||||||
author_specified: LonghandIdSet::default(),
|
|
||||||
reverted: Default::default(),
|
reverted: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,9 +557,6 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.seen.insert(physical_longhand_id);
|
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| {
|
let unset = css_wide_keyword.map_or(false, |css_wide_keyword| {
|
||||||
match css_wide_keyword {
|
match css_wide_keyword {
|
||||||
|
@ -684,15 +679,6 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
if let Some(svg) = builder.get_svg_if_mutated() {
|
if let Some(svg) = builder.get_svg_if_mutated() {
|
||||||
svg.fill_arrays();
|
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")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -713,26 +699,12 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let builder = &mut self.context.builder;
|
let cached_style = match cache.find(guards, &self.context.builder) {
|
||||||
|
|
||||||
let cached_style = match cache.find(guards, &builder) {
|
|
||||||
Some(style) => style,
|
Some(style) => style,
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
builder.copy_reset_from(cached_style);
|
self.context.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
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,20 +70,6 @@ bitflags! {
|
||||||
|
|
||||||
/// Whether this element is inside an `opacity: 0` subtree.
|
/// Whether this element is inside an `opacity: 0` subtree.
|
||||||
const IS_IN_OPACITY_ZERO_SUBTREE = 1 << 12;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -750,52 +750,6 @@ static ${name}: LonghandIdSet = LonghandIdSet {
|
||||||
};
|
};
|
||||||
</%def>
|
</%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
|
/// A set of longhand properties
|
||||||
#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)]
|
||||||
pub struct LonghandIdSet {
|
pub struct LonghandIdSet {
|
||||||
|
@ -883,29 +837,6 @@ impl LonghandIdSet {
|
||||||
&HAS_NO_EFFECT_ON_SCROLLBARS
|
&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.
|
/// Iterate over the current longhand id set.
|
||||||
pub fn iter(&self) -> LonghandIdSetIterator {
|
pub fn iter(&self) -> LonghandIdSetIterator {
|
||||||
LonghandIdSetIterator { longhands: self, cur: 0, }
|
LonghandIdSetIterator { longhands: self, cur: 0, }
|
||||||
|
@ -1067,6 +998,51 @@ 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.
|
/// An identifier for a given longhand property.
|
||||||
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
#[derive(Clone, Copy, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//! The rule tree.
|
//! The rule tree.
|
||||||
|
|
||||||
use crate::applicable_declarations::ApplicableDeclarationList;
|
use crate::applicable_declarations::ApplicableDeclarationList;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use crate::gecko::selector_parser::PseudoElement;
|
||||||
use crate::hash::{self, FxHashMap};
|
use crate::hash::{self, FxHashMap};
|
||||||
use crate::properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
|
use crate::properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
|
||||||
use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
|
use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
|
||||||
|
@ -1416,6 +1418,198 @@ 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<E>(
|
||||||
|
&self,
|
||||||
|
mut element: E,
|
||||||
|
mut pseudo: Option<PseudoElement>,
|
||||||
|
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.
|
/// Returns true if there is either animation or transition level rule.
|
||||||
pub fn has_animation_or_transition_rules(&self) -> bool {
|
pub fn has_animation_or_transition_rules(&self) -> bool {
|
||||||
self.self_and_ancestors()
|
self.self_and_ancestors()
|
||||||
|
|
|
@ -1630,11 +1630,7 @@ pub enum Appearance {
|
||||||
RadioLabel,
|
RadioLabel,
|
||||||
/// nsRangeFrame and its subparts
|
/// nsRangeFrame and its subparts
|
||||||
Range,
|
Range,
|
||||||
RangeThumb, // FIXME: This should not be exposed to content.
|
RangeThumb,
|
||||||
#[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 resizer background area in a status bar for the resizer widget in
|
||||||
/// the corner of a window.
|
/// the corner of a window.
|
||||||
#[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
|
#[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
|
||||||
|
@ -1860,14 +1856,6 @@ pub enum Appearance {
|
||||||
Count,
|
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.
|
/// A kind of break between two boxes.
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-break/#break-between
|
/// https://drafts.csswg.org/css-break/#break-between
|
||||||
|
|
|
@ -3723,6 +3723,31 @@ pub extern "C" fn Servo_SetExplicitStyle(element: &RawGeckoElement, style: &Comp
|
||||||
data.styles.primary = Some(unsafe { ArcBorrow::from_ref(style) }.clone_arc());
|
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(
|
fn get_pseudo_style(
|
||||||
guard: &SharedRwLockReadGuard,
|
guard: &SharedRwLockReadGuard,
|
||||||
element: GeckoElement,
|
element: GeckoElement,
|
||||||
|
|
|
@ -292,7 +292,8 @@ bool nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext,
|
||||||
aAppearance == StyleAppearance::MenulistButton) &&
|
aAppearance == StyleAppearance::MenulistButton) &&
|
||||||
aFrame->GetContent()->IsHTMLElement() &&
|
aFrame->GetContent()->IsHTMLElement() &&
|
||||||
aPresContext->HasAuthorSpecifiedRules(
|
aPresContext->HasAuthorSpecifiedRules(
|
||||||
aFrame, NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND);
|
aFrame,
|
||||||
|
NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsNativeTheme::IsDisabled(nsIFrame* aFrame, EventStates aEventStates) {
|
bool nsNativeTheme::IsDisabled(nsIFrame* aFrame, EventStates aEventStates) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче