/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#[derive(Clone, Debug)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] pubenum AttrValue { // // Variants that are stored in their serialized form. //
String(String),
Atom(Atom),
// // Variants that support lazy serialization. //
TokenList(OnceLock<String>, Vec<Atom>),
UInt(OnceLock<String>, u32),
Int(OnceLock<String>, i32),
Double(OnceLock<String>, f64), /// Note that this variant is only used transitively as a fast path to set /// the property declaration block relevant to the style of an element when /// set from the inline declaration of that element (that is, /// `element.style`).
Declaration { #[ignore_malloc_size_of = "Arc"]
block: Arc<Locked<PropertyDeclarationBlock>>,
lock: SharedRwLock,
serialization: OnceLock<String>,
},
// // Variants without a serialization implementation which must be eagerly serialized. //
LengthPercentage(String, Option<LengthPercentage>),
Color(String, Option<AbsoluteColor>),
Dimension(String, LengthOrPercentageOrAuto), /// Stores a URL, computed from the input string and a document's base URL. /// /// The URL is resolved at setting-time, so this kind of attribute value is /// not actually suitable for most URL-reflecting IDL attributes.
ResolvedUrl(
String, #[ignore_malloc_size_of = "Arc"] Option<Arc<url::Url>>,
), /// The value of an `exportparts` attribute.
ShadowParts(String, ShadowParts),
}
/// Assumes the `AttrValue` is a `TokenList` and returns its tokens /// /// ## Panics /// /// Panics if the `AttrValue` is not a `TokenList` pubfn as_tokens(&self) -> &[Atom] { match *self {
AttrValue::TokenList(_, ref tokens) => tokens,
_ => panic!("Tokens not found"),
}
}
/// Assumes the `AttrValue` is an `Atom` and returns its value /// /// ## Panics /// /// Panics if the `AttrValue` is not an `Atom` pubfn as_atom(&self) -> &Atom { match *self {
AttrValue::Atom(ref value) => value,
_ => panic!("Atom not found"),
}
}
/// Assumes the `AttrValue` is a `LengthPercentage` and returns its value /// /// ## Panics /// /// Panics if the `AttrValue` is not a `LengthPercentage` pubfn as_length_percentage(&self) -> Option<&LengthPercentage> { match *self {
AttrValue::LengthPercentage(_, ref length_percentage) => length_percentage.as_ref(),
_ => panic!("LengthPercentage not found"),
}
}
/// Assumes the `AttrValue` is a `Color` and returns its value /// /// ## Panics /// /// Panics if the `AttrValue` is not a `Color` pubfn as_color(&self) -> Option<&AbsoluteColor> { match *self {
AttrValue::Color(_, ref color) => color.as_ref(),
_ => panic!("Color not found"),
}
}
/// Assumes the `AttrValue` is a `Dimension` and returns its value /// /// ## Panics /// /// Panics if the `AttrValue` is not a `Dimension` pubfn as_dimension(&self) -> &LengthOrPercentageOrAuto { match *self {
AttrValue::Dimension(_, ref l) => l,
_ => panic!("Dimension not found"),
}
}
/// Assumes the `AttrValue` is a `ResolvedUrl` and returns its value. /// /// ## Panics /// /// Panics if the `AttrValue` is not a `ResolvedUrl` pubfn as_resolved_url(&self) -> Option<&Arc<::url::Url>> { match *self {
AttrValue::ResolvedUrl(_, ref url) => url.as_ref(),
_ => panic!("Url not found"),
}
}
/// Return the AttrValue as its signed integer representation, if any. /// This corresponds to attribute values returned as `AttrValue::Int(_)` /// by `VirtualMethods::parse_plain_attribute()`. /// /// ## Panics /// /// Panics if the `AttrValue` is not a `Int` pubfn as_int(&self) -> i32 { iflet AttrValue::Int(_, value) = *self {
value
} else {
panic!("Int not found");
}
}
/// Return the AttrValue as its unsigned integer representation, if any. /// This corresponds to attribute values returned as `AttrValue::UInt(_)` /// by `VirtualMethods::parse_plain_attribute()`. /// /// ## Panics /// /// Panics if the `AttrValue` is not a `UInt` pubfn as_uint(&self) -> u32 { iflet AttrValue::UInt(_, value) = *self {
value
} else {
panic!("Uint not found");
}
}
/// Return the AttrValue as a dimension computed from its unsigned integer /// representation, assuming that integer representation specifies pixels. /// /// This corresponds to attribute values returned as `AttrValue::UInt(_)` /// by `VirtualMethods::parse_plain_attribute()`. /// /// ## Panics /// /// Panics if the `AttrValue` is not a `UInt` pubfn as_uint_px_dimension(&self) -> LengthOrPercentageOrAuto { iflet AttrValue::UInt(_, value) = *self {
LengthOrPercentageOrAuto::Length(Au::from_px(value as i32))
} else {
panic!("Uint not found");
}
}
/// Return the AttrValue as it's shadow-part representation. /// /// This corresponds to attribute values returned as `AttrValue::ShadowParts(_)` /// by `VirtualMethods::parse_plain_attribute()`. /// /// ## Panics /// /// Panics if the `AttrValue` is not a shadow-part. pubfn as_shadow_parts(&self) -> &ShadowParts { iflet AttrValue::ShadowParts(_, value) = &self {
value
} else {
panic!("Not a shadowpart attribute");
}
}
pubfn eval_selector(&self, selector: &AttrSelectorOperation<&AtomString>) -> bool { // FIXME(SimonSapin) this can be more efficient by matching on `(self, selector)` variants // and doing Atom comparisons instead of string comparisons where possible, // with SelectorImpl::AttrValue changed to Atom.
selector.eval_str(self)
}
}
impl ::std::ops::Deref for AttrValue { type Target = str;
impl PartialEq<Atom> for AttrValue { fn eq(&self, other: &Atom) -> bool { match *self {
AttrValue::Atom(ref value) => value == other,
_ => other == &**self,
}
}
}
/// <https://html.spec.whatwg.org/multipage/#rules-for-parsing-non-zero-dimension-values> pubfn parse_nonzero_length(value: &str) -> LengthOrPercentageOrAuto { match parse_length(value) {
LengthOrPercentageOrAuto::Length(x) if x == Au::zero() => LengthOrPercentageOrAuto::Auto,
LengthOrPercentageOrAuto::Percentage(x) if x == 0. => LengthOrPercentageOrAuto::Auto,
x => x,
}
}
fn hex(ch: char) -> Result<u8, ()> { match ch { '0'..='9' => Ok((ch as u8) - b'0'), 'a'..='f' => Ok((ch as u8) - b'a' + 10), 'A'..='F' => Ok((ch as u8) - b'A' + 10),
_ => Err(()),
}
}
fn hex_string(string: &[u8]) -> Result<u8, ()> { match string.len() { 0 => Err(()), 1 => hex(string[0] as char),
_ => { let upper = hex(string[0] as char)?; let lower = hex(string[1] as char)?;
Ok((upper << 4) | lower)
},
}
}
}
/// Parses a [dimension value][dim]. If unparseable, `Auto` is returned. /// /// [dim]: https://html.spec.whatwg.org/multipage/#rules-for-parsing-dimension-values // TODO: this function can be rewritten to return Result<LengthPercentage, _> pubfn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { // Steps 1 & 2 are not relevant
// Step 3
value = value.trim_start_matches(HTML_SPACE_CHARACTERS);
// Steps 5 to 8 // We trim the string length to the minimum of: // 1. the end of the string // 2. the first occurence of a '%' (U+0025 PERCENT SIGN) // 3. the second occurrence of a '.' (U+002E FULL STOP) // 4. the occurrence of a character that is neither a digit nor '%' nor '.' // Note: Step 7.4 is directly subsumed by FromStr::from_str letmut end_index = value.len(); let (mut found_full_stop, mut found_percent) = (false, false); for (i, ch) in value.chars().enumerate() { match ch { '0'..='9' => continue, '%' => {
found_percent = true;
end_index = i; break;
}, '.'if !found_full_stop => {
found_full_stop = true; continue;
},
_ => {
end_index = i; break;
},
}
}
value = &value[..end_index];
if found_percent { let result: Result<f32, _> = FromStr::from_str(value); match result {
Ok(number) => return LengthOrPercentageOrAuto::Percentage((number as f32) / 100.0),
Err(_) => return LengthOrPercentageOrAuto::Auto,
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.