Auto merge of #15924 - upsuper:bug1315601, r=heycam,Manishearth

Implement access to CSSMediaRule for stylo

This is the Servo part of [bug 1315601](https://bugzilla.mozilla.org/show_bug.cgi?id=1315601).

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15924)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-03-12 23:55:46 -07:00 committed by GitHub
commit cc9fb0ba59
5 changed files with 212 additions and 5 deletions

View file

@ -8,14 +8,16 @@
#![allow(non_snake_case, missing_docs)] #![allow(non_snake_case, missing_docs)]
use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule};
use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule}; use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules}; use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock}; use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock};
use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
use media_queries::MediaList;
use parking_lot::RwLock; use parking_lot::RwLock;
use properties::{ComputedValues, PropertyDeclarationBlock}; use properties::{ComputedValues, PropertyDeclarationBlock};
use properties::animated_properties::AnimationValue; use properties::animated_properties::AnimationValue;
use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule}; use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, MediaRule};
macro_rules! impl_arc_ffi { macro_rules! impl_arc_ffi {
($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => { ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
@ -56,3 +58,9 @@ impl_arc_ffi!(RwLock<ImportRule> => RawServoImportRule
impl_arc_ffi!(AnimationValue => RawServoAnimationValue impl_arc_ffi!(AnimationValue => RawServoAnimationValue
[Servo_AnimationValue_AddRef, Servo_AnimationValue_Release]); [Servo_AnimationValue_AddRef, Servo_AnimationValue_Release]);
impl_arc_ffi!(RwLock<MediaList> => RawServoMediaList
[Servo_MediaList_AddRef, Servo_MediaList_Release]);
impl_arc_ffi!(RwLock<MediaRule> => RawServoMediaRule
[Servo_MediaRule_AddRef, Servo_MediaRule_Release]);

View file

@ -137,8 +137,15 @@ impl ToCss for Expression {
} }
} }
impl PartialEq for Expression {
fn eq(&self, other: &Expression) -> bool {
self.feature.mName == other.feature.mName &&
self.value == other.value && self.range == other.range
}
}
/// A resolution. /// A resolution.
#[derive(Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum Resolution { pub enum Resolution {
/// Dots per inch. /// Dots per inch.
Dpi(CSSFloat), Dpi(CSSFloat),
@ -200,7 +207,7 @@ unsafe fn string_from_ns_string_buffer(buffer: *const nsStringBuffer) -> String
} }
/// A value found or expected in a media expression. /// A value found or expected in a media expression.
#[derive(Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum MediaExpressionValue { pub enum MediaExpressionValue {
/// A length. /// A length.
Length(specified::Length), Length(specified::Length),

View file

@ -4,6 +4,16 @@ pub use nsstring::{nsACString, nsAString, nsString};
type nsACString_internal = nsACString; type nsACString_internal = nsACString;
type nsAString_internal = nsAString; type nsAString_internal = nsAString;
use gecko_bindings::structs::mozilla::css::URLValue; use gecko_bindings::structs::mozilla::css::URLValue;
pub type RawServoMediaListStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaList>;
pub type RawServoMediaListBorrowedOrNull<'a> = Option<&'a RawServoMediaList>;
pub type RawServoMediaListBorrowed<'a> = &'a RawServoMediaList;
enum RawServoMediaListVoid{ }
pub struct RawServoMediaList(RawServoMediaListVoid);
pub type RawServoMediaRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaRule>;
pub type RawServoMediaRuleBorrowedOrNull<'a> = Option<&'a RawServoMediaRule>;
pub type RawServoMediaRuleBorrowed<'a> = &'a RawServoMediaRule;
enum RawServoMediaRuleVoid{ }
pub struct RawServoMediaRule(RawServoMediaRuleVoid);
use gecko_bindings::structs::RawGeckoDocument; use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoKeyframeList; use gecko_bindings::structs::RawGeckoKeyframeList;
@ -286,12 +296,24 @@ extern "C" {
pub fn Servo_DeclarationBlock_Release(ptr: pub fn Servo_DeclarationBlock_Release(ptr:
RawServoDeclarationBlockBorrowed); RawServoDeclarationBlockBorrowed);
} }
extern "C" {
pub fn Servo_MediaList_AddRef(ptr: RawServoMediaListBorrowed);
}
extern "C" {
pub fn Servo_MediaList_Release(ptr: RawServoMediaListBorrowed);
}
extern "C" { extern "C" {
pub fn Servo_StyleRule_AddRef(ptr: RawServoStyleRuleBorrowed); pub fn Servo_StyleRule_AddRef(ptr: RawServoStyleRuleBorrowed);
} }
extern "C" { extern "C" {
pub fn Servo_StyleRule_Release(ptr: RawServoStyleRuleBorrowed); pub fn Servo_StyleRule_Release(ptr: RawServoStyleRuleBorrowed);
} }
extern "C" {
pub fn Servo_MediaRule_AddRef(ptr: RawServoMediaRuleBorrowed);
}
extern "C" {
pub fn Servo_MediaRule_Release(ptr: RawServoMediaRuleBorrowed);
}
extern "C" { extern "C" {
pub fn Servo_ImportRule_AddRef(ptr: RawServoImportRuleBorrowed); pub fn Servo_ImportRule_AddRef(ptr: RawServoImportRuleBorrowed);
} }
@ -1328,6 +1350,11 @@ extern "C" {
index: u32) index: u32)
-> RawServoStyleRuleStrong; -> RawServoStyleRuleStrong;
} }
extern "C" {
pub fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed,
index: u32)
-> RawServoMediaRuleStrong;
}
extern "C" { extern "C" {
pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
sheet: RawServoStyleSheetBorrowed, sheet: RawServoStyleSheetBorrowed,
@ -1360,6 +1387,22 @@ extern "C" {
pub fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, pub fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed,
result: *mut nsAString_internal); result: *mut nsAString_internal);
} }
extern "C" {
pub fn Servo_MediaRule_Debug(rule: RawServoMediaRuleBorrowed,
result: *mut nsACString_internal);
}
extern "C" {
pub fn Servo_MediaRule_GetMedia(rule: RawServoMediaRuleBorrowed)
-> RawServoMediaListStrong;
}
extern "C" {
pub fn Servo_MediaRule_GetRules(rule: RawServoMediaRuleBorrowed)
-> ServoCssRulesStrong;
}
extern "C" {
pub fn Servo_MediaRule_GetCssText(rule: RawServoMediaRuleBorrowed,
result: *mut nsAString_internal);
}
extern "C" { extern "C" {
pub fn Servo_ParseProperty(property: *const nsACString_internal, pub fn Servo_ParseProperty(property: *const nsACString_internal,
value: *const nsACString_internal, value: *const nsACString_internal,
@ -1584,6 +1627,34 @@ extern "C" {
pub fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarations: pub fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarations:
RawServoDeclarationBlockBorrowed); RawServoDeclarationBlockBorrowed);
} }
extern "C" {
pub fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed,
result: *mut nsAString_internal);
}
extern "C" {
pub fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed,
text: *const nsACString_internal);
}
extern "C" {
pub fn Servo_MediaList_GetLength(list: RawServoMediaListBorrowed) -> u32;
}
extern "C" {
pub fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed,
index: u32,
result: *mut nsAString_internal)
-> bool;
}
extern "C" {
pub fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
new_medium:
*const nsACString_internal);
}
extern "C" {
pub fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
old_medium:
*const nsACString_internal)
-> bool;
}
extern "C" { extern "C" {
pub fn Servo_CSSSupports2(name: *const nsACString_internal, pub fn Servo_CSSSupports2(name: *const nsACString_internal,
value: *const nsACString_internal) -> bool; value: *const nsACString_internal) -> bool;

View file

@ -66,7 +66,7 @@ impl ToCss for Qualifier {
/// A [media query][mq]. /// A [media query][mq].
/// ///
/// [mq]: https://drafts.csswg.org/mediaqueries/ /// [mq]: https://drafts.csswg.org/mediaqueries/
#[derive(Clone, Debug)] #[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MediaQuery { pub struct MediaQuery {
/// The qualifier for this query. /// The qualifier for this query.
@ -299,4 +299,37 @@ impl MediaList {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.media_queries.is_empty() self.media_queries.is_empty()
} }
/// Append a new media query item to the media list.
/// https://drafts.csswg.org/cssom/#dom-medialist-appendmedium
///
/// Returns true if added, false if fail to parse the medium string.
pub fn append_medium(&mut self, new_medium: &str) -> bool {
let mut parser = Parser::new(new_medium);
let new_query = match MediaQuery::parse(&mut parser) {
Ok(query) => query,
Err(_) => { return false; }
};
// This algorithm doesn't actually matches the current spec,
// but it matches the behavior of Gecko and Edge.
// See https://github.com/w3c/csswg-drafts/issues/697
self.media_queries.retain(|query| query != &new_query);
self.media_queries.push(new_query);
true
}
/// Delete a media query from the media list.
/// https://drafts.csswg.org/cssom/#dom-medialist-deletemedium
///
/// Returns true if found and deleted, false otherwise.
pub fn delete_medium(&mut self, old_medium: &str) -> bool {
let mut parser = Parser::new(old_medium);
let old_query = match MediaQuery::parse(&mut parser) {
Ok(query) => query,
Err(_) => { return false; }
};
let old_len = self.media_queries.len();
self.media_queries.retain(|query| query != &old_query);
old_len != self.media_queries.len()
}
} }

View file

@ -32,6 +32,8 @@ use style::gecko::wrapper::GeckoElement;
use style::gecko_bindings::bindings; use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut}; use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut};
use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong}; use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
use style::gecko_bindings::bindings::{RawServoMediaRuleBorrowed, RawServoMediaRuleStrong};
use style::gecko_bindings::bindings::{RawServoStyleRuleBorrowed, RawServoStyleRuleStrong}; use style::gecko_bindings::bindings::{RawServoStyleRuleBorrowed, RawServoStyleRuleStrong};
use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned}; use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned};
use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
@ -62,6 +64,7 @@ use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI}; use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
use style::gecko_properties::{self, style_structs}; use style::gecko_properties::{self, style_structs};
use style::keyframes::KeyframesStepValue; use style::keyframes::KeyframesStepValue;
use style::media_queries::{MediaList, parse_media_query_list};
use style::parallel; use style::parallel;
use style::parser::{ParserContext, ParserContextExtraData}; use style::parser::{ParserContext, ParserContextExtraData};
use style::properties::{ComputedValues, Importance, ParsedDeclaration}; use style::properties::{ComputedValues, Importance, ParsedDeclaration};
@ -72,7 +75,7 @@ use style::restyle_hints::{self, RestyleHint};
use style::selector_parser::PseudoElementCascadeType; use style::selector_parser::PseudoElementCascadeType;
use style::sequential; use style::sequential;
use style::string_cache::Atom; use style::string_cache::Atom;
use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StyleRule, ImportRule}; use style::stylesheets::{CssRule, CssRules, ImportRule, MediaRule, Origin, Stylesheet, StyleRule};
use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
use style::supports::parse_condition_or_declaration; use style::supports::parse_condition_or_declaration;
use style::thread_state; use style::thread_state;
@ -518,6 +521,18 @@ pub extern "C" fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed, in
} }
} }
#[no_mangle]
pub extern "C" fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed, index: u32)
-> RawServoMediaRuleStrong {
let rules = RwLock::<CssRules>::as_arc(&rules).read();
match rules.0[index as usize] {
CssRule::Media(ref rule) => rule.clone().into_strong(),
_ => {
unreachable!("GetMediaRuleAt should only be called on a media rule");
}
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, sheet: RawServoStyleSheetBorrowed, pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, sheet: RawServoStyleSheetBorrowed,
rule: *const nsACString, index: u32, nested: bool, rule: *const nsACString, index: u32, nested: bool,
@ -576,6 +591,31 @@ pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowe
rule.read().selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap(); rule.read().selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
} }
#[no_mangle]
pub extern "C" fn Servo_MediaRule_Debug(rule: RawServoMediaRuleBorrowed, result: *mut nsACString) -> () {
let rule = RwLock::<MediaRule>::as_arc(&rule);
let result = unsafe { result.as_mut().unwrap() };
write!(result, "{:?}", *rule.read()).unwrap();
}
#[no_mangle]
pub extern "C" fn Servo_MediaRule_GetMedia(rule: RawServoMediaRuleBorrowed) -> RawServoMediaListStrong {
let rule = RwLock::<MediaRule>::as_arc(&rule);
rule.read().media_queries.clone().into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_MediaRule_GetRules(rule: RawServoMediaRuleBorrowed) -> ServoCssRulesStrong {
let rule = RwLock::<MediaRule>::as_arc(&rule);
rule.read().rules.clone().into_strong()
}
#[no_mangle]
pub extern "C" fn Servo_MediaRule_GetCssText(rule: RawServoMediaRuleBorrowed, result: *mut nsAString) -> () {
let rule = RwLock::<MediaRule>::as_arc(&rule);
rule.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap();
}
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull, pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull,
pseudo_tag: *mut nsIAtom, pseudo_tag: *mut nsIAtom,
@ -880,6 +920,54 @@ pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawSer
remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ())) remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ()))
} }
#[no_mangle]
pub extern "C" fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed, result: *mut nsAString) {
let list = RwLock::<MediaList>::as_arc(&list);
list.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap();
}
#[no_mangle]
pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text: *const nsACString) {
let list = RwLock::<MediaList>::as_arc(&list);
let text = unsafe { text.as_ref().unwrap().as_str_unchecked() };
let mut parser = Parser::new(&text);
*list.write() = parse_media_query_list(&mut parser);
}
#[no_mangle]
pub extern "C" fn Servo_MediaList_GetLength(list: RawServoMediaListBorrowed) -> u32 {
let list = RwLock::<MediaList>::as_arc(&list);
list.read().media_queries.len() as u32
}
#[no_mangle]
pub extern "C" fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed, index: u32,
result: *mut nsAString) -> bool {
let list = RwLock::<MediaList>::as_arc(&list);
if let Some(media_query) = list.read().media_queries.get(index as usize) {
media_query.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
true
} else {
false
}
}
#[no_mangle]
pub extern "C" fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
new_medium: *const nsACString) {
let list = RwLock::<MediaList>::as_arc(&list);
let new_medium = unsafe { new_medium.as_ref().unwrap().as_str_unchecked() };
list.write().append_medium(new_medium);
}
#[no_mangle]
pub extern "C" fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
old_medium: *const nsACString) -> bool {
let list = RwLock::<MediaList>::as_arc(&list);
let old_medium = unsafe { old_medium.as_ref().unwrap().as_str_unchecked() };
list.write().delete_medium(old_medium)
}
macro_rules! get_longhand_from_id { macro_rules! get_longhand_from_id {
($id:expr, $retval:expr) => { ($id:expr, $retval:expr) => {
match PropertyId::from_nscsspropertyid($id) { match PropertyId::from_nscsspropertyid($id) {