зеркало из https://github.com/mozilla/gecko-dev.git
This relands #18519 as-is. It was backed-out because some Gecko changes hadn't landed yet, but I just pushed them in a way they wouldn't break the build. Source-Repo: https://github.com/servo/servo Source-Revision: 3d2dccf1f3e7bf99cb750ee9fd245c24255ad9e2 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 268b2a1d2a6de5657384558b5a08570b879ac4de
This commit is contained in:
Родитель
a8bb4881b1
Коммит
40e7c23de0
|
@ -547,6 +547,14 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
|||
};
|
||||
extended_filtering(&element_lang, &*value)
|
||||
}
|
||||
|
||||
fn is_html_document_body_element(&self) -> bool {
|
||||
// This is only used for the "tables inherit from body" quirk, which we
|
||||
// don't implement.
|
||||
//
|
||||
// FIXME(emilio): We should be able to give the right answer though!
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'le> PartialEq for ServoLayoutElement<'le> {
|
||||
|
|
|
@ -685,31 +685,33 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
|||
/// we can perform the more thoroughgoing check, needs_transitions_update, to further
|
||||
/// reduce the possibility of false positives.
|
||||
#[cfg(feature = "gecko")]
|
||||
fn might_need_transitions_update(&self,
|
||||
old_values: Option<&ComputedValues>,
|
||||
new_values: &ComputedValues)
|
||||
-> bool;
|
||||
fn might_need_transitions_update(
|
||||
&self,
|
||||
old_values: Option<&ComputedValues>,
|
||||
new_values: &ComputedValues
|
||||
) -> bool;
|
||||
|
||||
/// Returns true if one of the transitions needs to be updated on this element. We check all
|
||||
/// the transition properties to make sure that updating transitions is necessary.
|
||||
/// This method should only be called if might_needs_transitions_update returns true when
|
||||
/// passed the same parameters.
|
||||
#[cfg(feature = "gecko")]
|
||||
fn needs_transitions_update(&self,
|
||||
before_change_style: &ComputedValues,
|
||||
after_change_style: &ComputedValues)
|
||||
-> bool;
|
||||
fn needs_transitions_update(
|
||||
&self,
|
||||
before_change_style: &ComputedValues,
|
||||
after_change_style: &ComputedValues
|
||||
) -> bool;
|
||||
|
||||
/// Returns true if we need to update transitions for the specified property on this element.
|
||||
#[cfg(feature = "gecko")]
|
||||
fn needs_transitions_update_per_property(&self,
|
||||
property: &TransitionProperty,
|
||||
combined_duration: f32,
|
||||
before_change_style: &ComputedValues,
|
||||
after_change_style: &ComputedValues,
|
||||
existing_transitions: &HashMap<TransitionProperty,
|
||||
Arc<AnimationValue>>)
|
||||
-> bool;
|
||||
fn needs_transitions_update_per_property(
|
||||
&self,
|
||||
property: &TransitionProperty,
|
||||
combined_duration: f32,
|
||||
before_change_style: &ComputedValues,
|
||||
after_change_style: &ComputedValues,
|
||||
existing_transitions: &HashMap<TransitionProperty, Arc<AnimationValue>>
|
||||
) -> bool;
|
||||
|
||||
/// Returns the value of the `xml:lang=""` attribute (or, if appropriate,
|
||||
/// the `lang=""` attribute) on this element.
|
||||
|
@ -720,10 +722,15 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
|||
/// of the `xml:lang=""` or `lang=""` attribute to use in place of
|
||||
/// looking at the element and its ancestors. (This argument is used
|
||||
/// to implement matching of `:lang()` against snapshots.)
|
||||
fn match_element_lang(&self,
|
||||
override_lang: Option<Option<AttrValue>>,
|
||||
value: &PseudoClassStringArg)
|
||||
-> bool;
|
||||
fn match_element_lang(
|
||||
&self,
|
||||
override_lang: Option<Option<AttrValue>>,
|
||||
value: &PseudoClassStringArg
|
||||
) -> bool;
|
||||
|
||||
/// Returns whether this element is the main body element of the HTML
|
||||
/// document it is on.
|
||||
fn is_html_document_body_element(&self) -> bool;
|
||||
}
|
||||
|
||||
/// TNode and TElement aren't Send because we want to be careful and explicit
|
||||
|
|
|
@ -1551,8 +1551,7 @@ extern "C" {
|
|||
*mut nsCSSCounterStyleRule);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_GetBody(pres_context: RawGeckoPresContextBorrowed)
|
||||
-> RawGeckoElementBorrowedOrNull;
|
||||
pub fn Gecko_IsDocumentBody(element: RawGeckoElementBorrowed) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_GetLookAndFeelSystemColor(color_id: i32,
|
||||
|
|
|
@ -11,7 +11,7 @@ use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError};
|
|||
use euclid::ScaleFactor;
|
||||
use euclid::Size2D;
|
||||
use font_metrics::get_metrics_provider_for_product;
|
||||
use gecko::values::convert_nscolor_to_rgba;
|
||||
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
|
||||
use gecko_bindings::bindings;
|
||||
use gecko_bindings::structs;
|
||||
use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, nsCSSUnit};
|
||||
|
@ -27,7 +27,7 @@ use rule_cache::RuleCacheConditions;
|
|||
use servo_arc::Arc;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::{self, Write};
|
||||
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
||||
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
|
||||
use str::starts_with_ignore_ascii_case;
|
||||
use string_cache::Atom;
|
||||
use style_traits::{CSSPixel, DevicePixel};
|
||||
|
@ -54,6 +54,11 @@ pub struct Device {
|
|||
/// the parent to compute everything else. So it is correct to just use
|
||||
/// a relaxed atomic here.
|
||||
root_font_size: AtomicIsize,
|
||||
/// The body text color, stored as an `nscolor`, used for the "tables
|
||||
/// inherit from body" quirk.
|
||||
///
|
||||
/// https://quirks.spec.whatwg.org/#the-tables-inherit-color-from-body-quirk
|
||||
body_text_color: AtomicUsize,
|
||||
/// Whether any styles computed in the document relied on the root font-size
|
||||
/// by using rem units.
|
||||
used_root_font_size: AtomicBool,
|
||||
|
@ -74,6 +79,7 @@ impl Device {
|
|||
default_values: ComputedValues::default_values(unsafe { &*pres_context }),
|
||||
// FIXME(bz): Seems dubious?
|
||||
root_font_size: AtomicIsize::new(font_size::get_initial_value().0.to_i32_au() as isize),
|
||||
body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize),
|
||||
used_root_font_size: AtomicBool::new(false),
|
||||
used_viewport_size: AtomicBool::new(false),
|
||||
}
|
||||
|
@ -110,6 +116,18 @@ impl Device {
|
|||
self.root_font_size.store(size.0 as isize, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Sets the body text color for the "inherit color from body" quirk.
|
||||
///
|
||||
/// https://quirks.spec.whatwg.org/#the-tables-inherit-color-from-body-quirk
|
||||
pub fn set_body_text_color(&self, color: RGBA) {
|
||||
self.body_text_color.store(convert_rgba_to_nscolor(&color) as usize, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Returns the body text color.
|
||||
pub fn body_text_color(&self) -> RGBA {
|
||||
convert_nscolor_to_rgba(self.body_text_color.load(Ordering::Relaxed) as u32)
|
||||
}
|
||||
|
||||
/// Gets the pres context associated with this document.
|
||||
pub fn pres_context(&self) -> &nsPresContext {
|
||||
unsafe { &*self.pres_context }
|
||||
|
|
|
@ -593,6 +593,10 @@ impl<'le> GeckoElement<'le> {
|
|||
self.as_node().node_info().mInner.mNamespaceID
|
||||
}
|
||||
|
||||
fn is_html_element(&self) -> bool {
|
||||
self.namespace_id() == (structs::root::kNameSpaceID_XHTML as i32)
|
||||
}
|
||||
|
||||
fn is_xul_element(&self) -> bool {
|
||||
self.namespace_id() == (structs::root::kNameSpaceID_XUL as i32)
|
||||
}
|
||||
|
@ -1484,11 +1488,11 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
fn match_element_lang(&self,
|
||||
override_lang: Option<Option<AttrValue>>,
|
||||
value: &PseudoClassStringArg)
|
||||
-> bool
|
||||
{
|
||||
fn match_element_lang(
|
||||
&self,
|
||||
override_lang: Option<Option<AttrValue>>,
|
||||
value: &PseudoClassStringArg
|
||||
) -> bool {
|
||||
// Gecko supports :lang() from CSS Selectors 3, which only accepts a
|
||||
// single language tag, and which performs simple dash-prefix matching
|
||||
// on it.
|
||||
|
@ -1502,6 +1506,18 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
Gecko_MatchLang(self.0, override_lang_ptr, override_lang.is_some(), value.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_html_document_body_element(&self) -> bool {
|
||||
if self.get_local_name() != &*local_name!("body") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !self.is_html_element() {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsafe { bindings::Gecko_IsDocumentBody(self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'le> PartialEq for GeckoElement<'le> {
|
||||
|
@ -1722,11 +1738,12 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
None
|
||||
}
|
||||
|
||||
fn attr_matches(&self,
|
||||
ns: &NamespaceConstraint<&Namespace>,
|
||||
local_name: &Atom,
|
||||
operation: &AttrSelectorOperation<&Atom>)
|
||||
-> bool {
|
||||
fn attr_matches(
|
||||
&self,
|
||||
ns: &NamespaceConstraint<&Namespace>,
|
||||
local_name: &Atom,
|
||||
operation: &AttrSelectorOperation<&Atom>
|
||||
) -> bool {
|
||||
unsafe {
|
||||
match *operation {
|
||||
AttrSelectorOperation::Exists => {
|
||||
|
@ -2010,10 +2027,8 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
|
|||
}
|
||||
|
||||
fn is_html_element_in_html_document(&self) -> bool {
|
||||
let node = self.as_node();
|
||||
let node_info = node.node_info();
|
||||
node_info.mInner.mNamespaceID == (structs::root::kNameSpaceID_XHTML as i32) &&
|
||||
node.owner_doc().mType == structs::root::nsIDocument_Type::eHTML
|
||||
self.is_html_element() &&
|
||||
self.as_node().owner_doc().mType == structs::root::nsIDocument_Type::eHTML
|
||||
}
|
||||
|
||||
fn ignores_nth_child_selectors(&self) -> bool {
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
#![allow(unsafe_code)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use context::{ElementCascadeInputs, SelectorFlagsMap, SharedStyleContext, StyleContext};
|
||||
use context::{ElementCascadeInputs, QuirksMode, SelectorFlagsMap};
|
||||
use context::{SharedStyleContext, StyleContext};
|
||||
use data::ElementData;
|
||||
use dom::TElement;
|
||||
use invalidation::element::restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS};
|
||||
|
@ -551,10 +552,6 @@ pub trait MatchMethods : TElement {
|
|||
|
||||
// Propagate the "can be fragmented" bit. It would be nice to
|
||||
// encapsulate this better.
|
||||
//
|
||||
// Note that this is technically not needed for pseudos since we already
|
||||
// do that when we resolve the non-pseudo style, but it doesn't hurt
|
||||
// anyway.
|
||||
if cfg!(feature = "servo") {
|
||||
let layout_parent =
|
||||
self.inheritance_parent().map(|e| e.layout_parent());
|
||||
|
@ -590,6 +587,21 @@ pub trait MatchMethods : TElement {
|
|||
}
|
||||
}
|
||||
|
||||
if context.shared.stylist.quirks_mode() == QuirksMode::Quirks {
|
||||
if self.is_html_document_body_element() {
|
||||
// NOTE(emilio): We _could_ handle dynamic changes to it if it
|
||||
// changes and before we reach our children the cascade stops,
|
||||
// but we don't track right now whether we use the document body
|
||||
// color, and nobody else handles that properly anyway.
|
||||
|
||||
let device = context.shared.stylist.device();
|
||||
|
||||
// Needed for the "inherit from body" quirk.
|
||||
let text_color = new_primary_style.get_color().clone_color();
|
||||
device.set_body_text_color(text_color);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't accumulate damage if we're in a forgetful traversal.
|
||||
if context.shared.traversal_flags.contains(traversal_flags::Forgetful) {
|
||||
return ChildCascadeRequirement::MustCascadeChildren;
|
||||
|
|
|
@ -92,6 +92,13 @@ impl Device {
|
|||
self.root_font_size.store(size.0 as isize, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Sets the body text color for the "inherit color from body" quirk.
|
||||
///
|
||||
/// https://quirks.spec.whatwg.org/#the-tables-inherit-color-from-body-quirk
|
||||
pub fn set_body_text_color(&self, _color: RGBA) {
|
||||
// Servo doesn't implement this quirk (yet)
|
||||
}
|
||||
|
||||
/// Returns whether we ever looked up the root font size of the Device.
|
||||
pub fn used_root_font_size(&self) -> bool {
|
||||
self.used_root_font_size.load(Ordering::Relaxed)
|
||||
|
|
|
@ -289,19 +289,7 @@ impl ToComputedValue for Color {
|
|||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
Color::InheritFromBodyQuirk => {
|
||||
use dom::TElement;
|
||||
use gecko::wrapper::GeckoElement;
|
||||
use gecko_bindings::bindings::Gecko_GetBody;
|
||||
let pres_context = context.device().pres_context();
|
||||
let body = unsafe { Gecko_GetBody(pres_context) }.map(GeckoElement);
|
||||
let data = body.as_ref().and_then(|wrap| wrap.borrow_data());
|
||||
if let Some(data) = data {
|
||||
ComputedColor::rgba(data.styles.primary()
|
||||
.get_color()
|
||||
.clone_color())
|
||||
} else {
|
||||
convert_nscolor_to_computedcolor(pres_context.mDefaultColor)
|
||||
}
|
||||
ComputedColor::rgba(context.device().body_text_color())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче