diff options
Diffstat (limited to 'components/script')
26 files changed, 632 insertions, 90 deletions
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 4bf6a9d3337..afee568d735 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -9,8 +9,9 @@ use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSeque use bluetooth_traits::scanfilter::{RequestDeviceoptions, ServiceUUIDSequence}; use core::clone::Clone; use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothMethods, BluetoothRequestDeviceFilter}; -use dom::bindings::codegen::Bindings::BluetoothBinding::RequestDeviceOptions; +use dom::bindings::codegen::Bindings::BluetoothBinding::{self, BluetoothDataFilterInit, BluetoothLEScanFilterInit}; +use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, RequestDeviceOptions}; +use dom::bindings::codegen::UnionTypes::StringOrUnsignedLong; use dom::bindings::error::Error::{self, NotFound, Security, Type}; use dom::bindings::error::Fallible; use dom::bindings::js::{JS, MutHeap, Root}; @@ -31,10 +32,14 @@ use js::jsapi::{JSAutoCompartment, JSContext}; use network_listener::{NetworkListener, PreInvoke}; use std::collections::HashMap; use std::rc::Rc; +use std::str::FromStr; use std::sync::{Arc, Mutex}; +const KEY_CONVERSION_ERROR: &'static str = "This `manufacturerData` key can not be parsed as unsigned short:"; const FILTER_EMPTY_ERROR: &'static str = "'filters' member, if present, must be nonempty to find any devices."; const FILTER_ERROR: &'static str = "A filter must restrict the devices in some way."; +const MANUFACTURER_DATA_ERROR: &'static str = "'manufacturerData', if present, must be non-empty to filter devices."; +const MASK_LENGTH_ERROR: &'static str = "`mask`, if present, must have the same length as `dataPrefix`."; // 248 is the maximum number of UTF-8 code units in a Bluetooth Device Name. const MAX_DEVICE_NAME_LENGTH: usize = 248; // A device name can never be longer than 29 bytes. @@ -44,6 +49,7 @@ const MAX_DEVICE_NAME_LENGTH: usize = 248; const MAX_FILTER_NAME_LENGTH: usize = 29; const NAME_PREFIX_ERROR: &'static str = "'namePrefix', if present, must be nonempty."; const NAME_TOO_LONG_ERROR: &'static str = "A device name can't be longer than 248 bytes."; +const SERVICE_DATA_ERROR: &'static str = "'serviceData', if present, must be non-empty to filter devices."; const SERVICE_ERROR: &'static str = "'services', if present, must contain at least one service."; const OPTIONS_ERROR: &'static str = "Fields of 'options' conflict with each other. Either 'acceptAllDevices' member must be true, or 'filters' member must be set to a value."; @@ -122,7 +128,7 @@ impl Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices fn request_bluetooth_devices(&self, p: &Rc<Promise>, - filters: &Option<Vec<BluetoothRequestDeviceFilter>>, + filters: &Option<Vec<BluetoothLEScanFilterInit>>, optional_services: &Option<Vec<BluetoothServiceUUID>>) { // TODO: Step 1: Triggered by user activation. @@ -165,7 +171,7 @@ pub fn response_async<T: AsyncBluetoothListener + Reflectable + 'static>( } // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices -fn convert_request_device_options(filters: &Option<Vec<BluetoothRequestDeviceFilter>>, +fn convert_request_device_options(filters: &Option<Vec<BluetoothLEScanFilterInit>>, optional_services: &Option<Vec<BluetoothServiceUUID>>) -> Fallible<RequestDeviceoptions> { // Step 2.2: There is no requiredServiceUUIDS, we scan for all devices. @@ -206,13 +212,13 @@ fn convert_request_device_options(filters: &Option<Vec<BluetoothRequestDeviceFil } // https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices -fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter) -> Fallible<BluetoothScanfilter> { +fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<BluetoothScanfilter> { // Step 2.4.1. if filter.services.is_none() && filter.name.is_none() && filter.namePrefix.is_none() && - filter.manufacturerId.is_none() && - filter.serviceDataUUID.is_none() { + filter.manufacturerData.is_none() && + filter.serviceData.is_none() { return Err(Type(FILTER_ERROR.to_owned())); } @@ -285,31 +291,66 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter) -> Fallible<Blueto None => String::new(), }; - // Step 2.4.6. - let manufacturer_id = filter.manufacturerId; - - // Step 2.4.7. - let service_data_uuid = match filter.serviceDataUUID { - Some(ref service_data_uuid) => { - // Step 2.4.7.1 - 2.4.7.2. - let uuid = try!(BluetoothUUID::service(service_data_uuid.clone())).to_string(); - - // Step 2.4.7.3. - if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) { - return Err(Security) + // Step 2.4.6 - 2.4.7 + let manufacturer_data = match filter.manufacturerData { + Some(ref manufacturer_data_map) => { + if manufacturer_data_map.is_empty() { + return Err(Type(MANUFACTURER_DATA_ERROR.to_owned())); } + let mut map = HashMap::new(); + for (key, bdfi) in manufacturer_data_map.iter() { + let manufacturer_id = match u16::from_str(key.as_ref()) { + Ok(id) => id, + Err(err) => return Err(Type(format!("{} {} {}", KEY_CONVERSION_ERROR, key, err))), + }; + map.insert(manufacturer_id, try!(canonicalize_bluetooth_data_filter_init(bdfi))); + } + Some(map) + }, + None => None, + }; - // Step 2.4.7.4. - uuid + // Step 2.4.8 -2.4.9 + let service_data = match filter.serviceData { + Some(ref service_data_map) => { + if service_data_map.is_empty() { + return Err(Type(SERVICE_DATA_ERROR.to_owned())); + } + let mut map = HashMap::new(); + for (key, bdfi) in service_data_map.iter() { + let service_name = match u32::from_str(key.as_ref()) { + Ok(number) => StringOrUnsignedLong::UnsignedLong(number), + _ => StringOrUnsignedLong::String(key.clone()) + }; + let service = try!(BluetoothUUID::service(service_name)).to_string(); + if uuid_is_blocklisted(service.as_ref(), Blocklist::All) { + return Err(Security); + } + map.insert(service, try!(canonicalize_bluetooth_data_filter_init(bdfi))); + } + Some(map) }, - None => String::new(), + None => None, }; - Ok(BluetoothScanfilter::new(name, - name_prefix, - services_vec, - manufacturer_id, - service_data_uuid)) + // Step 10. + Ok(BluetoothScanfilter::new(name, name_prefix, services_vec, manufacturer_data, service_data)) +} + +// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdatafilterinit-canonicalizing +fn canonicalize_bluetooth_data_filter_init(bdfi: &BluetoothDataFilterInit) -> Fallible<(Vec<u8>, Vec<u8>)> { + // Step 1. + let data_prefix = bdfi.dataPrefix.clone().unwrap_or(vec![]); + // Step 2. + // If no mask present, mask will be a sequence of 0xFF bytes the same length as dataPrefix. + // Masking dataPrefix with this, leaves dataPrefix untouched. + let mask = bdfi.mask.clone().unwrap_or(vec![0xFF; data_prefix.len()]); + // Step 3. + if mask.len() != data_prefix.len() { + return Err(Type(MASK_LENGTH_ERROR.to_owned())); + } + // Step 4. + Ok((data_prefix, mask)) } impl From<BluetoothError> for Error { diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index dae5fd3e558..390878342db 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -214,6 +214,47 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap(); return p; } + + #[allow(unrooted_must_root)] + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications + fn StartNotifications(&self) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let p_cx = p.global().get_cx(); + // Step 1. + if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { + p.reject_error(p_cx, Security); + return p; + } + // Step 3. + if !(self.Properties().Notify() || + self.Properties().Indicate()) { + p.reject_error(p_cx, NotSupported); + return p; + } + // Step 6. + if !self.Service().Device().Gatt().Connected() { + p.reject_error(p_cx, Network); + return p; + } + let sender = response_async(&p, self); + self.get_bluetooth_thread().send( + BluetoothRequest::EnableNotification(self.get_instance_id(), + true, + sender)).unwrap(); + return p; + } + + #[allow(unrooted_must_root)] + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications + fn StopNotifications(&self) -> Rc<Promise> { + let p = Promise::new(&self.global()); + let sender = response_async(&p, self); + self.get_bluetooth_thread().send( + BluetoothRequest::EnableNotification(self.get_instance_id(), + false, + sender)).unwrap(); + return p; + } } impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { @@ -263,6 +304,9 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic { *self.value.borrow_mut() = Some(value.clone()); promise.resolve_native(promise_cx, &value); }, + BluetoothResponse::EnableNotification(_result) => { + promise.resolve_native(promise_cx, self); + }, _ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())), } } diff --git a/components/script/dom/cssfontfacerule.rs b/components/script/dom/cssfontfacerule.rs index 18371c89c45..60022b7ba8f 100644 --- a/components/script/dom/cssfontfacerule.rs +++ b/components/script/dom/cssfontfacerule.rs @@ -22,7 +22,7 @@ pub struct CSSFontFaceRule { } impl CSSFontFaceRule { - fn new_inherited(parent: &CSSStyleSheet, fontfacerule: Arc<RwLock<FontFaceRule>>) -> CSSFontFaceRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, fontfacerule: Arc<RwLock<FontFaceRule>>) -> CSSFontFaceRule { CSSFontFaceRule { cssrule: CSSRule::new_inherited(parent), fontfacerule: fontfacerule, @@ -30,7 +30,7 @@ impl CSSFontFaceRule { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, fontfacerule: Arc<RwLock<FontFaceRule>>) -> Root<CSSFontFaceRule> { reflect_dom_object(box CSSFontFaceRule::new_inherited(parent, fontfacerule), window, diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index 3558686ea74..cd55cd358b6 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -3,28 +3,67 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding; -use dom::bindings::js::Root; -use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding::CSSGroupingRuleMethods; +use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleBinding::CSSRuleMethods; +use dom::bindings::error::{ErrorResult, Fallible}; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; +use dom::bindings::str::DOMString; use dom::cssrule::CSSRule; +use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; +use style::stylesheets::CssRules as StyleCssRules; #[dom_struct] pub struct CSSGroupingRule { cssrule: CSSRule, + #[ignore_heap_size_of = "Arc"] + rules: StyleCssRules, + rulelist: MutNullableHeap<JS<CSSRuleList>>, } impl CSSGroupingRule { - pub fn new_inherited(parent: &CSSStyleSheet) -> CSSGroupingRule { + pub fn new_inherited(parent: Option<&CSSStyleSheet>, + rules: StyleCssRules) -> CSSGroupingRule { CSSGroupingRule { cssrule: CSSRule::new_inherited(parent), + rules: rules, + rulelist: MutNullableHeap::new(None), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet) -> Root<CSSGroupingRule> { - reflect_dom_object(box CSSGroupingRule::new_inherited(parent), + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, rules: StyleCssRules) -> Root<CSSGroupingRule> { + reflect_dom_object(box CSSGroupingRule::new_inherited(parent, rules), window, CSSGroupingRuleBinding::Wrap) } + + fn rulelist(&self) -> Root<CSSRuleList> { + let sheet = self.upcast::<CSSRule>().GetParentStyleSheet(); + let sheet = sheet.as_ref().map(|s| &**s); + self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), + sheet, + RulesSource::Rules(self.rules.clone()))) + } +} + +impl CSSGroupingRuleMethods for CSSGroupingRule { + // https://drafts.csswg.org/cssom/#dom-cssgroupingrule-cssrules + fn CssRules(&self) -> Root<CSSRuleList> { + // XXXManishearth check origin clean flag + self.rulelist() + } + + // https://drafts.csswg.org/cssom/#dom-cssgroupingrule-insertrule + fn InsertRule(&self, rule: DOMString, index: u32) -> Fallible<u32> { + self.rulelist().insert_rule(&rule, index, /* nested */ true) + } + + // https://drafts.csswg.org/cssom/#dom-cssgroupingrule-deleterule + fn DeleteRule(&self, index: u32) -> ErrorResult { + self.rulelist().remove_rule(index) + } } diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs new file mode 100644 index 00000000000..e09099e1135 --- /dev/null +++ b/components/script/dom/csskeyframerule.rs @@ -0,0 +1,50 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::CSSKeyframeRuleBinding; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssstylesheet::CSSStyleSheet; +use dom::window::Window; +use parking_lot::RwLock; +use std::sync::Arc; +use style::keyframes::Keyframe; +use style_traits::ToCss; + +#[dom_struct] +pub struct CSSKeyframeRule { + cssrule: CSSRule, + #[ignore_heap_size_of = "Arc"] + keyframerule: Arc<RwLock<Keyframe>>, +} + +impl CSSKeyframeRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, keyframerule: Arc<RwLock<Keyframe>>) -> CSSKeyframeRule { + CSSKeyframeRule { + cssrule: CSSRule::new_inherited(parent), + keyframerule: keyframerule, + } + } + + #[allow(unrooted_must_root)] + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + keyframerule: Arc<RwLock<Keyframe>>) -> Root<CSSKeyframeRule> { + reflect_dom_object(box CSSKeyframeRule::new_inherited(parent, keyframerule), + window, + CSSKeyframeRuleBinding::Wrap) + } +} + +impl SpecificCSSRule for CSSKeyframeRule { + fn ty(&self) -> u16 { + use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants; + CSSRuleConstants::KEYFRAME_RULE + } + + fn get_css(&self) -> DOMString { + self.keyframerule.read().to_css_string().into() + } +} diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 138c8b20558..b7baf6b85a9 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -2,16 +2,25 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use cssparser::Parser; use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding; -use dom::bindings::js::Root; -use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding::CSSKeyframesRuleMethods; +use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; +use dom::csskeyframerule::CSSKeyframeRule; use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; -use style::stylesheets::KeyframesRule; +use style::keyframes::{Keyframe, KeyframeSelector}; +use style::parser::ParserContextExtraData; +use style::stylesheets::{KeyframesRule, Origin}; use style_traits::ToCss; #[dom_struct] @@ -19,23 +28,84 @@ pub struct CSSKeyframesRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] keyframesrule: Arc<RwLock<KeyframesRule>>, + rulelist: MutNullableHeap<JS<CSSRuleList>>, } impl CSSKeyframesRule { - fn new_inherited(parent: &CSSStyleSheet, keyframesrule: Arc<RwLock<KeyframesRule>>) -> CSSKeyframesRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, keyframesrule: Arc<RwLock<KeyframesRule>>) -> CSSKeyframesRule { CSSKeyframesRule { cssrule: CSSRule::new_inherited(parent), keyframesrule: keyframesrule, + rulelist: MutNullableHeap::new(None), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, keyframesrule: Arc<RwLock<KeyframesRule>>) -> Root<CSSKeyframesRule> { reflect_dom_object(box CSSKeyframesRule::new_inherited(parent, keyframesrule), window, CSSKeyframesRuleBinding::Wrap) } + + fn rulelist(&self) -> Root<CSSRuleList> { + self.rulelist.or_init(|| { + let sheet = self.upcast::<CSSRule>().GetParentStyleSheet(); + let sheet = sheet.as_ref().map(|s| &**s); + CSSRuleList::new(self.global().as_window(), + sheet, + RulesSource::Keyframes(self.keyframesrule.clone())) + }) + } + + /// Given a keyframe selector, finds the index of the first corresponding rule if any + fn find_rule(&self, selector: &str) -> Option<usize> { + let mut input = Parser::new(selector); + if let Ok(sel) = KeyframeSelector::parse(&mut input) { + // This finds the *last* element matching a selector + // because that's the rule that applies. Thus, rposition + self.keyframesrule.read() + .keyframes.iter().rposition(|frame| { + frame.read().selector == sel + }) + } else { + None + } + } +} + +impl CSSKeyframesRuleMethods for CSSKeyframesRule { + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-cssrules + fn CssRules(&self) -> Root<CSSRuleList> { + self.rulelist() + } + + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-appendrule + fn AppendRule(&self, rule: DOMString) { + let global = self.global(); + let window = global.as_window(); + let doc = window.Document(); + let rule = Keyframe::parse(&rule, Origin::Author, doc.url().clone(), + ParserContextExtraData::default()); + if let Ok(rule) = rule { + self.keyframesrule.write().keyframes.push(rule); + self.rulelist().append_lazy_dom_rule(); + } + } + + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-deleterule + fn DeleteRule(&self, selector: DOMString) { + if let Some(idx) = self.find_rule(&selector) { + let _ = self.rulelist().remove_rule(idx as u32); + } + } + + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-findrule + fn FindRule(&self, selector: DOMString) -> Option<Root<CSSKeyframeRule>> { + self.find_rule(&selector).and_then(|idx| { + self.rulelist().item(idx as u32) + }).and_then(Root::downcast) + } } impl SpecificCSSRule for CSSKeyframesRule { @@ -47,4 +117,8 @@ impl SpecificCSSRule for CSSKeyframesRule { fn get_css(&self) -> DOMString { self.keyframesrule.read().to_css_string().into() } + + fn deparent_children(&self) { + self.rulelist.get().map(|list| list.deparent_all()); + } } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index a8d8649b31f..67933fccd3b 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -23,15 +23,16 @@ pub struct CSSMediaRule { } impl CSSMediaRule { - fn new_inherited(parent: &CSSStyleSheet, mediarule: Arc<RwLock<MediaRule>>) -> CSSMediaRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, mediarule: Arc<RwLock<MediaRule>>) -> CSSMediaRule { + let list = mediarule.read().rules.clone(); CSSMediaRule { - cssrule: CSSGroupingRule::new_inherited(parent), + cssrule: CSSGroupingRule::new_inherited(parent, list), mediarule: mediarule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, mediarule: Arc<RwLock<MediaRule>>) -> Root<CSSMediaRule> { reflect_dom_object(box CSSMediaRule::new_inherited(parent, mediarule), window, diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs index 04c4431df77..4e93eea2e1f 100644 --- a/components/script/dom/cssnamespacerule.rs +++ b/components/script/dom/cssnamespacerule.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::CSSNamespaceRuleBinding; +use dom::bindings::codegen::Bindings::CSSNamespaceRuleBinding::CSSNamespaceRuleMethods; use dom::bindings::js::Root; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; @@ -22,7 +23,7 @@ pub struct CSSNamespaceRule { } impl CSSNamespaceRule { - fn new_inherited(parent: &CSSStyleSheet, namespacerule: Arc<RwLock<NamespaceRule>>) -> CSSNamespaceRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, namespacerule: Arc<RwLock<NamespaceRule>>) -> CSSNamespaceRule { CSSNamespaceRule { cssrule: CSSRule::new_inherited(parent), namespacerule: namespacerule, @@ -30,7 +31,7 @@ impl CSSNamespaceRule { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, namespacerule: Arc<RwLock<NamespaceRule>>) -> Root<CSSNamespaceRule> { reflect_dom_object(box CSSNamespaceRule::new_inherited(parent, namespacerule), window, @@ -38,6 +39,20 @@ impl CSSNamespaceRule { } } +impl CSSNamespaceRuleMethods for CSSNamespaceRule { + // https://drafts.csswg.org/cssom/#dom-cssnamespacerule-prefix + fn Prefix(&self) -> DOMString { + self.namespacerule.read().prefix + .as_ref().map(|s| s.to_string().into()) + .unwrap_or(DOMString::new()) + } + + // https://drafts.csswg.org/cssom/#dom-cssnamespacerule-namespaceuri + fn NamespaceURI(&self) -> DOMString { + (*self.namespacerule.read().url).into() + } +} + impl SpecificCSSRule for CSSNamespaceRule { fn ty(&self) -> u16 { use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants; diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs index e46738bb1b4..ca1e52b77f0 100644 --- a/components/script/dom/cssrule.rs +++ b/components/script/dom/cssrule.rs @@ -9,6 +9,7 @@ use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssfontfacerule::CSSFontFaceRule; +use dom::csskeyframerule::CSSKeyframeRule; use dom::csskeyframesrule::CSSKeyframesRule; use dom::cssmediarule::CSSMediaRule; use dom::cssnamespacerule::CSSNamespaceRule; @@ -27,15 +28,15 @@ pub struct CSSRule { impl CSSRule { #[allow(unrooted_must_root)] - pub fn new_inherited(parent: &CSSStyleSheet) -> CSSRule { + pub fn new_inherited(parent: Option<&CSSStyleSheet>) -> CSSRule { CSSRule { reflector_: Reflector::new(), - parent: MutNullableHeap::new(Some(parent)), + parent: MutNullableHeap::new(parent), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet) -> Root<CSSRule> { + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>) -> Root<CSSRule> { reflect_dom_object(box CSSRule::new_inherited(parent), window, CSSRuleBinding::Wrap) @@ -54,6 +55,8 @@ impl CSSRule { rule as &SpecificCSSRule } else if let Some(rule) = self.downcast::<CSSViewportRule>() { rule as &SpecificCSSRule + } else if let Some(rule) = self.downcast::<CSSKeyframeRule>() { + rule as &SpecificCSSRule } else { unreachable!() } @@ -61,7 +64,7 @@ impl CSSRule { // Given a StyleCssRule, create a new instance of a derived class of // CSSRule based on which rule it is - pub fn new_specific(window: &Window, parent: &CSSStyleSheet, + pub fn new_specific(window: &Window, parent: Option<&CSSStyleSheet>, rule: StyleCssRule) -> Root<CSSRule> { // be sure to update the match in as_specific when this is updated match rule { @@ -73,6 +76,21 @@ impl CSSRule { StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent, s)), } } + + /// Sets owner sheet/rule to null + pub fn detach(&self) { + self.deparent(); + // should set parent rule to None when we add parent rule support + } + + /// Sets owner sheet to null (and does the same for all children) + pub fn deparent(&self) { + self.parent.set(None); + // https://github.com/w3c/csswg-drafts/issues/722 + // Spec doesn't ask us to do this, but it makes sense + // and browsers implement this behavior + self.as_specific().deparent_children(); + } } impl CSSRuleMethods for CSSRule { @@ -100,4 +118,8 @@ impl CSSRuleMethods for CSSRule { pub trait SpecificCSSRule { fn ty(&self) -> u16; fn get_css(&self) -> DOMString; + /// Remove CSSStyleSheet parent from all transitive children + fn deparent_children(&self) { + // most CSSRules do nothing here + } } diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 1c383403a00..deb6b93e8b1 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -2,61 +2,248 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CSSRuleListBinding; use dom::bindings::codegen::Bindings::CSSRuleListBinding::CSSRuleListMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; +use dom::csskeyframerule::CSSKeyframeRule; use dom::cssrule::CSSRule; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; -use style::stylesheets::CssRules; +use parking_lot::RwLock; +use std::sync::Arc; +use style::parser::ParserContextExtraData; +use style::stylesheets::{CssRules, KeyframesRule, Origin}; +use style::stylesheets::CssRule as StyleCssRule; +no_jsmanaged_fields!(RulesSource); no_jsmanaged_fields!(CssRules); #[dom_struct] pub struct CSSRuleList { reflector_: Reflector, - sheet: JS<CSSStyleSheet>, + sheet: MutNullableHeap<JS<CSSStyleSheet>>, #[ignore_heap_size_of = "Arc"] - rules: CssRules, - dom_rules: Vec<MutNullableHeap<JS<CSSRule>>> + rules: RulesSource, + dom_rules: DOMRefCell<Vec<MutNullableHeap<JS<CSSRule>>>> +} + +pub enum RulesSource { + Rules(CssRules), + Keyframes(Arc<RwLock<KeyframesRule>>), } impl CSSRuleList { #[allow(unrooted_must_root)] - pub fn new_inherited(sheet: &CSSStyleSheet, rules: CssRules) -> CSSRuleList { - let dom_rules = rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect(); + pub fn new_inherited(sheet: Option<&CSSStyleSheet>, rules: RulesSource) -> CSSRuleList { + let dom_rules = match rules { + RulesSource::Rules(ref rules) => { + rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect() + } + RulesSource::Keyframes(ref rules) => { + rules.read().keyframes.iter().map(|_| MutNullableHeap::new(None)).collect() + } + }; + CSSRuleList { reflector_: Reflector::new(), - sheet: JS::from_ref(sheet), + sheet: MutNullableHeap::new(sheet), rules: rules, - dom_rules: dom_rules, + dom_rules: DOMRefCell::new(dom_rules), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, sheet: &CSSStyleSheet, rules: CssRules) -> Root<CSSRuleList> { + pub fn new(window: &Window, sheet: Option<&CSSStyleSheet>, + rules: RulesSource) -> Root<CSSRuleList> { reflect_dom_object(box CSSRuleList::new_inherited(sheet, rules), window, CSSRuleListBinding::Wrap) } + + /// https://drafts.csswg.org/cssom/#insert-a-css-rule + /// + /// Should only be called for CssRules-backed rules. Use append_lazy_rule + /// for keyframes-backed rules. + pub fn insert_rule(&self, rule: &str, idx: u32, nested: bool) -> Fallible<u32> { + use style::stylesheets::SingleRuleParseError; + /// Insert an item into a vector, appending if it is out of bounds + fn insert<T>(vec: &mut Vec<T>, index: usize, item: T) { + if index >= vec.len() { + vec.push(item); + } else { + vec.insert(index, item); + } + } + + let css_rules = if let RulesSource::Rules(ref rules) = self.rules { + rules + } else { + panic!("Called insert_rule on non-CssRule-backed CSSRuleList"); + }; + + let global = self.global(); + let window = global.as_window(); + let doc = window.Document(); + let index = idx as usize; + + + let new_rule = { + let rules = css_rules.0.read(); + let state = if nested { + None + } else { + Some(CssRules::state_at_index(&rules, index)) + }; + + let rev_state = CssRules::state_at_index_rev(&rules, index); + + // Step 1, 2 + // XXXManishearth get url from correct location + // XXXManishearth should we also store the namespace map? + let parse_result = StyleCssRule::parse(&rule, Origin::Author, + doc.url().clone(), + ParserContextExtraData::default(), + state); + + if let Err(SingleRuleParseError::Syntax) = parse_result { + return Err(Error::Syntax) + } + + // Step 3, 4 + if index > rules.len() { + return Err(Error::IndexSize); + } + + let (new_rule, new_state) = try!(parse_result.map_err(|_| Error::HierarchyRequest)); + + if new_state > rev_state { + // We inserted a rule too early, e.g. inserting + // a regular style rule before @namespace rules + return Err((Error::HierarchyRequest)); + } + + // Step 6 + if let StyleCssRule::Namespace(..) = new_rule { + if !CssRules::only_ns_or_import(&rules) { + return Err(Error::InvalidState); + } + } + + new_rule + }; + + insert(&mut css_rules.0.write(), index, new_rule.clone()); + let sheet = self.sheet.get(); + let sheet = sheet.as_ref().map(|sheet| &**sheet); + let dom_rule = CSSRule::new_specific(&window, sheet, new_rule); + insert(&mut self.dom_rules.borrow_mut(), + index, MutNullableHeap::new(Some(&*dom_rule))); + Ok((idx)) + } + + // https://drafts.csswg.org/cssom/#remove-a-css-rule + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-deleterule + // In case of a keyframe rule, index must be valid. + pub fn remove_rule(&self, index: u32) -> ErrorResult { + let index = index as usize; + + match self.rules { + RulesSource::Rules(ref css_rules) => { + // https://drafts.csswg.org/cssom/#remove-a-css-rule + { + let rules = css_rules.0.read(); + + // Step 1, 2 + if index >= rules.len() { + return Err(Error::IndexSize); + } + + // Step 3 + let ref rule = rules[index]; + + // Step 4 + if let StyleCssRule::Namespace(..) = *rule { + if !CssRules::only_ns_or_import(&rules) { + return Err(Error::InvalidState); + } + } + } + + // Step 5, 6 + let mut dom_rules = self.dom_rules.borrow_mut(); + css_rules.0.write().remove(index); + dom_rules[index].get().map(|r| r.detach()); + dom_rules.remove(index); + Ok(()) + } + RulesSource::Keyframes(ref kf) => { + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-deleterule + let mut dom_rules = self.dom_rules.borrow_mut(); + dom_rules[index].get().map(|r| r.detach()); + dom_rules.remove(index); + kf.write().keyframes.remove(index); + Ok(()) + } + } + } + + // Remove parent stylesheets from all children + pub fn deparent_all(&self) { + for rule in self.dom_rules.borrow().iter() { + rule.get().map(|r| Root::upcast(r).deparent()); + } + } + + pub fn item(&self, idx: u32) -> Option<Root<CSSRule>> { + self.dom_rules.borrow().get(idx as usize).map(|rule| { + rule.or_init(|| { + let sheet = self.sheet.get(); + let sheet = sheet.as_ref().map(|sheet| &**sheet); + match self.rules { + RulesSource::Rules(ref rules) => { + CSSRule::new_specific(self.global().as_window(), + sheet, + rules.0.read()[idx as usize].clone()) + } + RulesSource::Keyframes(ref rules) => { + Root::upcast(CSSKeyframeRule::new(self.global().as_window(), + sheet, + rules.read() + .keyframes[idx as usize] + .clone())) + } + } + + }) + }) + } + + /// Add a rule to the list of DOM rules. This list is lazy, + /// so we just append a placeholder. + /// + /// Should only be called for keyframes-backed rules, use insert_rule + /// for CssRules-backed rules + pub fn append_lazy_dom_rule(&self) { + if let RulesSource::Rules(..) = self.rules { + panic!("Can only call append_lazy_rule with keyframes-backed CSSRules"); + } + self.dom_rules.borrow_mut().push(MutNullableHeap::new(None)); + } } impl CSSRuleListMethods for CSSRuleList { // https://drafts.csswg.org/cssom/#ref-for-dom-cssrulelist-item-1 fn Item(&self, idx: u32) -> Option<Root<CSSRule>> { - self.dom_rules.get(idx as usize).map(|rule| { - rule.or_init(|| { - CSSRule::new_specific(self.global().as_window(), - &self.sheet, - self.rules.0.read()[idx as usize].clone()) - }) - }) + self.item(idx) } // https://drafts.csswg.org/cssom/#dom-cssrulelist-length fn Length(&self) -> u32 { - self.dom_rules.len() as u32 + self.dom_rules.borrow().len() as u32 } // check-tidy: no specs after this line diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs index 30726018ca9..7d776655147 100644 --- a/components/script/dom/cssstylerule.rs +++ b/components/script/dom/cssstylerule.rs @@ -22,7 +22,7 @@ pub struct CSSStyleRule { } impl CSSStyleRule { - fn new_inherited(parent: &CSSStyleSheet, stylerule: Arc<RwLock<StyleRule>>) -> CSSStyleRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, stylerule: Arc<RwLock<StyleRule>>) -> CSSStyleRule { CSSStyleRule { cssrule: CSSRule::new_inherited(parent), stylerule: stylerule, @@ -30,7 +30,7 @@ impl CSSStyleRule { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, stylerule: Arc<RwLock<StyleRule>>) -> Root<CSSStyleRule> { reflect_dom_object(box CSSStyleRule::new_inherited(parent, stylerule), window, diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index d5a9342a75a..2e2ac45d867 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -4,10 +4,11 @@ use dom::bindings::codegen::Bindings::CSSStyleSheetBinding; use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods; +use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::js::{JS, Root, MutNullableHeap}; use dom::bindings::reflector::{reflect_dom_object, Reflectable}; use dom::bindings::str::DOMString; -use dom::cssrulelist::CSSRuleList; +use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::stylesheet::StyleSheet; use dom::window::Window; use std::sync::Arc; @@ -40,12 +41,33 @@ impl CSSStyleSheet { window, CSSStyleSheetBinding::Wrap) } + + fn rulelist(&self) -> Root<CSSRuleList> { + self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), + Some(self), + RulesSource::Rules(self.style_stylesheet + .rules.clone()))) + } } impl CSSStyleSheetMethods for CSSStyleSheet { // https://drafts.csswg.org/cssom/#dom-cssstylesheet-cssrules fn CssRules(&self) -> Root<CSSRuleList> { - self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), self, self.style_stylesheet.rules.clone())) + // XXXManishearth check origin clean flag + // https://github.com/servo/servo/issues/14327 + self.rulelist() + } + + // https://drafts.csswg.org/cssom/#dom-cssstylesheet-insertrule + fn InsertRule(&self, rule: DOMString, index: u32) -> Fallible<u32> { + // XXXManishearth check origin clean flag + self.rulelist().insert_rule(&rule, index, /* nested */ false) + } + + // https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule + fn DeleteRule(&self, index: u32) -> ErrorResult { + // XXXManishearth check origin clean flag + self.rulelist().remove_rule(index) } } diff --git a/components/script/dom/cssviewportrule.rs b/components/script/dom/cssviewportrule.rs index f534c535a64..b324b0c64f5 100644 --- a/components/script/dom/cssviewportrule.rs +++ b/components/script/dom/cssviewportrule.rs @@ -22,7 +22,7 @@ pub struct CSSViewportRule { } impl CSSViewportRule { - fn new_inherited(parent: &CSSStyleSheet, viewportrule: Arc<RwLock<ViewportRule>>) -> CSSViewportRule { + fn new_inherited(parent: Option<&CSSStyleSheet>, viewportrule: Arc<RwLock<ViewportRule>>) -> CSSViewportRule { CSSViewportRule { cssrule: CSSRule::new_inherited(parent), viewportrule: viewportrule, @@ -30,7 +30,7 @@ impl CSSViewportRule { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: &CSSStyleSheet, + pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, viewportrule: Arc<RwLock<ViewportRule>>) -> Root<CSSViewportRule> { reflect_dom_object(box CSSViewportRule::new_inherited(parent, viewportrule), window, diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index d1f6d8e957f..f311d022470 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -22,6 +22,7 @@ use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::htmlelement::HTMLElement; use dom::node::{Node, document_from_node, window_from_node}; +use dom::stylesheet::StyleSheet as DOMStyleSheet; use dom::virtualmethods::VirtualMethods; use encoding::EncodingRef; use encoding::all::UTF_8; @@ -452,4 +453,9 @@ impl HTMLLinkElementMethods for HTMLLinkElement { // https://html.spec.whatwg.org/multipage/#dom-link-target make_setter!(SetTarget, "target"); + + // https://drafts.csswg.org/cssom/#dom-linkstyle-sheet + fn GetSheet(&self) -> Option<Root<DOMStyleSheet>> { + self.get_cssom_stylesheet().map(Root::upcast) + } } diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index d65153bee31..6a20bf06cdd 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -5,6 +5,7 @@ use cssparser::Parser as CssParser; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HTMLStyleElementBinding; +use dom::bindings::codegen::Bindings::HTMLStyleElementBinding::HTMLStyleElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; @@ -14,6 +15,7 @@ use dom::document::Document; use dom::element::Element; use dom::htmlelement::HTMLElement; use dom::node::{ChildrenMutation, Node, document_from_node, window_from_node}; +use dom::stylesheet::StyleSheet as DOMStyleSheet; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; use script_layout_interface::message::Msg; @@ -117,3 +119,10 @@ impl VirtualMethods for HTMLStyleElement { } } } + +impl HTMLStyleElementMethods for HTMLStyleElement { + // https://drafts.csswg.org/cssom/#dom-linkstyle-sheet + fn GetSheet(&self) -> Option<Root<DOMStyleSheet>> { + self.get_cssom_stylesheet().map(Root::upcast) + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 05ec1963a20..23209d89e07 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -244,6 +244,7 @@ pub mod crypto; pub mod css; pub mod cssfontfacerule; pub mod cssgroupingrule; +pub mod csskeyframerule; pub mod csskeyframesrule; pub mod cssmediarule; pub mod cssnamespacerule; diff --git a/components/script/dom/webidls/Bluetooth.webidl b/components/script/dom/webidls/Bluetooth.webidl index 89f09205f7e..b925e0b0b25 100644 --- a/components/script/dom/webidls/Bluetooth.webidl +++ b/components/script/dom/webidls/Bluetooth.webidl @@ -4,16 +4,25 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetooth -dictionary BluetoothRequestDeviceFilter { +dictionary BluetoothDataFilterInit { +// BufferSource dataPrefix; + sequence<octet> dataPrefix; +// BufferSource mask; + sequence<octet> mask; +}; + +dictionary BluetoothLEScanFilterInit { sequence<BluetoothServiceUUID> services; DOMString name; DOMString namePrefix; - unsigned short manufacturerId; - BluetoothServiceUUID serviceDataUUID; +// Maps unsigned shorts to BluetoothDataFilters. + MozMap<BluetoothDataFilterInit> manufacturerData; +// Maps BluetoothServiceUUIDs to BluetoothDataFilters. + MozMap<BluetoothDataFilterInit> serviceData; }; dictionary RequestDeviceOptions { - sequence<BluetoothRequestDeviceFilter> filters; + sequence<BluetoothLEScanFilterInit> filters; sequence<BluetoothServiceUUID> optionalServices /*= []*/; boolean acceptAllDevices = false; }; @@ -23,6 +32,12 @@ interface Bluetooth { // [SecureContext] // readonly attribute BluetoothDevice? referringDevice; // [SecureContext] +// Promise<boolean> getAvailability(); +// [SecureContext] +// attribute EventHandler onavailabilitychanged; +// [SecureContext] +// readonly attribute BluetoothDevice? referringDevice; + [SecureContext] Promise<BluetoothDevice> requestDevice(optional RequestDeviceOptions options); }; diff --git a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl index 596a1095457..d1d937475b4 100644 --- a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl +++ b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl @@ -17,8 +17,8 @@ interface BluetoothRemoteGATTCharacteristic { //Promise<DataView> readValue(); Promise<void> writeValue(sequence<octet> value); //Promise<void> writeValue(BufferSource value); - //Promise<void> startNotifications(); - //Promise<void> stopNotifications(); + Promise<BluetoothRemoteGATTCharacteristic> startNotifications(); + Promise<BluetoothRemoteGATTCharacteristic> stopNotifications(); }; //BluetootRemoteGATTCharacteristic implements EventTarget; diff --git a/components/script/dom/webidls/CSSGroupingRule.webidl b/components/script/dom/webidls/CSSGroupingRule.webidl index 6a317191ff6..9f8347a17d5 100644 --- a/components/script/dom/webidls/CSSGroupingRule.webidl +++ b/components/script/dom/webidls/CSSGroupingRule.webidl @@ -5,8 +5,8 @@ // https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface [Exposed=Window] interface CSSGroupingRule : CSSRule { - // [SameObject] readonly attribute CSSRuleList cssRules; - // unsigned long insertRule(DOMString rule, unsigned long index); - // void deleteRule(unsigned long index); + [SameObject] readonly attribute CSSRuleList cssRules; + [Throws] unsigned long insertRule(DOMString rule, unsigned long index); + [Throws] void deleteRule(unsigned long index); }; diff --git a/components/script/dom/webidls/CSSKeyframeRule.webidl b/components/script/dom/webidls/CSSKeyframeRule.webidl new file mode 100644 index 00000000000..5458440be6d --- /dev/null +++ b/components/script/dom/webidls/CSSKeyframeRule.webidl @@ -0,0 +1,10 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +// https://drafts.csswg.org/css-animations/#interface-csskeyframerule +[Exposed=Window] +interface CSSKeyframeRule : CSSRule { + // attribute DOMString keyText; + // readonly attribute CSSStyleDeclaration style; +}; diff --git a/components/script/dom/webidls/CSSKeyframesRule.webidl b/components/script/dom/webidls/CSSKeyframesRule.webidl index db152d72850..34d45e1a357 100644 --- a/components/script/dom/webidls/CSSKeyframesRule.webidl +++ b/components/script/dom/webidls/CSSKeyframesRule.webidl @@ -6,9 +6,9 @@ [Exposed=Window] interface CSSKeyframesRule : CSSRule { // attribute DOMString name; - // readonly attribute CSSRuleList cssRules; + readonly attribute CSSRuleList cssRules; - // void appendRule(DOMString rule); - // void deleteRule(DOMString select); - // CSSKeyframeRule? findRule(DOMString select); + void appendRule(DOMString rule); + void deleteRule(DOMString select); + CSSKeyframeRule? findRule(DOMString select); }; diff --git a/components/script/dom/webidls/CSSNamespaceRule.webidl b/components/script/dom/webidls/CSSNamespaceRule.webidl index a8d6b61548f..aa1ce87e289 100644 --- a/components/script/dom/webidls/CSSNamespaceRule.webidl +++ b/components/script/dom/webidls/CSSNamespaceRule.webidl @@ -5,6 +5,6 @@ // https://drafts.csswg.org/cssom/#the-cssnamespacerule-interface [Exposed=Window] interface CSSNamespaceRule : CSSRule { - // readonly attribute DOMString namespaceURI; - // readonly attribute DOMString prefix; + readonly attribute DOMString namespaceURI; + readonly attribute DOMString prefix; }; diff --git a/components/script/dom/webidls/CSSStyleSheet.webidl b/components/script/dom/webidls/CSSStyleSheet.webidl index 99ab3234705..6fba0cf983a 100644 --- a/components/script/dom/webidls/CSSStyleSheet.webidl +++ b/components/script/dom/webidls/CSSStyleSheet.webidl @@ -7,6 +7,6 @@ interface CSSStyleSheet : StyleSheet { // readonly attribute CSSRule? ownerRule; [SameObject] readonly attribute CSSRuleList cssRules; - // unsigned long insertRule(DOMString rule, unsigned long index); - // void deleteRule(unsigned long index); + [Throws] unsigned long insertRule(DOMString rule, unsigned long index); + [Throws] void deleteRule(unsigned long index); }; diff --git a/components/script/dom/webidls/HTMLLinkElement.webidl b/components/script/dom/webidls/HTMLLinkElement.webidl index 8c1bf496590..e7bec059efe 100644 --- a/components/script/dom/webidls/HTMLLinkElement.webidl +++ b/components/script/dom/webidls/HTMLLinkElement.webidl @@ -15,7 +15,7 @@ interface HTMLLinkElement : HTMLElement { // also has obsolete members }; -//HTMLLinkElement implements LinkStyle; +HTMLLinkElement implements LinkStyle; // https://html.spec.whatwg.org/multipage/#HTMLLinkElement-partial partial interface HTMLLinkElement { diff --git a/components/script/dom/webidls/HTMLStyleElement.webidl b/components/script/dom/webidls/HTMLStyleElement.webidl index dd766f41d22..78926c2c1a8 100644 --- a/components/script/dom/webidls/HTMLStyleElement.webidl +++ b/components/script/dom/webidls/HTMLStyleElement.webidl @@ -8,4 +8,4 @@ interface HTMLStyleElement : HTMLElement { // attribute DOMString type; // attribute boolean scoped; }; -//HTMLStyleElement implements LinkStyle; +HTMLStyleElement implements LinkStyle; diff --git a/components/script/dom/webidls/StyleSheet.webidl b/components/script/dom/webidls/StyleSheet.webidl index a63e2a41f01..336bc6b282c 100644 --- a/components/script/dom/webidls/StyleSheet.webidl +++ b/components/script/dom/webidls/StyleSheet.webidl @@ -15,3 +15,9 @@ interface StyleSheet { // [SameObject, PutForwards=mediaText] readonly attribute MediaList media; // attribute boolean disabled; }; + +// https://drafts.csswg.org/cssom/#the-linkstyle-interface +[NoInterfaceObject] +interface LinkStyle { + readonly attribute StyleSheet? sheet; +}; |