diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 2508c8e14179..c79c53782c90 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2910,8 +2910,7 @@ nsContainerFrame* nsCSSFrameConstructor::ConstructPageFrame( "Page name from prev-in-flow should not have been null"); } RefPtr pageContentPseudoStyle = - styleSet->ResolvePageContentStyle(pageName, - StylePagePseudoClassFlags::NONE); + styleSet->ResolvePageContentStyle(pageName); nsContainerFrame* pageContentFrame = NS_NewPageContentFrame( aPresShell, pageContentPseudoStyle, pageName.forget()); diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp index 503b6aee4aa4..6f277190ee1a 100644 --- a/layout/generic/nsPageContentFrame.cpp +++ b/layout/generic/nsPageContentFrame.cpp @@ -419,8 +419,7 @@ void nsPageContentFrame::EnsurePageName() { return; } RefPtr pageContentPseudoStyle = - PresShell()->StyleSet()->ResolvePageContentStyle( - mPageName, StylePagePseudoClassFlags::FIRST); + PresShell()->StyleSet()->ResolvePageContentStyle(mPageName); SetComputedStyleWithoutNotification(pageContentPseudoStyle); } diff --git a/layout/reftests/css-page/pseudo-first-margin-001.html b/layout/reftests/css-page/pseudo-first-margin-001.html deleted file mode 100644 index 7d3cb95d3a99..000000000000 --- a/layout/reftests/css-page/pseudo-first-margin-001.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - -
-
- - diff --git a/layout/reftests/css-page/pseudo-first-margin-002.html b/layout/reftests/css-page/pseudo-first-margin-002.html deleted file mode 100644 index 67a4f54eebca..000000000000 --- a/layout/reftests/css-page/pseudo-first-margin-002.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - -
-
- - diff --git a/layout/reftests/css-page/pseudo-first-margin-003.html b/layout/reftests/css-page/pseudo-first-margin-003.html deleted file mode 100644 index 13388717424b..000000000000 --- a/layout/reftests/css-page/pseudo-first-margin-003.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - -
-
- - diff --git a/layout/reftests/css-page/pseudo-first-margin-ref.html b/layout/reftests/css-page/pseudo-first-margin-ref.html deleted file mode 100644 index 99ee55b561e1..000000000000 --- a/layout/reftests/css-page/pseudo-first-margin-ref.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
-
-
-
-
-
- - - diff --git a/layout/reftests/css-page/reftest.list b/layout/reftests/css-page/reftest.list index 8feca5423fd5..2228dc15b748 100644 --- a/layout/reftests/css-page/reftest.list +++ b/layout/reftests/css-page/reftest.list @@ -81,6 +81,3 @@ == page-name-two-page-034.html page-name-two-page-ref.html == page-name-two-page-035.html page-name-two-page-ref.html == page-name-zero-height-001.html page-name-zero-height-001-ref.html -== pseudo-first-margin-001.html pseudo-first-margin-ref.html -== pseudo-first-margin-002.html pseudo-first-margin-ref.html -== pseudo-first-margin-003.html pseudo-first-margin-ref.html diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index 24c974bdc510..e04fcadbf3a7 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -572,7 +572,7 @@ ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType) { } already_AddRefed ServoStyleSet::ResolvePageContentStyle( - const nsAtom* aPageName, const StylePagePseudoClassFlags& aPseudo) { + const nsAtom* aPageName) { // The empty atom is used to indicate no specified page name, and is not // usable as a page-rule selector. Changing this to null is a slight // optimization to avoid the Servo code from doing an unnecessary hashtable @@ -580,12 +580,10 @@ already_AddRefed ServoStyleSet::ResolvePageContentStyle( if (aPageName == nsGkAtoms::_empty) { aPageName = nullptr; } - // Only use the cache when we are doing a lookup for page styles without a - // page-name or any pseudo classes. - const bool useCache = !aPageName && !aPseudo; + // Only use the cache if we are not doing a lookup for a named page style. RefPtr& cache = mNonInheritingComputedStyles[nsCSSAnonBoxes::NonInheriting::pageContent]; - if (useCache && cache) { + if (!aPageName && cache) { RefPtr retval = cache; return retval.forget(); } @@ -593,11 +591,11 @@ already_AddRefed ServoStyleSet::ResolvePageContentStyle( UpdateStylistIfNeeded(); RefPtr computedValues = - Servo_ComputedValues_GetForPageContent(mRawData.get(), aPageName, aPseudo) + Servo_ComputedValues_GetForPageContent(mRawData.get(), aPageName) .Consume(); MOZ_ASSERT(computedValues); - if (useCache) { + if (!aPageName) { cache = computedValues; } return computedValues.forget(); @@ -687,8 +685,7 @@ StyleSheet* ServoStyleSet::SheetAt(Origin aOrigin, size_t aIndex) const { ServoStyleSet::FirstPageSizeAndOrientation ServoStyleSet::GetFirstPageSizeAndOrientation(const nsAtom* aFirstPageName) { FirstPageSizeAndOrientation retval; - const RefPtr style = - ResolvePageContentStyle(aFirstPageName, StylePagePseudoClassFlags::FIRST); + const RefPtr style = ResolvePageContentStyle(aFirstPageName); const StylePageSize& pageSize = style->StylePage()->mSize; if (pageSize.IsSize()) { diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h index 35a827dfda4b..c91241ef5d9b 100644 --- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -35,7 +35,6 @@ enum class StyleRuleChangeKind : uint32_t; template struct StyleTimingFunction; -struct StylePagePseudoClassFlags; struct StylePiecewiseLinearFunction; using StyleComputedTimingFunction = StyleTimingFunction; @@ -255,10 +254,9 @@ class ServoStyleSet { PseudoStyleType aType); // Get a ComputedStyle for a pageContent box with the specified page-name. - // A page name that is null or the empty atom and has no pseudo classes gets - // the global page style. + // A page name that is null or the empty atom gets the global page style. already_AddRefed ResolvePageContentStyle( - const nsAtom* aPageName, const StylePagePseudoClassFlags& aPseudo); + const nsAtom* aPageName); already_AddRefed ResolveXULTreePseudoStyle( dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag, diff --git a/servo/components/style/stylesheets/mod.rs b/servo/components/style/stylesheets/mod.rs index d8d9f7ce246d..b9a0ec98311f 100644 --- a/servo/components/style/stylesheets/mod.rs +++ b/servo/components/style/stylesheets/mod.rs @@ -59,8 +59,8 @@ pub use self::loader::StylesheetLoader; pub use self::media_rule::MediaRule; pub use self::namespace_rule::NamespaceRule; pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter}; +pub use self::page_rule::{PageRule, PageSelector, PageSelectors}; pub use self::property_rule::PropertyRule; -pub use self::page_rule::{PageRule, PagePseudoClassFlags, PageSelector, PageSelectors}; pub use self::rule_list::{CssRules, CssRulesHelpers}; pub use self::rule_parser::{InsertRuleContext, State, TopLevelRuleParser}; pub use self::rules_iterator::{AllRules, EffectiveRules}; diff --git a/servo/components/style/stylesheets/page_rule.rs b/servo/components/style/stylesheets/page_rule.rs index c917c1f4a538..5cd2458aa25b 100644 --- a/servo/components/style/stylesheets/page_rule.rs +++ b/servo/components/style/stylesheets/page_rule.rs @@ -12,205 +12,28 @@ use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use crate::str::CssStringWriter; use crate::values::{AtomIdent, CustomIdent}; -use cssparser::{Parser, SourceLocation, Token}; +use cssparser::{Parser, SourceLocation}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use servo_arc::Arc; use std::fmt::{self, Write}; -use smallvec::SmallVec; use style_traits::{CssWriter, ParseError, ToCss}; -macro_rules! page_pseudo_classes { - ($($(#[$($meta:tt)+])* $id:ident => $val:literal,)+) => { - /// [`@page`][page] rule pseudo-classes. - /// - /// https://drafts.csswg.org/css-page-3/#page-selectors - #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToShmem)] - #[repr(u8)] - pub enum PagePseudoClass { - $($(#[$($meta)+])* $id,)+ - } - impl PagePseudoClass { - fn parse<'i, 't>( - input: &mut Parser<'i, 't>, - ) -> Result> { - let loc = input.current_source_location(); - let colon = input.next_including_whitespace()?; - if *colon != Token::Colon { - return Err(loc.new_unexpected_token_error(colon.clone())); - } - - let ident = input.next_including_whitespace()?; - if let Token::Ident(s) = ident { - return match_ignore_ascii_case! { &**s, - $($val => Ok(PagePseudoClass::$id),)+ - _ => Err(loc.new_unexpected_token_error(Token::Ident(s.clone()))), - }; - } - Err(loc.new_unexpected_token_error(ident.clone())) - } - #[inline] - fn to_str(&self) -> &'static str { - match *self { - $(PagePseudoClass::$id => concat!(':', $val),)+ - } - } - } - } -} - -page_pseudo_classes! { - /// [`:first`][first] pseudo-class - /// - /// [first] https://drafts.csswg.org/css-page-3/#first-pseudo - First => "first", - /// [`:blank`][blank] pseudo-class - /// - /// [blank] https://drafts.csswg.org/css-page-3/#blank-pseudo - Blank => "blank", - /// [`:left`][left] pseudo-class - /// - /// [left]: https://drafts.csswg.org/css-page-3/#spread-pseudos - Left => "left", - /// [`:right`][right] pseudo-class - /// - /// [right]: https://drafts.csswg.org/css-page-3/#spread-pseudos - Right => "right", -} - -bitflags! { - /// Bit-flags for pseudo-class. This should only be used for querying if a - /// page-rule applies. - /// - /// https://drafts.csswg.org/css-page-3/#page-selectors - #[derive(Clone, Copy)] - #[repr(C)] - pub struct PagePseudoClassFlags : u8 { - /// No pseudo-classes - const NONE = 0; - /// Flag for PagePseudoClass::First - const FIRST = 1 << 0; - /// Flag for PagePseudoClass::Blank - const BLANK = 1 << 1; - /// Flag for PagePseudoClass::Left - const LEFT = 1 << 2; - /// Flag for PagePseudoClass::Right - const RIGHT = 1 << 3; - } -} - -impl PagePseudoClassFlags { - /// Creates a pseudo-class flags object with a single pseudo-class. - #[inline] - pub fn new(other: &PagePseudoClass) -> Self { - match *other { - PagePseudoClass::First => PagePseudoClassFlags::FIRST, - PagePseudoClass::Blank => PagePseudoClassFlags::BLANK, - PagePseudoClass::Left => PagePseudoClassFlags::LEFT, - PagePseudoClass::Right => PagePseudoClassFlags::RIGHT, - } - } - /// Checks if the given pseudo class applies to this set of flags. - #[inline] - pub fn contains_class(self, other: &PagePseudoClass) -> bool { - self.intersects(PagePseudoClassFlags::new(other)) - } -} - -type PagePseudoClasses = SmallVec<[PagePseudoClass; 4]>; - /// Type of a single [`@page`][page selector] /// +/// We do not support pseudo selectors yet. /// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors -#[derive(Clone, Debug, MallocSizeOf, ToShmem)] -pub struct PageSelector{ - /// Page name - /// - /// https://drafts.csswg.org/css-page-3/#page-type-selector - pub name: AtomIdent, - /// Pseudo-classes for [`@page`][page-selectors] - /// - /// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors - pub pseudos: PagePseudoClasses, -} +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] +pub struct PageSelector(pub AtomIdent); impl PageSelector { /// Checks if the ident matches a page-name's ident. /// - /// This does not take pseudo selectors into account. + /// This does not currently take pseudo selectors into account. #[inline] pub fn ident_matches(&self, other: &CustomIdent) -> bool { - self.name.0 == other.0 + self.0 .0 == other.0 } - - /// Checks that this selector matches the ident and all pseudo classes are - /// present in the provided flags. - #[inline] - pub fn matches(&self, name: &CustomIdent, flags: &PagePseudoClassFlags) -> bool { - self.ident_matches(name) && self.flags_match(flags) - } - - /// Checks that all pseudo classes in this selector are present in the - /// provided flags. - /// - /// Equivalent to, but may be more efficient than: - /// - /// ``` - /// match_specificity(flags).is_some() - /// ``` - pub fn flags_match(&self, flags: &PagePseudoClassFlags) -> bool { - self.pseudos.iter().all(|pc| flags.contains_class(pc)) - } - - /// Implements specificity calculation for a page selector given a set of - /// page pseudo-classes to match with. - /// If this selector includes any pseudo-classes that are not in the flags, - /// then this will return None. - /// - /// To fit the specificity calculation into a 32-bit value, this limits the - /// maximum count of :first and :blank to 32767, and the maximum count of - /// :left and :right to 65535. - /// - /// https://drafts.csswg.org/css-page-3/#cascading-and-page-context - pub fn match_specificity(&self, flags: &PagePseudoClassFlags) -> Option { - let mut g: usize = 0; - let mut h: usize = 0; - for pc in self.pseudos.iter() { - if !flags.contains_class(pc) { - return None - } - match pc { - PagePseudoClass::First | - PagePseudoClass::Blank => g += 1, - PagePseudoClass::Left | - PagePseudoClass::Right => h += 1, - } - } - let h = h.min(0xFFFF) as u32; - let g = (g.min(0x7FFF) as u32) << 16; - let f = if self.name.0.is_empty() { 0 } else { 0x80000000 }; - Some(h + g + f) - } -} - -impl ToCss for PageSelector { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write - { - self.name.to_css(dest)?; - for pc in self.pseudos.iter() { - dest.write_str(pc.to_str())?; - } - Ok(()) - } -} - -fn parse_page_name<'i, 't>( - input: &mut Parser<'i, 't> -) -> Result> { - let s = input.expect_ident()?; - Ok(AtomIdent::from(&**s)) } impl Parse for PageSelector { @@ -218,12 +41,8 @@ impl Parse for PageSelector { _context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let name = input.try_parse(parse_page_name).unwrap_or(AtomIdent(atom!(""))); - let mut pseudos = PagePseudoClasses::default(); - while let Ok(pc) = input.try_parse(PagePseudoClass::parse) { - pseudos.push(pc); - } - Ok(PageSelector{name, pseudos}) + let s = input.expect_ident()?; + Ok(PageSelector(AtomIdent::from(&**s))) } } @@ -289,22 +108,6 @@ impl PageRule { self.block.read_with(guard).size_of(ops) + self.selectors.size_of(ops) } - /// Computes the specificity of this page rule when matched with flags. - /// - /// Computing this value has linear-complexity with the size of the - /// selectors, so the caller should usually call this once and cache the - /// result. - /// - /// Returns None if the flags do not match this page rule. - /// - /// The return type is ordered by page-rule specificity. - pub fn match_specificity(&self, flags: &PagePseudoClassFlags) -> Option { - let mut specificity = None; - for s in self.selectors.0.iter().map(|s| s.match_specificity(flags)) { - specificity = s.max(specificity); - } - specificity - } } impl ToCssWithGuard for PageRule { diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs index ec4d9cb78f46..97385c3c520d 100644 --- a/servo/components/style/stylist.rs +++ b/servo/components/style/stylist.rs @@ -1600,23 +1600,36 @@ pub struct PageRuleData { pub rule: Arc>, } +/// Wrapper to allow better tracking of memory usage by page rule lists. +/// +/// This is meant to be used by the global page rule list which are already +/// sorted by layer ID, since all global page rules are less specific than all +/// named page rules that match a certain page. +#[derive(Clone, Debug, Deref, MallocSizeOf)] +pub struct PageRuleDataNoLayer( + #[ignore_malloc_size_of = "Arc, stylesheet measures as primary ref"] pub Arc>, +); + /// Stores page rules indexed by page names. #[derive(Clone, Debug, Default, MallocSizeOf)] pub struct PageRuleMap { - /// Page rules, indexed by page name. An empty atom indicates no page name. - pub rules: PrecomputedHashMap>, + /// Global, unnamed page rules. + pub global: LayerOrderedVec, + /// Named page rules + pub named: PrecomputedHashMap>, } impl PageRuleMap { #[inline] fn clear(&mut self) { - self.rules.clear(); + self.global.clear(); + self.named.clear(); } } impl MallocShallowSizeOf for PageRuleMap { fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.rules.shallow_size_of(ops) + self.global.size_of(ops) + self.named.shallow_size_of(ops) } } @@ -1682,15 +1695,20 @@ impl ExtraStyleData { layer: LayerId, ) -> Result<(), AllocErr> { let page_rule = rule.read_with(guard); - let mut add_rule = |name| { - let vec = self.pages.rules.entry(name).or_default(); - vec.push(PageRuleData{layer, rule: rule.clone()}); - }; if page_rule.selectors.0.is_empty() { - add_rule(atom!("")); + self.pages + .global + .push(PageRuleDataNoLayer(rule.clone()), layer); } else { - for selector in page_rule.selectors.as_slice() { - add_rule(selector.name.0.clone()); + // TODO: Handle pseudo-classes + self.pages.named.try_reserve(page_rule.selectors.0.len())?; + for name in page_rule.selectors.as_slice() { + let vec = self.pages.named.entry(name.0 .0.clone()).or_default(); + vec.try_reserve(1)?; + vec.push(PageRuleData { + layer, + rule: rule.clone(), + }); } } Ok(()) @@ -1701,6 +1719,7 @@ impl ExtraStyleData { self.font_feature_values.sort(layers); self.font_palette_values.sort(layers); self.counter_styles.sort(layers); + self.pages.global.sort(layers); } fn clear(&mut self) { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 10868bfca622..806a364f8385 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -106,7 +106,7 @@ use style::properties::{PropertyDeclarationId, ShorthandId}; use style::properties::{SourcePropertyDeclaration, StyleBuilder}; use style::properties_and_values::rule::Inherits as PropertyInherits; use style::rule_cache::RuleCacheConditions; -use style::rule_tree::{CascadeLevel, StrongRuleNode, StyleSource}; +use style::rule_tree::{CascadeLevel, StrongRuleNode}; use style::selector_parser::PseudoElementCascadeType; use style::shared_lock::{ Locked, SharedRwLock, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, @@ -122,9 +122,8 @@ use style::stylesheets::{ AllowImportRules, ContainerRule, CounterStyleRule, CssRule, CssRuleType, CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule, FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule, - Origin, OriginSet, PageRule, PagePseudoClassFlags, PropertyRule, SanitizationData, - SanitizationKind, StyleRule, StylesheetContents, StylesheetLoader as StyleStylesheetLoader, - SupportsRule, UrlExtraData, + Origin, OriginSet, PageRule, PropertyRule, SanitizationData, SanitizationKind, StyleRule, + StylesheetContents, StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData, }; use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist}; use style::thread_state; @@ -3864,7 +3863,6 @@ counter_style_descriptors! { pub unsafe extern "C" fn Servo_ComputedValues_GetForPageContent( raw_data: &PerDocumentStyleData, page_name: *const nsAtom, - flags: PagePseudoClassFlags, ) -> Strong { let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); @@ -3874,39 +3872,30 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForPageContent( let mut extra_declarations = vec![]; let iter = data.stylist.iter_extra_data_origins_rev(); for (data, origin) in iter { - let start = extra_declarations.len(); let level = match origin { Origin::UserAgent => CascadeLevel::UANormal, Origin::User => CascadeLevel::UserNormal, Origin::Author => CascadeLevel::same_tree_author_normal(), }; - let mut add_rule_with_name = |name: &Atom| { - if let Some(rules) = data.pages.rules.get(name) { - for rule_data in rules.iter() { - let rule = rule_data.rule.read_with(level.guard(&guards)); - if let Some(s) = rule.match_specificity(&flags) { - let block = rule.block.clone(); - extra_declarations.push(ApplicableDeclarationBlock::new( - StyleSource::from_declarations(block), - 0, - level, - s, - LayerOrder::root(), - )); - } - } - } + extra_declarations.reserve(data.pages.global.len()); + let mut add_rule = |rule: &Arc>| { + extra_declarations.push(ApplicableDeclarationBlock::from_declarations( + rule.read_with(level.guard(&guards)).block.clone(), + level, + LayerOrder::root(), + )); }; - // Add any nameless rules that match pseudo classes. - let empty_ = atom!(""); - add_rule_with_name(&empty_); - // Add any rules that match the name. - if !page_name.is_null() { - Atom::with(page_name, add_rule_with_name); + for &(ref rule, _layer_id) in data.pages.global.iter() { + add_rule(&rule.0); + } + if !page_name.is_null() { + Atom::with(page_name, |name| { + if let Some(rules) = data.pages.named.get(name) { + // Rules are already sorted by source order. + rules.iter().for_each(|d| add_rule(&d.rule)); + } + }); } - extra_declarations[start..].sort_unstable_by_key(|block| { - (block.layer_order(), block.specificity, block.source_order()) - }); } let rule_node = data.stylist.rule_node_for_precomputed_pseudo( diff --git a/testing/web-platform/meta/css/cssom/cssom-pagerule.html.ini b/testing/web-platform/meta/css/cssom/cssom-pagerule.html.ini new file mode 100644 index 000000000000..7d389e8fdf27 --- /dev/null +++ b/testing/web-platform/meta/css/cssom/cssom-pagerule.html.ini @@ -0,0 +1,8 @@ +[cssom-pagerule.html] + expected: + if (os == "android") and fission: [OK, TIMEOUT] + [Set selectorText to :left pseudo page] + expected: FAIL + + [Set selectorText to named page with :first pseudo page] + expected: FAIL diff --git a/testing/web-platform/tests/css/cssom/cssom-pagerule.html b/testing/web-platform/tests/css/cssom/cssom-pagerule.html index 994257b2450b..c7604eba3380 100644 --- a/testing/web-platform/tests/css/cssom/cssom-pagerule.html +++ b/testing/web-platform/tests/css/cssom/cssom-pagerule.html @@ -34,40 +34,6 @@ assert_equals(rule.selectorText, "named:first"); }, "Set selectorText to named page with :first pseudo page"); - test(() => { - rule.selectorText = "named:First"; - assert_equals(rule.selectorText, "named:first"); - }, "Set selectorText to named page with case insensitive :first pseudo page"); - - test(() => { - rule.selectorText = "named:first:first"; - assert_equals(rule.selectorText, "named:first:first"); - }, "Set selectorText to named page with two :first pseudo page"); - - test(() => { - rule.selectorText = "named:first:left:right:first"; - assert_equals(rule.selectorText, "named:first:left:right:first"); - }, "Set selectorText to named page with pseudo pages of " + - ":first, :left, :right, :first in order."); - - test(() => { - rule.selectorText = ""; - rule.selectorText = "named :first"; - assert_equals(rule.selectorText, ""); - }, "Cannot set selectorText to named page with pseudo, whitespace between"); - - test(() => { - rule.selectorText = ""; - rule.selectorText = ":first :left"; - assert_equals(rule.selectorText, ""); - }, "Cannot set selectorText to two pseudos, whitespace between"); - - test(() => { - rule.selectorText = ""; - rule.selectorText = ":notapagepseudo"; - assert_equals(rule.selectorText, ""); - }, "Cannot set selectorText to invalid pseudo page"); - test(() => { assert_equals(rule.parentStyleSheet, sheet); sheet.deleteRule(0);