mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Use resources stylesheet for details element.
Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
parent
871630606f
commit
d7ec3635e6
7 changed files with 114 additions and 64 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -6551,6 +6551,7 @@ dependencies = [
|
|||
"servo_malloc_size_of",
|
||||
"servo_url",
|
||||
"stylo",
|
||||
"url",
|
||||
"webrender_api",
|
||||
]
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ use rayon::ThreadPool;
|
|||
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
|
||||
use script_layout_interface::{
|
||||
Layout, LayoutConfig, LayoutFactory, NodesFromPointQueryType, OffsetParentResponse, ReflowGoal,
|
||||
ReflowRequest, ReflowResult, TrustedNodeAddress,
|
||||
ReflowRequest, ReflowResult, TrustedNodeAddress, parse_ua_stylesheet,
|
||||
};
|
||||
use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage};
|
||||
use servo_arc::Arc as ServoArc;
|
||||
|
@ -58,7 +58,7 @@ use style::properties::{ComputedValues, PropertyId};
|
|||
use style::queries::values::PrefersColorScheme;
|
||||
use style::selector_parser::{PseudoElement, RestyleDamage, SnapshotMap};
|
||||
use style::servo::media_queries::FontMetricsProvider;
|
||||
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
|
||||
use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards};
|
||||
use style::stylesheets::{
|
||||
DocumentStyleSheet, Origin, Stylesheet, StylesheetInDocument, UrlExtraData,
|
||||
UserAgentStylesheets,
|
||||
|
@ -72,7 +72,6 @@ use style::values::specified::font::{KeywordInfo, QueryFontMetricsFlags};
|
|||
use style::{Zero, driver};
|
||||
use style_traits::{CSSPixel, SpeculativePainter};
|
||||
use stylo_atoms::Atom;
|
||||
use url::Url;
|
||||
use webrender_api::units::{DevicePixel, DevicePoint, LayoutPixel, LayoutPoint, LayoutSize};
|
||||
use webrender_api::{ExternalScrollId, HitTestFlags};
|
||||
|
||||
|
@ -989,28 +988,6 @@ impl LayoutThread {
|
|||
}
|
||||
|
||||
fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
||||
fn parse_ua_stylesheet(
|
||||
shared_lock: &SharedRwLock,
|
||||
filename: &str,
|
||||
content: &[u8],
|
||||
) -> Result<DocumentStyleSheet, &'static str> {
|
||||
let url = Url::parse(&format!("chrome://resources/{:?}", filename))
|
||||
.ok()
|
||||
.unwrap();
|
||||
Ok(DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
|
||||
content,
|
||||
url.into(),
|
||||
None,
|
||||
None,
|
||||
Origin::UserAgent,
|
||||
MediaList::empty(),
|
||||
shared_lock.clone(),
|
||||
None,
|
||||
None,
|
||||
QuirksMode::NoQuirks,
|
||||
))))
|
||||
}
|
||||
|
||||
let shared_lock = &GLOBAL_STYLE_DATA.shared_lock;
|
||||
|
||||
// FIXME: presentational-hints.css should be at author origin with zero specificity.
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
use std::cell::{Cell, Ref};
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::resources::Resource;
|
||||
use html5ever::{LocalName, Prefix, local_name};
|
||||
use js::rust::HandleObject;
|
||||
use script_layout_interface::parse_resource_stylesheet;
|
||||
use style::attr::AttrValue;
|
||||
|
||||
use super::element::ElementCreator;
|
||||
use super::types::HTMLLinkElement;
|
||||
use crate::dom::attr::Attr;
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLDetailsElementBinding::HTMLDetailsElementMethods;
|
||||
|
@ -116,13 +121,49 @@ impl HTMLDetailsElement {
|
|||
)
|
||||
.expect("Attaching UA shadow root failed");
|
||||
|
||||
let link_element = HTMLLinkElement::new(
|
||||
local_name!("link"),
|
||||
None,
|
||||
&document,
|
||||
None,
|
||||
ElementCreator::ScriptCreated,
|
||||
can_gc,
|
||||
);
|
||||
link_element.upcast::<Element>().set_attribute(
|
||||
&local_name!("rel"),
|
||||
AttrValue::String("stylesheet".to_owned()),
|
||||
can_gc,
|
||||
);
|
||||
root.upcast::<Node>()
|
||||
.AppendChild(link_element.upcast::<Node>(), can_gc)
|
||||
.unwrap();
|
||||
|
||||
let details_stylesheet = parse_resource_stylesheet(
|
||||
link_element
|
||||
.upcast::<Node>()
|
||||
.owner_doc()
|
||||
.style_shared_lock(),
|
||||
Resource::DetailsCSS,
|
||||
);
|
||||
link_element.set_stylesheet(details_stylesheet.unwrap());
|
||||
|
||||
let summary = HTMLSlotElement::new(local_name!("slot"), None, &document, None, can_gc);
|
||||
summary.upcast::<Element>().set_attribute(
|
||||
&local_name!("name"),
|
||||
AttrValue::from_atomic("internal-main-summary".to_owned()),
|
||||
can_gc,
|
||||
);
|
||||
root.upcast::<Node>()
|
||||
.AppendChild(summary.upcast::<Node>(), can_gc)
|
||||
.unwrap();
|
||||
|
||||
let fallback_summary =
|
||||
HTMLElement::new(local_name!("summary"), None, &document, None, can_gc);
|
||||
fallback_summary.upcast::<Element>().set_attribute(
|
||||
&local_name!("name"),
|
||||
AttrValue::from_atomic("internal-fallback-summary".to_owned()),
|
||||
can_gc,
|
||||
);
|
||||
fallback_summary
|
||||
.upcast::<Node>()
|
||||
.SetTextContent(Some(DEFAULT_SUMMARY.into()), can_gc);
|
||||
|
@ -179,40 +220,6 @@ impl HTMLDetailsElement {
|
|||
}
|
||||
shadow_tree.descendants.Assign(slottable_children);
|
||||
}
|
||||
|
||||
fn update_shadow_tree_styles(&self, can_gc: CanGc) {
|
||||
let shadow_tree = self.shadow_tree(can_gc);
|
||||
|
||||
let value = if self.Open() {
|
||||
"display: block;"
|
||||
} else {
|
||||
// TODO: This should be "display: block; content-visibility: hidden;",
|
||||
// but servo does not support content-visibility yet
|
||||
"display: none;"
|
||||
};
|
||||
shadow_tree
|
||||
.descendants
|
||||
.upcast::<Element>()
|
||||
.set_string_attribute(&local_name!("style"), value.into(), can_gc);
|
||||
|
||||
// Manually update the list item style of the implicit summary element.
|
||||
// Unlike the other summaries, this summary is in the shadow tree and
|
||||
// can't be styled with UA sheets
|
||||
let implicit_summary_list_item_style = if self.Open() {
|
||||
"disclosure-open"
|
||||
} else {
|
||||
"disclosure-closed"
|
||||
};
|
||||
let implicit_summary_style = format!(
|
||||
"display: list-item;
|
||||
counter-increment: list-item 0;
|
||||
list-style: {implicit_summary_list_item_style} inside;"
|
||||
);
|
||||
shadow_tree
|
||||
.implicit_summary
|
||||
.upcast::<Element>()
|
||||
.set_string_attribute(&local_name!("style"), implicit_summary_style.into(), can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
impl HTMLDetailsElementMethods<crate::DomTypeHolder> for HTMLDetailsElement {
|
||||
|
@ -234,8 +241,6 @@ impl VirtualMethods for HTMLDetailsElement {
|
|||
.attribute_mutated(attr, mutation, can_gc);
|
||||
|
||||
if attr.local_name() == &local_name!("open") {
|
||||
self.update_shadow_tree_styles(can_gc);
|
||||
|
||||
let counter = self.toggle_counter.get() + 1;
|
||||
self.toggle_counter.set(counter);
|
||||
|
||||
|
@ -263,6 +268,5 @@ impl VirtualMethods for HTMLDetailsElement {
|
|||
self.super_type().unwrap().bind_to_tree(context, can_gc);
|
||||
|
||||
self.update_shadow_tree_contents(CanGc::note());
|
||||
self.update_shadow_tree_styles(CanGc::note());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ pub fn sandbox_access_files_dirs() -> Vec<PathBuf> {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Resource {
|
||||
/// A list of GATT services that are blocked from being used by web bluetooth.
|
||||
/// The format of the file is a list of UUIDs, one per line, with an optional second word to specify the
|
||||
|
@ -109,6 +110,9 @@ pub enum Resource {
|
|||
DirectoryListingHTML,
|
||||
/// A HTML page that is used for the about:memory url.
|
||||
AboutMemoryHTML,
|
||||
/// A CSS file to style the elements inside <details> element UA Shadow Tree.
|
||||
/// It can be empty but then <details> element simply wouldn't work.
|
||||
DetailsCSS,
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
|
@ -123,6 +127,7 @@ impl Resource {
|
|||
Resource::CrashHTML => "crash.html",
|
||||
Resource::DirectoryListingHTML => "directory-listing.html",
|
||||
Resource::AboutMemoryHTML => "about-memory.html",
|
||||
Resource::DetailsCSS => "details.css",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +172,7 @@ fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> {
|
|||
Resource::AboutMemoryHTML => {
|
||||
&include_bytes!("../../../resources/about-memory.html")[..]
|
||||
},
|
||||
Resource::DetailsCSS => &include_bytes!("../../../resources/details.css")[..],
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
|
|
|
@ -38,4 +38,5 @@ serde = { workspace = true }
|
|||
servo_arc = { workspace = true }
|
||||
servo_url = { path = "../../url" }
|
||||
stylo = { workspace = true }
|
||||
url = { workspace = true }
|
||||
webrender_api = { workspace = true }
|
||||
|
|
|
@ -20,6 +20,7 @@ use base::Epoch;
|
|||
use base::id::{BrowsingContextId, PipelineId, WebViewId};
|
||||
use compositing_traits::CrossProcessCompositorApi;
|
||||
use constellation_traits::{LoadData, ScrollState};
|
||||
use embedder_traits::resources::{self, Resource};
|
||||
use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails};
|
||||
use euclid::default::{Point2D, Rect};
|
||||
use fnv::FnvHashMap;
|
||||
|
@ -43,11 +44,13 @@ use style::context::QuirksMode;
|
|||
use style::data::ElementData;
|
||||
use style::dom::OpaqueNode;
|
||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||
use style::media_queries::Device;
|
||||
use style::media_queries::{Device, MediaList};
|
||||
use style::properties::PropertyId;
|
||||
use style::properties::style_structs::Font;
|
||||
use style::selector_parser::{PseudoElement, RestyleDamage, Snapshot};
|
||||
use style::stylesheets::Stylesheet;
|
||||
use style::shared_lock::SharedRwLock;
|
||||
use style::stylesheets::{DocumentStyleSheet, Origin, Stylesheet};
|
||||
use url::Url;
|
||||
use webrender_api::ImageKey;
|
||||
use webrender_api::units::DeviceIntSize;
|
||||
|
||||
|
@ -635,3 +638,43 @@ mod test {
|
|||
assert_eq!(image_animation_state.last_update_time, 0.101);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_stylesheet_as_origin(
|
||||
shared_lock: &SharedRwLock,
|
||||
filename: &str,
|
||||
content: &[u8],
|
||||
origin: Origin,
|
||||
) -> Result<ServoArc<Stylesheet>, &'static str> {
|
||||
let url = Url::parse(&format!("chrome://resources/{:?}", filename))
|
||||
.ok()
|
||||
.unwrap();
|
||||
Ok(ServoArc::new(Stylesheet::from_bytes(
|
||||
content,
|
||||
url.into(),
|
||||
None,
|
||||
None,
|
||||
origin,
|
||||
MediaList::empty(),
|
||||
shared_lock.clone(),
|
||||
None,
|
||||
None,
|
||||
QuirksMode::NoQuirks,
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn parse_ua_stylesheet(
|
||||
shared_lock: &SharedRwLock,
|
||||
filename: &str,
|
||||
content: &[u8],
|
||||
) -> Result<DocumentStyleSheet, &'static str> {
|
||||
parse_stylesheet_as_origin(shared_lock, filename, content, Origin::UserAgent)
|
||||
.map(DocumentStyleSheet)
|
||||
}
|
||||
|
||||
pub fn parse_resource_stylesheet(
|
||||
shared_lock: &SharedRwLock,
|
||||
resources: Resource,
|
||||
) -> Result<ServoArc<Stylesheet>, &'static str> {
|
||||
let content = &resources::read_bytes(resources.clone());
|
||||
parse_stylesheet_as_origin(shared_lock, resources.filename(), content, Origin::Author)
|
||||
}
|
||||
|
|
18
resources/details.css
Normal file
18
resources/details.css
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* We should use `content-visibility` but it is yet to be implemented.
|
||||
* These rule would not comply with ::details-content and should be removed
|
||||
* with it's implementation */
|
||||
slot:not([name]) {
|
||||
display: none;
|
||||
}
|
||||
:host([open]) slot:not([name]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
summary[name=internal-fallback-summary] {
|
||||
display: list-item;
|
||||
counter-increment: list-item 0;
|
||||
list-style: disclosure-closed inside;
|
||||
}
|
||||
:host([open]) summary[name=internal-fallback-summary] {
|
||||
list-style-type: disclosure-open;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue