Bug 1830369 - [css-nesting] Update cssparser to allow parsing qualified rules along with declarations. r=tlouw,supply-chain-reviewers

No implementation just yet (the default QualifiedRuleParser
implementation just rejects stuff), but this is plumbing that I'd rather
get reviewed separately.

Differential Revision: https://phabricator.services.mozilla.com/D176686
This commit is contained in:
Emilio Cobos Álvarez 2023-04-29 18:21:25 +00:00
Родитель 9acd8521cd
Коммит 8d2220d803
28 изменённых файлов: 258 добавлений и 178 удалений

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

@ -105,9 +105,9 @@ git = "https://github.com/mozilla/uniffi-rs.git"
rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de"
replace-with = "vendored-sources"
[source."git+https://github.com/servo/rust-cssparser?rev=45bc47e2bcb846f1efb5aea156be5fe7d18624bf"]
[source."git+https://github.com/servo/rust-cssparser?rev=3e1bd05139cb7174ace395d498ca7128feb8f69d"]
git = "https://github.com/servo/rust-cssparser"
rev = "45bc47e2bcb846f1efb5aea156be5fe7d18624bf"
rev = "3e1bd05139cb7174ace395d498ca7128feb8f69d"
replace-with = "vendored-sources"

6
Cargo.lock сгенерированный
Просмотреть файл

@ -1016,8 +1016,8 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.30.0"
source = "git+https://github.com/servo/rust-cssparser?rev=45bc47e2bcb846f1efb5aea156be5fe7d18624bf#45bc47e2bcb846f1efb5aea156be5fe7d18624bf"
version = "0.31.0"
source = "git+https://github.com/servo/rust-cssparser?rev=3e1bd05139cb7174ace395d498ca7128feb8f69d#3e1bd05139cb7174ace395d498ca7128feb8f69d"
dependencies = [
"cssparser-macros",
"dtoa-short",
@ -1032,7 +1032,7 @@ dependencies = [
[[package]]
name = "cssparser-macros"
version = "0.6.0"
source = "git+https://github.com/servo/rust-cssparser?rev=45bc47e2bcb846f1efb5aea156be5fe7d18624bf#45bc47e2bcb846f1efb5aea156be5fe7d18624bf"
source = "git+https://github.com/servo/rust-cssparser?rev=3e1bd05139cb7174ace395d498ca7128feb8f69d#3e1bd05139cb7174ace395d498ca7128feb8f69d"
dependencies = [
"quote",
"syn",

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

@ -163,7 +163,7 @@ midir = { git = "https://github.com/mozilla/midir.git", rev = "519e651241e867af3
# warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }
cssparser = { git = "https://github.com/servo/rust-cssparser", rev = "45bc47e2bcb846f1efb5aea156be5fe7d18624bf" }
cssparser = { git = "https://github.com/servo/rust-cssparser", rev = "3e1bd05139cb7174ace395d498ca7128feb8f69d" }
# application-services overrides to make updating them all simpler.
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "86c84c217036c12283d19368867323a66bf35883" }

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

@ -31,7 +31,7 @@ accountable-refcell = { version = "0.2.0", optional = true }
app_units = "0.7"
content-security-policy = { version = "0.4.0", features = ["serde"], optional = true }
crossbeam-channel = { version = "0.4", optional = true }
cssparser = "0.30"
cssparser = "0.31"
dom = { path = "../../../dom/base/rust" }
euclid = "0.22"
hyper = { version = "0.12", optional = true }

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

@ -20,7 +20,7 @@ bench = []
[dependencies]
bitflags = "1.0"
matches = "0.1"
cssparser = "0.30"
cssparser = "0.31"
derive_more = { version = "0.99", default-features = false, features = ["add", "add_assign"] }
fxhash = "0.2"
log = "0.4"

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

@ -32,7 +32,7 @@ arrayvec = "0.7"
atomic_refcell = "0.1"
bitflags = "1.0"
byteorder = "1.0"
cssparser = "0.30"
cssparser = "0.31"
derive_more = { version = "0.99", default-features = false, features = ["add", "add_assign", "deref", "from"] }
dom = { path = "../../../dom/base/rust" }
new_debug_unreachable = "1.0"

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

@ -13,7 +13,7 @@ use crate::str::CssStringWriter;
use crate::values::specified::Integer;
use crate::values::CustomIdent;
use crate::Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, QualifiedRuleParser};
use cssparser::{CowRcStr, Parser, SourceLocation, Token};
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
@ -153,6 +153,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for CounterStyleRuleParser<'a, 'b> {
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for CounterStyleRuleParser<'a, 'b> {
type Prelude = ();
type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>;
}
macro_rules! checker {
($self:ident._($value:ident)) => {};
($self:ident. $checker:ident($value:ident)) => {

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

@ -14,18 +14,20 @@ use crate::shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use crate::str::CssStringWriter;
use crate::values::computed::font::{FamilyName, FontStretch};
use crate::values::generics::font::FontStyle as GenericFontStyle;
#[cfg(feature = "gecko")]
use crate::values::specified::font::{FontFeatureSettings, FontVariationSettings};
use crate::values::specified::font::SpecifiedFontStyle;
use crate::values::specified::font::{
AbsoluteFontWeight, FontStretch as SpecifiedFontStretch, MetricsOverride,
};
#[cfg(feature = "gecko")]
use crate::values::specified::font::{FontFeatureSettings, FontVariationSettings};
use crate::values::specified::url::SpecifiedUrl;
use crate::values::specified::{Angle, NonNegativePercentage};
#[cfg(feature = "gecko")]
use cssparser::UnicodeRange;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{CowRcStr, SourceLocation};
use cssparser::{
AtRuleParser, CowRcStr, DeclarationListParser, DeclarationParser, Parser, QualifiedRuleParser,
SourceLocation,
};
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError};
@ -541,6 +543,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for FontFaceRuleParser<'a, 'b> {
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for FontFaceRuleParser<'a, 'b> {
type Prelude = ();
type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>;
}
impl Parse for Source {
fn parse<'i, 't>(
context: &ParserContext,

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

@ -18,10 +18,12 @@ use crate::selector_map::PrecomputedHashSet;
use crate::selector_parser::SelectorImpl;
use crate::shared_lock::Locked;
use crate::str::{CssString, CssStringWriter};
use crate::stylesheets::{CssRuleType, Origin, UrlExtraData, layer_rule::LayerOrder};
use crate::stylesheets::{layer_rule::LayerOrder, CssRuleType, Origin, UrlExtraData};
use crate::values::computed::Context;
use cssparser::{parse_important, CowRcStr, DeclarationListParser, ParserInput};
use cssparser::{AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind, Parser};
use cssparser::{
parse_important, AtRuleParser, CowRcStr, DeclarationListParser, DeclarationParser, Delimiter,
ParseErrorKind, Parser, ParserInput, QualifiedRuleParser,
};
use itertools::Itertools;
use selectors::SelectorList;
use smallbitvec::{self, SmallBitVec};
@ -915,10 +917,7 @@ impl PropertyDeclarationBlock {
&self,
context: &Context,
) -> Option<Arc<crate::custom_properties::CustomPropertiesMap>> {
self.cascade_custom_properties(
context.style().custom_properties(),
context.device(),
)
self.cascade_custom_properties(context.style().custom_properties(), context.device())
}
/// Returns a custom properties map which is the result of cascading custom
@ -933,7 +932,13 @@ impl PropertyDeclarationBlock {
for declaration in self.normal_declaration_iter() {
if let PropertyDeclaration::Custom(ref declaration) = *declaration {
builder.cascade(declaration, CascadePriority::new(CascadeLevel::same_tree_author_normal(), LayerOrder::root()));
builder.cascade(
declaration,
CascadePriority::new(
CascadeLevel::same_tree_author_normal(),
LayerOrder::root(),
),
);
}
}
@ -1097,12 +1102,11 @@ impl PropertyDeclarationBlock {
// 3.4.7:
// Let value be the result of invoking serialize a CSS value
// of current longhands.
let appendable_value = match shorthand
.get_shorthand_appendable_value(&current_longhands)
{
None => continue,
Some(appendable_value) => appendable_value,
};
let appendable_value =
match shorthand.get_shorthand_appendable_value(&current_longhands) {
None => continue,
Some(appendable_value) => appendable_value,
};
// We avoid re-serializing if we're already an
// AppendableValue::Css.
@ -1125,7 +1129,9 @@ impl PropertyDeclarationBlock {
AppendableValue::Css({
// Safety: serialization only generates valid utf-8.
#[cfg(feature = "gecko")]
unsafe { v.as_str_unchecked() }
unsafe {
v.as_str_unchecked()
}
#[cfg(feature = "servo")]
&v
})
@ -1356,6 +1362,13 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> {
type Error = StyleParseErrorKind<'i>;
}
/// Default methods reject all rules.
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for PropertyDeclarationParser<'a, 'b> {
type Prelude = ();
type QualifiedRule = Importance;
type Error = StyleParseErrorKind<'i>;
}
/// Based on NonMozillaVendorIdentifier from Gecko's CSS parser.
fn is_non_mozilla_vendor_identifier(name: &str) -> bool {
(name.starts_with("-") && !name.starts_with("-moz-")) || name.starts_with("_")

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

@ -18,9 +18,10 @@ use crate::stylesheets::CssRuleType;
use crate::values::computed::font::FamilyName;
use crate::values::serialize_atom_identifier;
use crate::Atom;
use cssparser::{AtRuleParser, BasicParseErrorKind, CowRcStr};
use cssparser::{DeclarationListParser, DeclarationParser, Parser};
use cssparser::{ParserState, QualifiedRuleParser, RuleListParser, SourceLocation, Token};
use cssparser::{
AtRuleParser, BasicParseErrorKind, CowRcStr, DeclarationListParser, DeclarationParser, Parser,
ParserState, QualifiedRuleParser, RuleListParser, SourceLocation, Token,
};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
@ -193,6 +194,12 @@ impl<'a, 'b, 'i, T> AtRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> {
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i, T> QualifiedRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> {
type Prelude = ();
type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T>
where
T: Parse,

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

@ -636,6 +636,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for KeyframeDeclarationParser<'a, 'b> {
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for KeyframeDeclarationParser<'a, 'b> {
type Prelude = ();
type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> {
type Declaration = ();
type Error = StyleParseErrorKind<'i>;

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

@ -24,8 +24,10 @@ use crate::values::generics::NonNegative;
use crate::values::specified::{self, NoCalcLength};
use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercentageLength};
use app_units::Au;
use cssparser::CowRcStr;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{
parse_important, AtRuleParser, CowRcStr, DeclarationListParser, DeclarationParser, Parser,
QualifiedRuleParser,
};
use euclid::Size2D;
use selectors::parser::SelectorParseErrorKind;
use std::borrow::Cow;
@ -245,6 +247,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for ViewportRuleParser<'a, 'b> {
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> QualifiedRuleParser<'i> for ViewportRuleParser<'a, 'b> {
type Prelude = ();
type QualifiedRule = Vec<ViewportDescriptorDeclaration>;
type Error = StyleParseErrorKind<'i>;
}
impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
type Declaration = Vec<ViewportDescriptorDeclaration>;
type Error = StyleParseErrorKind<'i>;

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

@ -16,7 +16,7 @@ gecko = []
[dependencies]
app_units = "0.7"
bitflags = "1.0"
cssparser = "0.30"
cssparser = "0.31"
euclid = "0.22"
lazy_static = "1"
malloc_size_of = { path = "../malloc_size_of" }

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

@ -14,7 +14,7 @@ servo = ["cssparser/serde", "string_cache"]
gecko = []
[dependencies]
cssparser = "0.30"
cssparser = "0.31"
servo_arc = { path = "../servo_arc" }
smallbitvec = "2.1.1"
smallvec = "1.0"

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

@ -15,7 +15,7 @@ gecko_refcount_logging = ["style/gecko_refcount_logging", "servo_arc/gecko_refco
[dependencies]
atomic_refcell = "0.1"
bincode = "1.0"
cssparser = "0.30"
cssparser = "0.31"
cstr = "0.2"
dom = { path = "../../../dom/base/rust" }
gecko-profiler = { path = "../../../tools/profiler/rust-api" }

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

@ -12,7 +12,7 @@ doctest = false
[dependencies]
byteorder = "1.0"
app_units = "0.7"
cssparser = "0.30"
cssparser = "0.31"
euclid = "0.22"
html5ever = "0.22"
parking_lot = "0.10"

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

@ -600,27 +600,11 @@ to a match expression.
"""
[[audits.cssparser-macros]]
who = "Tiaan Louw <tlouw@mozilla.com>"
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
criteria = "safe-to-deploy"
delta = "0.6.0 -> 0.6.0@git:45bc47e2bcb846f1efb5aea156be5fe7d18624bf"
notes = "Latest version of changes to the cssparser pulled from master branch."
[[audits.cssparser-macros]]
who = "Tiaan Louw <tlouw@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.6.0 -> 0.6.0@git:722b30d2f1634714befab967ecae627813fa4cf0"
delta = "0.6.0 -> 0.6.0@git:3e1bd05139cb7174ace395d498ca7128feb8f69d"
notes = "We are pulling this package from a non crates.io source until the changes are published. No changes were made to the code."
[[audits.cssparser-macros]]
who = "Tiaan Louw <tlouw@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.6.0 -> 0.6.0@git:b196a164dcbb317016d4aa6c58c13147e6045ebb"
[[audits.cssparser-macros]]
who = "Tiaan Louw <tlouw@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.6.0 -> 0.6.0@git:d3670a89bae26ba3a8db4758eb7976616113987d"
[[audits.cstr]]
who = "Emilio Cobos Álvarez <emilio@crisal.io>"
criteria = "safe-to-deploy"

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

@ -1 +1 @@
{"files":{".github/workflows/main.yml":"d66f2aac0764ebb09540737931fe2b9311e7033a2bf9a116c072cae6bec5e187","Cargo.toml":"50e9595b9b5243dab2200c2006ea9aed05e68118a9109e3320bda3d3bd82924b","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"53a6805edd80f642473514cb93f1f4197e17a911d66a2dfcefc3dc5e82bac206","build.rs":"b30f35bfbd713943822a19ce6ebe5c99017f603cb001ed37354020549aec71fc","build/match_byte.rs":"f57faf0597cb7b3e32999c5fb1215a43a5603121588c67d5031f720362171e1c","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"788898ddc0dec90fc972091642f37ab769fc818199293b8dc1c59c21ad0d3d00","src/cow_rc_str.rs":"89b5dff5cf80eef3fcff0c11799e54a978d02d8b8963a621fbb999d35e7c03a3","src/from_bytes.rs":"b1cf15c4e975523fef46b575598737a39f3c63e5ce0b2bfd6ec627c69c6ea54a","src/lib.rs":"9a6b8657291eb142cd33972eaba1afd8fb2432b96b061687238278fecc3e0de1","src/macros.rs":"0d4c3d27a22677d9eb3616d7f7af604dc3de2932ca04fd1c036102884cd6f079","src/nth.rs":"2fc26915f0a36cb22ac45dd9a7ecbdc64c327b2ec135370258ec3db9f9985460","src/parser.rs":"f9985187ede4361a29b3bf22d248903343d58e5cf369a9b5e046961356a4faf9","src/rules_and_declarations.rs":"d826f82f8c179fc13756b92336556e3ee40a273314ef774f95af71e687745f2a","src/serializer.rs":"3a0155521676deea9a6327c2ed00af6d5dabb29a97e2341d0f565f8c2b66d0a3","src/size_of_tests.rs":"da0cbcaa304f7800e9122e2bce0a11d42a70b9012e646a723cb23ee74a6b858c","src/tests.rs":"9847bd8a60bda34259d2900e2b2d217e4c4a0e7dc6e410c61eee3b0e805b9a7e","src/tokenizer.rs":"71600903284f1d68a7da6b69c938b31f9d641f8d981c7adfd06a3c8b783541f2","src/unicode_range.rs":"20d96f06fbb73921e308cc340c9fe065e27f19843005689fb259007a6a372bcc"},"package":null}
{"files":{".github/workflows/main.yml":"73c57dbb2c5471de2fcba828e356d09931ae89176f3bb695029b169dbb3f696f","Cargo.toml":"ad9de3a9ca008259eb361bc7150e70ca2a20e1a6af6d85d89288a4a1371b7f32","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"53a6805edd80f642473514cb93f1f4197e17a911d66a2dfcefc3dc5e82bac206","build.rs":"b30f35bfbd713943822a19ce6ebe5c99017f603cb001ed37354020549aec71fc","build/match_byte.rs":"f57faf0597cb7b3e32999c5fb1215a43a5603121588c67d5031f720362171e1c","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"df7d97636896df02b7ba56abf6f74f121d8320615f9e6ef6d43e6f272d3600cb","src/cow_rc_str.rs":"22d6829ab54c51486af4bacf5f184a6c95c15febdbbd5630a98b995ed0ee3e55","src/from_bytes.rs":"b1cf15c4e975523fef46b575598737a39f3c63e5ce0b2bfd6ec627c69c6ea54a","src/lib.rs":"445e7b09b906014cffa0330a34ac7fcb011288cf370549d24883c8570219140f","src/macros.rs":"4462d7063e10e892ae9542074374422ca38bcffc0638f8a87343b049fef5504f","src/nth.rs":"2fc26915f0a36cb22ac45dd9a7ecbdc64c327b2ec135370258ec3db9f9985460","src/parser.rs":"c47a34d302dc458cb84a7ec9377cc94eb613d2365efa414b783f130d77dd6fe6","src/rules_and_declarations.rs":"011d0411106762b4241928907bab225d4c1a1191c220ed852ec228c1a38b8578","src/serializer.rs":"3a0155521676deea9a6327c2ed00af6d5dabb29a97e2341d0f565f8c2b66d0a3","src/size_of_tests.rs":"da0cbcaa304f7800e9122e2bce0a11d42a70b9012e646a723cb23ee74a6b858c","src/tests.rs":"58dba29c73a59fb45a0fe1810cfee1d018aa427dcd6bae8cc5d8f17d5230fba8","src/tokenizer.rs":"6fd5b9f3a89a87bf9334cc4765ad76e080ab6aaec73d996f052558480a3f007a","src/unicode_range.rs":"20d96f06fbb73921e308cc340c9fe065e27f19843005689fb259007a6a372bcc"},"package":null}

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

@ -16,7 +16,7 @@ jobs:
- nightly
- beta
- stable
- 1.56.0
- 1.63.0
features:
-
- --features dummy_match_byte
@ -35,10 +35,6 @@ jobs:
toolchain: ${{ matrix.toolchain }}
override: true
- name: Downgrade phf to a version compatible with the MSRV
run: cargo update --package phf --precise 0.10.1
if: matrix.toolchain == '1.40.0'
- name: Cargo build
run: cargo build ${{ matrix.features }}

4
third_party/rust/cssparser/Cargo.toml поставляемый
Просмотреть файл

@ -11,9 +11,9 @@
[package]
edition = "2018"
rust-version = "1.56"
rust-version = "1.63"
name = "cssparser"
version = "0.30.0"
version = "0.31.0"
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
build = "build.rs"
exclude = [

89
third_party/rust/cssparser/src/color.rs поставляемый
Просмотреть файл

@ -2,6 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Allow text like <color> in docs.
#![allow(rustdoc::invalid_html_tags)]
use std::f32::consts::PI;
use std::fmt;
use std::str::FromStr;
@ -23,7 +26,7 @@ where
}
}
/// https://drafts.csswg.org/css-color-4/#serializing-alpha-values
/// <https://drafts.csswg.org/css-color-4/#serializing-alpha-values>
#[inline]
fn serialize_alpha(
dest: &mut impl fmt::Write,
@ -53,14 +56,13 @@ fn serialize_alpha(
// Guaratees hue in [0..360)
fn normalize_hue(hue: f32) -> f32 {
// https://drafts.csswg.org/css-values/#angles
// <https://drafts.csswg.org/css-values/#angles>
// Subtract an integer before rounding, to avoid some rounding errors:
hue - 360.0 * (hue / 360.0).floor()
}
/// A color with red, green, blue, and alpha components, in a byte each.
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct RGBA {
/// The red component.
pub red: Option<u8>,
@ -150,6 +152,7 @@ impl ToCss for RGBA {
}
}
/// Color specified by hue, saturation and lightness components.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct Hsl {
/// The hue component.
@ -163,6 +166,7 @@ pub struct Hsl {
}
impl Hsl {
/// Construct a new HSL color from it's components.
pub fn new(
hue: Option<f32>,
saturation: Option<f32>,
@ -215,6 +219,7 @@ impl<'de> Deserialize<'de> for Hsl {
}
}
/// Color specified by hue, whiteness and blackness components.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct Hwb {
/// The hue component.
@ -228,6 +233,7 @@ pub struct Hwb {
}
impl Hwb {
/// Construct a new HWB color from it's components.
pub fn new(
hue: Option<f32>,
whiteness: Option<f32>,
@ -285,7 +291,6 @@ impl<'de> Deserialize<'de> for Hwb {
/// Color specified by lightness, a- and b-axis components.
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct Lab {
/// The lightness component.
pub lightness: Option<f32>,
@ -299,7 +304,6 @@ pub struct Lab {
/// Color specified by lightness, a- and b-axis components.
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct Oklab {
/// The lightness component.
pub lightness: Option<f32>,
@ -378,7 +382,6 @@ impl_lab_like!(Oklab, "oklab");
/// Color specified by lightness, chroma and hue components.
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct Lch {
/// The lightness component.
pub lightness: Option<f32>,
@ -392,7 +395,6 @@ pub struct Lch {
/// Color specified by lightness, chroma and hue components.
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct Oklch {
/// The lightness component.
pub lightness: Option<f32>,
@ -467,24 +469,24 @@ impl_lch_like!(Lch, "lch");
impl_lch_like!(Oklch, "oklch");
/// A Predefined color space specified in:
/// https://drafts.csswg.org/css-color-4/#predefined
/// <https://drafts.csswg.org/css-color-4/#predefined>
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum PredefinedColorSpace {
/// https://drafts.csswg.org/css-color-4/#predefined-sRGB
/// <https://drafts.csswg.org/css-color-4/#predefined-sRGB>
Srgb,
/// https://drafts.csswg.org/css-color-4/#predefined-sRGB-linear
/// <https://drafts.csswg.org/css-color-4/#predefined-sRGB-linear>
SrgbLinear,
/// https://drafts.csswg.org/css-color-4/#predefined-display-p3
/// <https://drafts.csswg.org/css-color-4/#predefined-display-p3>
DisplayP3,
/// https://drafts.csswg.org/css-color-4/#predefined-a98-rgb
/// <https://drafts.csswg.org/css-color-4/#predefined-a98-rgb>
A98Rgb,
/// https://drafts.csswg.org/css-color-4/#predefined-prophoto-rgb
/// <https://drafts.csswg.org/css-color-4/#predefined-prophoto-rgb>
ProphotoRgb,
/// https://drafts.csswg.org/css-color-4/#predefined-rec2020
/// <https://drafts.csswg.org/css-color-4/#predefined-rec2020>
Rec2020,
/// https://drafts.csswg.org/css-color-4/#predefined-xyz
/// <https://drafts.csswg.org/css-color-4/#predefined-xyz>
XyzD50,
/// https://drafts.csswg.org/css-color-4/#predefined-xyz
/// <https://drafts.csswg.org/css-color-4/#predefined-xyz>
XyzD65,
}
@ -533,7 +535,7 @@ impl ToCss for PredefinedColorSpace {
}
/// A color specified by the color() function.
/// https://drafts.csswg.org/css-color-4/#color-function
/// <https://drafts.csswg.org/css-color-4/#color-function>
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct ColorFunction {
/// The color space for this color.
@ -588,8 +590,13 @@ impl ToCss for ColorFunction {
}
}
/// A <color> value.
/// https://drafts.csswg.org/css-color-4/#color-type
/// Describes one of the value <color> values according to the CSS
/// specification.
///
/// Most components are `Option<_>`, so when the value is `None`, that component
/// serializes to the "none" keyword.
///
/// <https://drafts.csswg.org/css-color-4/#color-type>
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Color {
/// The 'currentcolor' keyword.
@ -715,12 +722,14 @@ pub trait ColorParser<'i> {
Token::Dimension {
value: v, ref unit, ..
} => {
let degrees = match_ignore_ascii_case! { &*unit,
let degrees = match_ignore_ascii_case! { unit,
"deg" => v,
"grad" => v * 360. / 400.,
"rad" => v * 360. / (2. * PI),
"turn" => v * 360.,
_ => return Err(location.new_unexpected_token_error(Token::Ident(unit.clone()))),
_ => {
return Err(location.new_unexpected_token_error(Token::Ident(unit.clone())))
}
};
AngleOrNumber::Angle { degrees }
@ -773,7 +782,7 @@ impl Color {
/// Parse a <color> value, per CSS Color Module Level 3.
///
/// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Color, ParseError<'i, ()>> {
pub fn parse<'i>(input: &mut Parser<'i, '_>) -> Result<Color, ParseError<'i, ()>> {
parse_color_with(&DefaultColorParser, input)
}
}
@ -842,7 +851,7 @@ pub trait FromParsedColor {
/// Parse a color hash, without the leading '#' character.
#[inline]
pub fn parse_hash_color<'i, 't, O>(value: &[u8]) -> Result<O, ()>
pub fn parse_hash_color<'i, O>(value: &[u8]) -> Result<O, ()>
where
O: FromParsedColor,
{
@ -875,8 +884,8 @@ where
})
}
/// Parse a CSS color with the specified [`ColorComponentParser`] and return a
/// new color value on success.
/// Parse a CSS color using the specified [`ColorParser`] and return a new color
/// value on success.
pub fn parse_color_with<'i, 't, P>(
color_parser: &P,
input: &mut Parser<'i, 't>,
@ -888,11 +897,11 @@ where
let token = input.next()?;
match *token {
Token::Hash(ref value) | Token::IDHash(ref value) => parse_hash_color(value.as_bytes()),
Token::Ident(ref value) => parse_color_keyword(&*value),
Token::Ident(ref value) => parse_color_keyword(value),
Token::Function(ref name) => {
let name = name.clone();
return input.parse_nested_block(|arguments| {
parse_color_function(color_parser, &*name, arguments)
parse_color_function(color_parser, &name, arguments)
});
}
_ => Err(()),
@ -1173,12 +1182,12 @@ fn clamp_unit_f32(val: f32) -> u8 {
// Chrome does something similar for the alpha value, but not
// the rgb values.
//
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1340484
// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1340484>
//
// Clamping to 256 and rounding after would let 1.0 map to 256, and
// `256.0_f32 as u8` is undefined behavior:
//
// https://github.com/rust-lang/rust/issues/10184
// <https://github.com/rust-lang/rust/issues/10184>
clamp_floor_256_f32(val * 255.)
}
@ -1347,7 +1356,7 @@ where
/// Parses hsl syntax.
///
/// https://drafts.csswg.org/css-color/#the-hsl-notation
/// <https://drafts.csswg.org/css-color/#the-hsl-notation>
#[inline]
fn parse_hsl<'i, 't, P>(
color_parser: &P,
@ -1386,7 +1395,7 @@ where
/// Parses hwb syntax.
///
/// https://drafts.csswg.org/css-color/#the-hbw-notation
/// <https://drafts.csswg.org/css-color/#the-hbw-notation>
#[inline]
fn parse_hwb<'i, 't, P>(
color_parser: &P,
@ -1410,7 +1419,7 @@ where
Ok(P::Output::from_hwb(hue, whiteness, blackness, alpha))
}
/// https://drafts.csswg.org/css-color-4/#hwb-to-rgb
/// <https://drafts.csswg.org/css-color-4/#hwb-to-rgb>
#[inline]
pub fn hwb_to_rgb(h: f32, w: f32, b: f32) -> (f32, f32, f32) {
if w + b >= 1.0 {
@ -1427,11 +1436,11 @@ pub fn hwb_to_rgb(h: f32, w: f32, b: f32) -> (f32, f32, f32) {
(red, green, blue)
}
/// https://drafts.csswg.org/css-color/#hsl-color
/// <https://drafts.csswg.org/css-color/#hsl-color>
/// except with h pre-multiplied by 3, to avoid some rounding errors.
#[inline]
pub fn hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> (f32, f32, f32) {
debug_assert!(hue >= 0.0 && hue <= 1.0);
debug_assert!((0.0..=1.0).contains(&hue));
fn hue_to_rgb(m1: f32, m2: f32, mut h3: f32) -> f32 {
if h3 < 0. {
@ -1463,13 +1472,16 @@ pub fn hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> (f32, f32, f32)
(red, green, blue)
}
type IntoColorFn<Output> =
fn(l: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>) -> Output;
#[inline]
fn parse_lab_like<'i, 't, P>(
color_parser: &P,
arguments: &mut Parser<'i, 't>,
lightness_range: f32,
a_b_range: f32,
into_color: fn(l: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>) -> P::Output,
into_color: IntoColorFn<P::Output>,
) -> Result<P::Output, ParseError<'i, P::Error>>
where
P: ColorParser<'i>,
@ -1495,7 +1507,7 @@ fn parse_lch_like<'i, 't, P>(
arguments: &mut Parser<'i, 't>,
lightness_range: f32,
chroma_range: f32,
into_color: fn(l: Option<f32>, c: Option<f32>, h: Option<f32>, alpha: Option<f32>) -> P::Output,
into_color: IntoColorFn<P::Output>,
) -> Result<P::Output, ParseError<'i, P::Error>>
where
P: ColorParser<'i>,
@ -1553,6 +1565,9 @@ where
))
}
type ComponentParseResult<'i, R1, R2, R3, Error> =
Result<(Option<R1>, Option<R2>, Option<R3>, Option<f32>), ParseError<'i, Error>>;
/// Parse the color components and alpha with the modern [color-4] syntax.
pub fn parse_components<'i, 't, P, F1, F2, F3, R1, R2, R3>(
color_parser: &P,
@ -1560,7 +1575,7 @@ pub fn parse_components<'i, 't, P, F1, F2, F3, R1, R2, R3>(
f1: F1,
f2: F2,
f3: F3,
) -> Result<(Option<R1>, Option<R2>, Option<R3>, Option<f32>), ParseError<'i, P::Error>>
) -> ComponentParseResult<'i, R1, R2, R3, P::Error>
where
P: ColorParser<'i>,
F1: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R1, ParseError<'i, P::Error>>,

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

@ -12,7 +12,6 @@ use std::ops::Deref;
use std::rc::Rc;
use std::slice;
use std::str;
use std::usize;
/// A string that is either shared (heap-allocated and reference-counted) or borrowed.
///

4
third_party/rust/cssparser/src/lib.rs поставляемый
Просмотреть файл

@ -69,8 +69,8 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
pub use crate::color::{
hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with, parse_hash_color, AngleOrNumber,
Color, ColorFunction, ColorParser, FromParsedColor, Lab, Lch, NumberOrPercentage, Oklab, Oklch,
PredefinedColorSpace, RGBA,
Color, ColorFunction, ColorParser, FromParsedColor, Hsl, Hwb, Lab, Lch, NumberOrPercentage,
Oklab, Oklch, PredefinedColorSpace, RGBA,
};
pub use crate::cow_rc_str::CowRcStr;
pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};

37
third_party/rust/cssparser/src/macros.rs поставляемый
Просмотреть файл

@ -12,11 +12,9 @@ use std::mem::MaybeUninit;
/// # Example
///
/// ```rust
/// #[macro_use] extern crate cssparser;
///
/// # fn main() {} // Make doctest not wrap everything in its own main
/// # fn dummy(function_name: &String) { let _ =
/// match_ignore_ascii_case! { &function_name,
/// cssparser::match_ignore_ascii_case! { &function_name,
/// "rgb" => parse_rgb(..),
/// # #[cfg(not(something))]
/// "rgba" => parse_rgba(..),
@ -51,7 +49,7 @@ macro_rules! match_ignore_ascii_case {
$( $( $pattern )+ )+
}
}
_cssparser_internal_to_lowercase!($input, cssparser_internal::MAX_LENGTH => lowercase);
$crate::_cssparser_internal_to_lowercase!($input, cssparser_internal::MAX_LENGTH => lowercase);
// "A" is a short string that we know is different for every string pattern,
// since weve verified that none of them include ASCII upper case letters.
match lowercase.unwrap_or("A") {
@ -74,12 +72,10 @@ macro_rules! match_ignore_ascii_case {
/// ## Example:
///
/// ```rust
/// #[macro_use] extern crate cssparser;
///
/// # fn main() {} // Make doctest not wrap everything in its own main
///
/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
/// ascii_case_insensitive_phf_map! {
/// cssparser::ascii_case_insensitive_phf_map! {
/// keyword -> (u8, u8, u8) = {
/// "red" => (255, 0, 0),
/// "green" => (0, 255, 0),
@ -108,7 +104,7 @@ macro_rules! ascii_case_insensitive_phf_map {
$key => $value,
)*
};
_cssparser_internal_to_lowercase!(input, _cssparser_internal::MAX_LENGTH => lowercase);
$crate::_cssparser_internal_to_lowercase!(input, _cssparser_internal::MAX_LENGTH => lowercase);
lowercase.and_then(|s| MAP.get(s))
}
}
@ -156,22 +152,21 @@ pub fn _cssparser_internal_to_lowercase<'a>(
input: &'a str,
first_uppercase: usize,
) -> &'a str {
unsafe {
// This cast doesn't change the pointer's validity
// since `u8` has the same layout as `MaybeUninit<u8>`:
let input_bytes = &*(input.as_bytes() as *const [u8] as *const [MaybeUninit<u8>]);
// This cast doesn't change the pointer's validity
// since `u8` has the same layout as `MaybeUninit<u8>`:
let input_bytes =
unsafe { &*(input.as_bytes() as *const [u8] as *const [MaybeUninit<u8>]) };
buffer.copy_from_slice(&*input_bytes);
buffer.copy_from_slice(&*input_bytes);
// Same as above re layout, plus these bytes have been initialized:
let buffer = &mut *(buffer as *mut [MaybeUninit<u8>] as *mut [u8]);
// Same as above re layout, plus these bytes have been initialized:
let buffer = unsafe { &mut *(buffer as *mut [MaybeUninit<u8>] as *mut [u8]) };
buffer[first_uppercase..].make_ascii_lowercase();
// `buffer` was initialized to a copy of `input`
// (which is `&str` so well-formed UTF-8)
// then ASCII-lowercased (which preserves UTF-8 well-formedness):
::std::str::from_utf8_unchecked(buffer)
}
buffer[first_uppercase..].make_ascii_lowercase();
// `buffer` was initialized to a copy of `input`
// (which is `&str` so well-formed UTF-8)
// then ASCII-lowercased (which preserves UTF-8 well-formedness):
unsafe { ::std::str::from_utf8_unchecked(buffer) }
}
Some(

40
third_party/rust/cssparser/src/parser.rs поставляемый
Просмотреть файл

@ -5,6 +5,7 @@
use crate::cow_rc_str::CowRcStr;
use crate::tokenizer::{SourceLocation, SourcePosition, Token, Tokenizer};
use smallvec::SmallVec;
use std::fmt;
use std::ops::BitOr;
use std::ops::Range;
@ -53,6 +54,24 @@ pub enum BasicParseErrorKind<'i> {
QualifiedRuleInvalid,
}
impl<'i> fmt::Display for BasicParseErrorKind<'i> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BasicParseErrorKind::UnexpectedToken(token) => {
write!(f, "unexpected token: {:?}", token)
}
BasicParseErrorKind::EndOfInput => write!(f, "unexpected end of input"),
BasicParseErrorKind::AtRuleInvalid(rule) => {
write!(f, "invalid @ rule encountered: '@{}'", rule)
}
BasicParseErrorKind::AtRuleBodyInvalid => write!(f, "invalid @ rule body encountered"),
BasicParseErrorKind::QualifiedRuleInvalid => {
write!(f, "invalid qualified rule encountered")
}
}
}
}
/// The fundamental parsing errors that can be triggered by built-in parsing routines.
#[derive(Clone, Debug, PartialEq)]
pub struct BasicParseError<'i> {
@ -123,6 +142,15 @@ impl<'i, T> ParseErrorKind<'i, T> {
}
}
impl<'i, E: fmt::Display> fmt::Display for ParseErrorKind<'i, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ParseErrorKind::Basic(ref basic) => basic.fmt(f),
ParseErrorKind::Custom(ref custom) => custom.fmt(f),
}
}
}
/// Extensible parse errors that can be encountered by client parsing implementations.
#[derive(Clone, Debug, PartialEq)]
pub struct ParseError<'i, E> {
@ -137,7 +165,7 @@ impl<'i, T> ParseError<'i, T> {
pub fn basic(self) -> BasicParseError<'i> {
match self.kind {
ParseErrorKind::Basic(kind) => BasicParseError {
kind: kind,
kind,
location: self.location,
},
ParseErrorKind::Custom(_) => panic!("Not a basic parse error"),
@ -156,6 +184,14 @@ impl<'i, T> ParseError<'i, T> {
}
}
impl<'i, E: fmt::Display> fmt::Display for ParseError<'i, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.kind.fmt(f)
}
}
impl<'i, E: fmt::Display + fmt::Debug> std::error::Error for ParseError<'i, E> {}
/// The owned input for a parser.
pub struct ParserInput<'i> {
tokenizer: Tokenizer<'i>,
@ -396,7 +432,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
#[inline]
pub fn new_basic_error(&self, kind: BasicParseErrorKind<'i>) -> BasicParseError<'i> {
BasicParseError {
kind: kind,
kind,
location: self.current_source_location(),
}
}

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

@ -51,6 +51,13 @@ pub trait DeclarationParser<'i> {
name: CowRcStr<'i>,
input: &mut Parser<'i, 't>,
) -> Result<Self::Declaration, ParseError<'i, Self::Error>>;
/// Whether to try to parse qualified rules along with declarations. See
/// <https://github.com/w3c/csswg-drafts/issues/7961> for the current state of the discussion.
/// This is a low effort opt-in to be able to experiment with it, but it's likely to be needed
/// when nesting is less experimental as well (e.g., you probably don't want to allow nesting
/// in a style attribute anyways).
fn enable_nesting(&self) -> bool { false }
}
/// A trait to provide various parsing of at-rules.
@ -140,14 +147,14 @@ pub trait AtRuleParser<'i> {
/// A trait to provide various parsing of qualified rules.
///
/// For example, there could be different implementations
/// for top-level qualified rules (i.e. style rules with Selectors as prelude)
/// and for qualified rules inside `@keyframes` (keyframe rules with keyframe selectors as prelude).
/// For example, there could be different implementations for top-level qualified rules (i.e. style
/// rules with Selectors as prelude) and for qualified rules inside `@keyframes` (keyframe rules
/// with keyframe selectors as prelude).
///
/// Default implementations that reject all qualified rules are provided,
/// so that `impl QualifiedRuleParser<(), ()> for ... {}` can be used
/// for example for using `RuleListParser` to parse a rule list with only at-rules
/// (such as inside `@font-feature-values`).
/// Default implementations that reject all qualified rules are provided, so that
/// `impl QualifiedRuleParser<(), ()> for ... {}` can be used for example for using
/// `RuleListParser` to parse a rule list with only at-rules (such as inside
/// `@font-feature-values`).
pub trait QualifiedRuleParser<'i> {
/// The intermediate representation of a qualified rule prelude.
type Prelude;
@ -223,10 +230,7 @@ where
/// since `<DeclarationListParser as Iterator>::next` can return either.
/// It could be a custom enum.
pub fn new(input: &'a mut Parser<'i, 't>, parser: P) -> Self {
DeclarationListParser {
input: input,
parser: parser,
}
DeclarationListParser { input, parser }
}
}
@ -234,7 +238,9 @@ where
/// or `Err(())` for an invalid one.
impl<'i, 't, 'a, I, P, E: 'i> Iterator for DeclarationListParser<'i, 't, 'a, P>
where
P: DeclarationParser<'i, Declaration = I, Error = E> + AtRuleParser<'i, AtRule = I, Error = E>,
P: DeclarationParser<'i, Declaration = I, Error = E>
+ AtRuleParser<'i, AtRule = I, Error = E>
+ QualifiedRuleParser<'i, QualifiedRule = I, Error = E>,
{
type Item = Result<I, (ParseError<'i, E>, &'i str)>;
@ -247,15 +253,19 @@ where
}
Ok(&Token::Ident(ref name)) => {
let name = name.clone();
let result = {
let mut result = {
let parser = &mut self.parser;
// FIXME: https://github.com/servo/rust-cssparser/issues/254
let callback = |input: &mut Parser<'i, '_>| {
parse_until_after(self.input, Delimiter::Semicolon, |input| {
input.expect_colon()?;
parser.parse_value(name, input)
};
parse_until_after(self.input, Delimiter::Semicolon, callback)
})
};
if result.is_err() && self.parser.enable_nesting() {
self.input.reset(&start);
result = parse_qualified_rule(&start, self.input, &mut self.parser);
}
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
Ok(&Token::AtKeyword(ref name)) => {
@ -263,10 +273,17 @@ where
return Some(parse_at_rule(&start, name, self.input, &mut self.parser));
}
Ok(token) => {
let token = token.clone();
let result = self.input.parse_until_after(Delimiter::Semicolon, |_| {
Err(start.source_location().new_unexpected_token_error(token))
});
let result = if self.parser.enable_nesting() {
self.input.reset(&start);
// XXX do we need to, if we fail, consume only until the next semicolon,
// rather than until the next `{`?
parse_qualified_rule(&start, self.input, &mut self.parser)
} else {
let token = token.clone();
self.input.parse_until_after(Delimiter::Semicolon, |_| {
Err(start.source_location().new_unexpected_token_error(token))
})
};
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
Err(..) => return None,
@ -304,8 +321,8 @@ where
/// It could be a custom enum.
pub fn new_for_stylesheet(input: &'a mut Parser<'i, 't>, parser: P) -> Self {
RuleListParser {
input: input,
parser: parser,
input,
parser,
is_stylesheet: true,
any_rule_so_far: false,
}
@ -319,8 +336,8 @@ where
/// (This is to deal with legacy workarounds for `<style>` HTML element parsing.)
pub fn new_for_nested_rule(input: &'a mut Parser<'i, 't>, parser: P) -> Self {
RuleListParser {
input: input,
parser: parser,
input,
parser,
is_stylesheet: false,
any_rule_so_far: false,
}
@ -372,7 +389,7 @@ where
}
} else {
self.any_rule_so_far = true;
let result = parse_qualified_rule(self.input, &mut self.parser);
let result = parse_qualified_rule(&start, self.input, &mut self.parser);
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
}
@ -424,7 +441,7 @@ where
if let Some(name) = at_keyword {
parse_at_rule(&start, name, input, parser).map_err(|e| e.0)
} else {
parse_qualified_rule(input, parser)
parse_qualified_rule(&start, input, parser)
}
})
}
@ -439,26 +456,20 @@ where
P: AtRuleParser<'i, Error = E>,
{
let delimiters = Delimiter::Semicolon | Delimiter::CurlyBracketBlock;
// FIXME: https://github.com/servo/rust-cssparser/issues/254
let callback = |input: &mut Parser<'i, '_>| parser.parse_prelude(name, input);
let result = parse_until_before(input, delimiters, callback);
let result = parse_until_before(input, delimiters, |input| parser.parse_prelude(name, input));
match result {
Ok(prelude) => {
let result = match input.next() {
Ok(&Token::Semicolon) | Err(_) => {
parser.rule_without_block(prelude, start)
.map_err(|()| input.new_unexpected_token_error(Token::Semicolon))
},
Ok(&Token::Semicolon) | Err(_) => parser
.rule_without_block(prelude, start)
.map_err(|()| input.new_unexpected_token_error(Token::Semicolon)),
Ok(&Token::CurlyBracketBlock) => {
// FIXME: https://github.com/servo/rust-cssparser/issues/254
let callback =
|input: &mut Parser<'i, '_>| parser.parse_block(prelude, start, input);
parse_nested_block(input, callback)
},
parse_nested_block(input, |input| parser.parse_block(prelude, start, input))
}
Ok(_) => unreachable!(),
};
result.map_err(|e| (e, input.slice_from(start.position())))
},
}
Err(error) => {
let end_position = input.position();
match input.next() {
@ -466,28 +477,26 @@ where
_ => unreachable!(),
};
Err((error, input.slice(start.position()..end_position)))
},
}
}
}
fn parse_qualified_rule<'i, 't, P, E>(
start: &ParserState,
input: &mut Parser<'i, 't>,
parser: &mut P,
) -> Result<<P as QualifiedRuleParser<'i>>::QualifiedRule, ParseError<'i, E>>
where
P: QualifiedRuleParser<'i, Error = E>,
{
let start = input.state();
// FIXME: https://github.com/servo/rust-cssparser/issues/254
let callback = |input: &mut Parser<'i, '_>| parser.parse_prelude(input);
let prelude = parse_until_before(input, Delimiter::CurlyBracketBlock, callback);
let prelude = parse_until_before(input, Delimiter::CurlyBracketBlock, |input| {
parser.parse_prelude(input)
});
match *input.next()? {
Token::CurlyBracketBlock => {
// Do this here so that we consume the `{` even if the prelude is `Err`.
let prelude = prelude?;
// FIXME: https://github.com/servo/rust-cssparser/issues/254
let callback = |input: &mut Parser<'i, '_>| parser.parse_block(prelude, &start, input);
parse_nested_block(input, callback)
parse_nested_block(input, |input| parser.parse_block(prelude, &start, input))
}
_ => unreachable!(),
}

3
third_party/rust/cssparser/src/tests.rs поставляемый
Просмотреть файл

@ -703,7 +703,6 @@ fn line_numbers() {
#[test]
fn overflow() {
use std::f32;
use std::iter::repeat;
let css = r"
@ -1487,7 +1486,7 @@ fn utf16_columns() {
#[test]
fn servo_define_css_keyword_enum() {
macro_rules! define_css_keyword_enum {
(pub enum $name:ident { $($variant:ident = $css:expr,)+ }) => {
(pub enum $name:ident { $($variant:ident = $css:pat,)+ }) => {
#[derive(PartialEq, Debug)]
pub enum $name {
$($variant),+

1
third_party/rust/cssparser/src/tokenizer.rs поставляемый
Просмотреть файл

@ -8,7 +8,6 @@ use self::Token::*;
use crate::cow_rc_str::CowRcStr;
use crate::parser::ParserState;
use std::char;
use std::i32;
use std::ops::Range;
/// One of the pieces the CSS input is broken into.