/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script/dom/html/htmlfontelement.rs
228 строк
7 KB
Tim van der Lippe
script: Remove cx argument from macros (#46375)
08 июл 2026, 13:16
Не верифицирован
08 июл 2026, 13:16
1b15719
Код
Авторство
О чём код?
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use cssparser::match_ignore_ascii_case; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix, local_name, ns}; use js::context::JSContext; use js::rust::HandleObject; use style::attr::AttrValue; use style::color::AbsoluteColor; use style::str::{HTML_SPACE_CHARACTERS, read_numbers}; use style::values::computed::font::{ FamilyName, FontFamilyNameSyntax, GenericFontFamily, SingleFontFamily, }; use stylo_atoms::Atom; use crate::dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::root::{DomRoot, LayoutDom}; use crate::dom::bindings::str::DOMString; use crate::dom::document::Document; use crate::dom::element::Element; use crate::dom::element::attributes::storage::AttrRef; use crate::dom::html::htmlelement::HTMLElement; use crate::dom::node::Node; use crate::dom::node::virtualmethods::VirtualMethods; #[dom_struct] pub(crate) struct HTMLFontElement { htmlelement: HTMLElement, } impl HTMLFontElement { fn new_inherited( local_name: LocalName, prefix: Option<Prefix>, document: &Document, ) -> HTMLFontElement { HTMLFontElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), } } pub(crate) fn new( cx: &mut JSContext, local_name: LocalName, prefix: Option<Prefix>, document: &Document, proto: Option<HandleObject>, ) -> DomRoot<HTMLFontElement> { Node::reflect_node_with_proto( cx, Box::new(HTMLFontElement::new_inherited(local_name, prefix, document)), document, proto, ) } pub(crate) fn parse_face_attribute(face_value: Atom) -> Vec<SingleFontFamily> { face_value .split(',') .map(|string| Self::parse_single_face_value_from_string(string.trim())) .collect() } fn parse_single_face_value_from_string(string: &str) -> SingleFontFamily { match_ignore_ascii_case! { string, "serif" => return SingleFontFamily::Generic(GenericFontFamily::Serif), "sans-serif" => return SingleFontFamily::Generic(GenericFontFamily::SansSerif), "cursive" => return SingleFontFamily::Generic(GenericFontFamily::Cursive), "fantasy" => return SingleFontFamily::Generic(GenericFontFamily::Fantasy), "monospace" => return SingleFontFamily::Generic(GenericFontFamily::Monospace), "system-ui" => return SingleFontFamily::Generic(GenericFontFamily::SystemUi), _ => {} } let name = string.to_owned().replace(['\'', '"'], ""); let syntax = if name == string { FontFamilyNameSyntax::Identifiers } else { FontFamilyNameSyntax::Quoted }; SingleFontFamily::FamilyName(FamilyName { name: name.into(), syntax, }) } } impl HTMLFontElementMethods<crate::DomTypeHolder> for HTMLFontElement { // https://html.spec.whatwg.org/multipage/#dom-font-color make_getter!(Color, "color"); // https://html.spec.whatwg.org/multipage/#dom-font-color make_legacy_color_setter!(SetColor, "color"); // https://html.spec.whatwg.org/multipage/#dom-font-face make_getter!(Face, "face"); // https://html.spec.whatwg.org/multipage/#dom-font-face make_atomic_setter!(SetFace, "face"); // https://html.spec.whatwg.org/multipage/#dom-font-size make_getter!(Size, "size"); /// <https://html.spec.whatwg.org/multipage/#dom-font-size> fn SetSize(&self, cx: &mut JSContext, value: DOMString) { let element = self.upcast::<Element>(); element.set_attribute(cx, &local_name!("size"), parse_size(&value)); } } impl VirtualMethods for HTMLFontElement { fn super_type(&self) -> Option<&dyn VirtualMethods> { Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods) } fn attribute_affects_presentational_hints(&self, attr: AttrRef<'_>) -> bool { if attr.local_name() == &local_name!("color") || attr.local_name() == &local_name!("size") || attr.local_name() == &local_name!("face") { return true; } self.super_type() .unwrap() .attribute_affects_presentational_hints(attr) } fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match *name { local_name!("face") => AttrValue::from_atomic(value.into()), local_name!("color") => AttrValue::from_legacy_color(value.into()), local_name!("size") => parse_size(&value), _ => self .super_type() .unwrap() .parse_plain_attribute(name, value), } } } impl LayoutDom<'_, HTMLFontElement> { pub(crate) fn get_color(self) -> Option<AbsoluteColor> { let color = self .upcast::<Element>() .get_attr_for_layout(&ns!(), &local_name!("color")); match color { Some(AttrValue::Color(_, color)) => *color, _ => None, } } pub(crate) fn get_face(self) -> Option<Atom> { let face = self .upcast::<Element>() .get_attr_for_layout(&ns!(), &local_name!("face")); match face { Some(AttrValue::Atom(s)) => Some(s.clone()), _ => None, } } pub(crate) fn get_size(self) -> Option<u32> { let size = self .upcast::<Element>() .get_attr_for_layout(&ns!(), &local_name!("size")); match size { Some(&AttrValue::UInt(_, s)) => Some(s), _ => None, } } } /// <https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size> fn parse_size(input: &DOMString) -> AttrValue { let original_input = input; // Steps 1 & 2 are not relevant // Step 3 let input = input.str(); let input = input.trim_matches(HTML_SPACE_CHARACTERS); enum ParseMode { RelativePlus, RelativeMinus, Absolute, } let mut input_chars = input.chars().peekable(); let parse_mode = match input_chars.peek() { // Step 4 None => return AttrValue::String(original_input.str().into()), // Step 5 Some(&'+') => { let _ = input_chars.next(); // consume the '+' ParseMode::RelativePlus }, Some(&'-') => { let _ = input_chars.next(); // consume the '-' ParseMode::RelativeMinus }, Some(_) => ParseMode::Absolute, }; // Steps 6, 7, 8 let mut value = match read_numbers(input_chars) { (Some(v), _) if v >= 0 => v, _ => return AttrValue::String(original_input.str().into()), }; // Step 9 match parse_mode { ParseMode::RelativePlus => value += 3, ParseMode::RelativeMinus => value = 3 - value, ParseMode::Absolute => (), } // Step 10: If value is greater than 7, let it be 7. // Step 11: If value is less than 1, let it be 1. value = value.clamp(1, 7); // Step 12 AttrValue::UInt(String::from(original_input.str()).into(), value as u32) }