servo: Merge #20456 - Remove nsCSSPseudoClasses and friends (from upsuper:remove-nscsspseudoclasses); r=emilio

This is the Servo side change of [bug 1449097](https://bugzilla.mozilla.org/show_bug.cgi?id=1449097) and [bug 1449089](https://bugzilla.mozilla.org/show_bug.cgi?id=1449089).

Source-Repo: https://github.com/servo/servo
Source-Revision: 97c12bd3927c057d5610b0295f0e8320b64af5e5

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : f63d725bb89e33c3dafa18714e4b77d8958675c6
This commit is contained in:
Xidorn Quan 2018-03-27 18:51:48 -04:00
Родитель f19d361797
Коммит 6ec573da45
6 изменённых файлов: 70 добавлений и 161 удалений

Просмотреть файл

@ -54,7 +54,6 @@ use gecko_bindings::structs::RawServoSelectorList;
use gecko_bindings::structs::RawServoSourceSizeList;
use gecko_bindings::structs::RefPtr;
use gecko_bindings::structs::RustString;
use gecko_bindings::structs::CSSPseudoClassType;
use gecko_bindings::structs::CSSPseudoElementType;
use gecko_bindings::structs::ServoTraversalFlags;
use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
@ -627,12 +626,6 @@ extern "C" {
extern "C" {
pub fn Gecko_IsRootElement(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" {
pub fn Gecko_MatchesElement(
type_: CSSPseudoClassType,
element: RawGeckoElementBorrowed,
) -> bool;
}
extern "C" {
pub fn Gecko_MatchLang(
element: RawGeckoElementBorrowed,
@ -647,6 +640,12 @@ extern "C" {
extern "C" {
pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument) -> nsIDocument_DocumentTheme;
}
extern "C" {
pub fn Gecko_IsTableBorderNonzero(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" {
pub fn Gecko_IsBrowserFrame(element: RawGeckoElementBorrowed) -> bool;
}
extern "C" {
pub fn Gecko_AtomAttrValue(
element: RawGeckoElementBorrowed,

Просмотреть файл

@ -12267,97 +12267,6 @@ pub mod root {
)
);
}
pub type CSSPseudoClassTypeBase = u8;
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CSSPseudoClassType {
empty = 0,
mozOnlyWhitespace = 1,
lang = 2,
root = 3,
any = 4,
firstChild = 5,
firstNode = 6,
lastChild = 7,
lastNode = 8,
onlyChild = 9,
firstOfType = 10,
lastOfType = 11,
onlyOfType = 12,
nthChild = 13,
nthLastChild = 14,
nthOfType = 15,
nthLastOfType = 16,
mozIsHTML = 17,
mozNativeAnonymous = 18,
mozUseShadowTreeRoot = 19,
mozLocaleDir = 20,
mozLWTheme = 21,
mozLWThemeBrightText = 22,
mozLWThemeDarkText = 23,
mozWindowInactive = 24,
mozTableBorderNonzero = 25,
mozBrowserFrame = 26,
scope = 27,
negation = 28,
dir = 29,
link = 30,
mozAnyLink = 31,
anyLink = 32,
visited = 33,
active = 34,
checked = 35,
disabled = 36,
enabled = 37,
focus = 38,
focusWithin = 39,
hover = 40,
mozDragOver = 41,
target = 42,
indeterminate = 43,
mozDevtoolsHighlighted = 44,
mozStyleeditorTransitioning = 45,
fullscreen = 46,
mozFullScreen = 47,
mozFocusRing = 48,
mozBroken = 49,
mozLoading = 50,
mozUserDisabled = 51,
mozSuppressed = 52,
mozHandlerClickToPlay = 53,
mozHandlerVulnerableUpdatable = 54,
mozHandlerVulnerableNoUpdate = 55,
mozHandlerDisabled = 56,
mozHandlerBlocked = 57,
mozHandlerCrashed = 58,
mozMathIncrementScriptLevel = 59,
mozHasDirAttr = 60,
mozDirAttrLTR = 61,
mozDirAttrRTL = 62,
mozDirAttrLikeAuto = 63,
mozAutofill = 64,
mozAutofillPreview = 65,
required = 66,
optional = 67,
valid = 68,
invalid = 69,
inRange = 70,
outOfRange = 71,
defaultPseudo = 72,
placeholderShown = 73,
mozReadOnly = 74,
mozReadWrite = 75,
mozSubmitInvalid = 76,
mozUIInvalid = 77,
mozUIValid = 78,
mozMeterOptimum = 79,
mozMeterSubOptimum = 80,
mozMeterSubSubOptimum = 81,
mozPlaceholder = 82,
Count = 83,
NotPseudo = 84,
MAX = 85,
}
#[repr(C)]
pub struct GeckoFont {
pub gecko: root::nsStyleFont,

Просмотреть файл

@ -28,9 +28,6 @@
*
* :scope -> <style scoped>, pending discussion.
*
* This follows the order defined in layout/style/nsCSSPseudoClassList.h when
* possible.
*
* $gecko_type can be either "_" or an ident in Gecko's CSSPseudoClassType.
* $state can be either "_" or an expression of type ElementState. If present,
* the semantics are that the pseudo-class matches if any of the bits in

Просмотреть файл

@ -6,7 +6,7 @@
use cssparser::{BasicParseError, BasicParseErrorKind, Parser, ToCss, Token, CowRcStr, SourceLocation};
use element_state::{DocumentState, ElementState};
use gecko_bindings::structs::{self, CSSPseudoClassType};
use gecko_bindings::structs;
use gecko_bindings::structs::RawServoSelectorList;
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
use invalidation::element::document_state::InvalidationMatchingData;
@ -133,6 +133,22 @@ impl Visit for NonTSPseudoClass {
impl NonTSPseudoClass {
/// Parses the name and returns a non-ts-pseudo-class if succeeds.
/// None otherwise. It doesn't check whether the pseudo-class is enabled
/// in a particular state.
pub fn parse_non_functional(name: &str) -> Option<Self> {
macro_rules! pseudo_class_parse {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match_ignore_ascii_case! { &name,
$($css => Some(NonTSPseudoClass::$name),)*
_ => None,
}
}
}
apply_non_ts_list!(pseudo_class_parse)
}
/// Returns true if this pseudo-class has any of the given flags set.
fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool {
macro_rules! check_flag {
@ -242,28 +258,6 @@ impl NonTSPseudoClass {
)
}
/// Convert NonTSPseudoClass to Gecko's CSSPseudoClassType.
pub fn to_gecko_pseudoclasstype(&self) -> Option<CSSPseudoClassType> {
macro_rules! gecko_type {
(_) => (None);
($gecko_type:ident) =>
(Some(::gecko_bindings::structs::CSSPseudoClassType::$gecko_type));
}
macro_rules! pseudo_class_geckotype {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match *self {
$(NonTSPseudoClass::$name => gecko_type!($gecko_type),)*
$(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)*
NonTSPseudoClass::MozLocaleDir(_) => gecko_type!(mozLocaleDir),
NonTSPseudoClass::Dir(_) => gecko_type!(dir),
NonTSPseudoClass::MozAny(_) => gecko_type!(any),
}
}
}
apply_non_ts_list!(pseudo_class_geckotype)
}
/// Returns true if the evaluation of the pseudo-class depends on the
/// element's attributes.
pub fn is_attr_based(&self) -> bool {
@ -373,23 +367,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
location: SourceLocation,
name: CowRcStr<'i>,
) -> Result<NonTSPseudoClass, ParseError<'i>> {
macro_rules! pseudo_class_parse {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match_ignore_ascii_case! { &name,
$($css => NonTSPseudoClass::$name,)*
_ => return Err(location.new_custom_error(
SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())
))
}
if let Some(pseudo_class) = NonTSPseudoClass::parse_non_functional(&name) {
if self.is_pseudo_class_enabled(&pseudo_class) {
return Ok(pseudo_class);
}
}
let pseudo_class = apply_non_ts_list!(pseudo_class_parse);
if self.is_pseudo_class_enabled(&pseudo_class) {
Ok(pseudo_class)
} else {
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
}
Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name)))
}
fn parse_non_ts_functional_pseudo_class<'t>(

Просмотреть файл

@ -32,7 +32,6 @@ use gecko_bindings::bindings;
use gecko_bindings::bindings::{Gecko_ConstructStyleChildrenIterator, Gecko_DestroyStyleChildrenIterator};
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_IsRootElement, Gecko_MatchesElement};
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_ElementHasAnimations;
@ -814,6 +813,21 @@ impl<'le> GeckoElement<'le> {
(!self.as_node().is_in_shadow_tree() && self.has_xbl_binding_parent())
}
/// Returns true if this node is the shadow root of an use-element shadow tree.
#[inline]
fn is_root_of_use_element_shadow_tree(&self) -> bool {
if !self.is_root_of_anonymous_subtree() {
return false
}
match self.parent_element() {
Some(e) => {
e.local_name() == &*local_name!("use") &&
e.namespace() == &*ns!("http://www.w3.org/2000/svg")
},
None => false,
}
}
fn css_transitions_info(&self) -> FnvHashMap<LonghandId, Arc<AnimationValue>> {
use gecko_bindings::bindings::Gecko_ElementTransitions_EndValueAt;
use gecko_bindings::bindings::Gecko_ElementTransitions_Length;
@ -1981,7 +1995,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
}
unsafe {
Gecko_IsRootElement(self.0)
bindings::Gecko_IsRootElement(self.0)
}
}
@ -2103,11 +2117,17 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
}
true
}
NonTSPseudoClass::MozTableBorderNonzero |
NonTSPseudoClass::MozBrowserFrame |
NonTSPseudoClass::MozNativeAnonymous |
NonTSPseudoClass::MozUseShadowTreeRoot => unsafe {
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
NonTSPseudoClass::MozNativeAnonymous => {
self.is_in_native_anonymous_subtree()
}
NonTSPseudoClass::MozUseShadowTreeRoot => {
self.is_root_of_use_element_shadow_tree()
}
NonTSPseudoClass::MozTableBorderNonzero => unsafe {
bindings::Gecko_IsTableBorderNonzero(self.0)
}
NonTSPseudoClass::MozBrowserFrame => unsafe {
bindings::Gecko_IsBrowserFrame(self.0)
},
NonTSPseudoClass::MozIsHTML => {
self.is_html_element_in_html_document()
@ -2235,20 +2255,10 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
#[inline]
fn blocks_ancestor_combinators(&self) -> bool {
if !self.is_root_of_anonymous_subtree() {
return false
}
match self.parent_element() {
Some(e) => {
// If this element is the shadow root of an use-element shadow
// tree, according to the spec, we should not match rules
// cross the shadow DOM boundary.
e.local_name() == &*local_name!("use") &&
e.namespace() == &*ns!("http://www.w3.org/2000/svg")
},
None => false,
}
// If this element is the shadow root of an use-element shadow tree,
// according to the spec, we should not match rules cross the shadow
// DOM boundary.
self.is_root_of_use_element_shadow_tree()
}
}

Просмотреть файл

@ -31,7 +31,7 @@ use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product}
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
use style::gecko::restyle_damage::GeckoRestyleDamage;
use style::gecko::selector_parser::PseudoElement;
use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement};
use style::gecko::traversal::RecalcStyleOnly;
use style::gecko::wrapper::{GeckoElement, GeckoNode};
use style::gecko_bindings::bindings;
@ -5115,3 +5115,14 @@ pub extern "C" fn Servo_ParseCounterStyleDescriptor(
result,
).is_ok()
}
#[no_mangle]
pub unsafe extern "C" fn Servo_PseudoClass_GetStates(name: *const nsACString) -> u64 {
let name = name.as_ref().unwrap().as_str_unchecked();
match NonTSPseudoClass::parse_non_functional(name) {
None => 0,
// Ignore :any-link since it contains both visited and unvisited state.
Some(NonTSPseudoClass::AnyLink) => 0,
Some(pseudo_class) => pseudo_class.state_flag().bits(),
}
}