diff options
Diffstat (limited to 'components/script')
31 files changed, 714 insertions, 103 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 6a8a5d1b25e..eaf86e3b39f 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -91,7 +91,7 @@ rustc-serialize = "0.3" selectors = {version = "0.5", features = ["heap_size"]} serde = "0.7" smallvec = "0.1" -string_cache = {version = "0.2.11", features = ["heap_size", "unstable"]} +string_cache = {version = "0.2.12", features = ["heap_size", "unstable"]} time = "0.1.12" unicase = "1.0" url = {version = "0.5.7", features = ["heap_size"]} diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 9cac7d9b940..e50f8ace9d0 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -143,6 +143,17 @@ impl<'a> GlobalRef<'a> { } } + /// Get the [base url](https://html.spec.whatwg.org/multipage/#api-base-url) + /// for this global scope. + pub fn api_base_url(&self) -> Url { + match *self { + // https://html.spec.whatwg.org/multipage/#script-settings-for-browsing-contexts:api-base-url + GlobalRef::Window(ref window) => window.Document().base_url(), + // https://html.spec.whatwg.org/multipage/#script-settings-for-workers:api-base-url + GlobalRef::Worker(ref worker) => worker.get_url().clone(), + } + } + /// `ScriptChan` used to send messages to the event loop of this global's /// thread. pub fn script_chan(&self) -> Box<ScriptChan + Send> { diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 9cc2d13fb77..16138b33641 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -62,6 +62,7 @@ use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; use net_traits::response::HttpsState; use net_traits::storage_thread::StorageType; +use offscreen_gl_context::GLLimits; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use script_runtime::ScriptChan; @@ -308,7 +309,7 @@ no_jsmanaged_fields!(StorageType); no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle); no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending); no_jsmanaged_fields!(RepetitionStyle); -no_jsmanaged_fields!(WebGLError); +no_jsmanaged_fields!(WebGLError, GLLimits); no_jsmanaged_fields!(TimeProfilerChan); no_jsmanaged_fields!(MemProfilerChan); no_jsmanaged_fields!(PseudoElement); diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 4e2af78f31a..f27bc3a35fb 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -377,7 +377,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { }, // Others _ => { - match this.get_size_for_layout() { + match this.size_for_layout() { 0 => None, s => Some(s as i32), } @@ -571,7 +571,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { // TODO option and menuitem can also have a checked state. match self.downcast::<HTMLInputElement>() { Some(input) => unsafe { - input.get_checked_state_for_layout() + input.checked_state_for_layout() }, None => false, } @@ -583,7 +583,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { // TODO progress elements can also be matched with :indeterminate match self.downcast::<HTMLInputElement>() { Some(input) => unsafe { - input.get_indeterminate_state_for_layout() + input.indeterminate_state_for_layout() }, None => false, } diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index 8ac184ea51d..ca133b88dbb 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -47,6 +47,16 @@ impl HTMLBodyElement { let element = HTMLBodyElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLBodyElementBinding::Wrap) } + + /// https://drafts.csswg.org/cssom-view/#the-html-body-element + pub fn is_the_html_body_element(&self) -> bool { + let self_node = self.upcast::<Node>(); + let root_elem = self.upcast::<Element>().root_element(); + let root_node = root_elem.upcast::<Node>(); + root_node.is_parent_of(self_node) && + self_node.preceding_siblings().all(|n| !n.is::<HTMLBodyElement>()) + } + } impl HTMLBodyElementMethods for HTMLBodyElement { diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index b3c95f89127..566a86d8804 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -233,7 +233,7 @@ impl HTMLElementMethods for HTMLElement { document.commit_focus_transaction(FocusType::Element); } - // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface + // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent fn GetOffsetParent(&self) -> Option<Root<Element>> { if self.is::<HTMLBodyElement>() || self.is::<HTMLHtmlElement>() { return None; @@ -246,7 +246,7 @@ impl HTMLElementMethods for HTMLElement { element } - // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface + // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop fn OffsetTop(&self) -> i32 { if self.is::<HTMLBodyElement>() { return 0; @@ -259,7 +259,7 @@ impl HTMLElementMethods for HTMLElement { rect.origin.y.to_nearest_px() } - // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface + // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft fn OffsetLeft(&self) -> i32 { if self.is::<HTMLBodyElement>() { return 0; @@ -272,7 +272,7 @@ impl HTMLElementMethods for HTMLElement { rect.origin.x.to_nearest_px() } - // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface + // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetwidth fn OffsetWidth(&self) -> i32 { let node = self.upcast::<Node>(); let window = window_from_node(self); @@ -281,7 +281,7 @@ impl HTMLElementMethods for HTMLElement { rect.size.width.to_nearest_px() } - // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface + // https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetheight fn OffsetHeight(&self) -> i32 { let node = self.upcast::<Node>(); let window = window_from_node(self); diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 70a2a7ad730..3e7421de443 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -414,7 +414,7 @@ impl HTMLFormElement { HTMLElementTypeId::HTMLInputElement => { let input = child.downcast::<HTMLInputElement>().unwrap(); // Step 3.2-3.7 - if let Some(datum) = input.get_form_datum(submitter) { + if let Some(datum) = input.form_datum(submitter) { data_set.push(datum); } } diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs index 93fdebbc954..bea12efbfea 100644 --- a/components/script/dom/htmlhrelement.rs +++ b/components/script/dom/htmlhrelement.rs @@ -37,6 +37,12 @@ impl HTMLHRElement { } impl HTMLHRElementMethods for HTMLHRElement { + // https://html.spec.whatwg.org/multipage/#dom-hr-align + make_getter!(Align, "align"); + + // https://html.spec.whatwg.org/multipage/#dom-hr-align + make_atomic_setter!(SetAlign, "align"); + // https://html.spec.whatwg.org/multipage/#dom-hr-color make_getter!(Color, "color"); @@ -86,6 +92,7 @@ impl VirtualMethods for HTMLHRElement { fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { match name { + &atom!("align") => AttrValue::from_dimension(value), &atom!("color") => AttrValue::from_legacy_color(value), &atom!("width") => AttrValue::from_dimension(value), _ => self.super_type().unwrap().parse_plain_attribute(name, value), diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 174a312448f..9c969ceec98 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -164,7 +164,7 @@ impl HTMLInputElement { } // https://html.spec.whatwg.org/multipage/#input-type-attr-summary - fn get_value_mode(&self) -> ValueMode { + fn value_mode(&self) -> ValueMode { match self.input_type.get() { InputType::InputSubmit | InputType::InputReset | @@ -208,15 +208,15 @@ impl HTMLInputElement { pub trait LayoutHTMLInputElementHelpers { #[allow(unsafe_code)] - unsafe fn get_value_for_layout(self) -> String; + unsafe fn value_for_layout(self) -> String; #[allow(unsafe_code)] - unsafe fn get_size_for_layout(self) -> u32; + unsafe fn size_for_layout(self) -> u32; #[allow(unsafe_code)] - unsafe fn get_selection_for_layout(self) -> Option<Range<isize>>; + unsafe fn selection_for_layout(self) -> Option<Range<isize>>; #[allow(unsafe_code)] - unsafe fn get_checked_state_for_layout(self) -> bool; + unsafe fn checked_state_for_layout(self) -> bool; #[allow(unsafe_code)] - unsafe fn get_indeterminate_state_for_layout(self) -> bool; + unsafe fn indeterminate_state_for_layout(self) -> bool; } #[allow(unsafe_code)] @@ -226,7 +226,7 @@ unsafe fn get_raw_textinput_value(input: LayoutJS<HTMLInputElement>) -> DOMStrin impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { #[allow(unsafe_code)] - unsafe fn get_value_for_layout(self) -> String { + unsafe fn value_for_layout(self) -> String { #[allow(unsafe_code)] unsafe fn get_raw_attr_value(input: LayoutJS<HTMLInputElement>, default: &str) -> String { let elem = input.upcast::<Element>(); @@ -245,7 +245,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { InputType::InputPassword => { let text = get_raw_textinput_value(self); if !text.is_empty() { - // The implementation of get_selection_for_layout expects a 1:1 mapping of chars. + // The implementation of selection_for_layout expects a 1:1 mapping of chars. text.chars().map(|_| '●').collect() } else { String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone()) @@ -254,7 +254,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { _ => { let text = get_raw_textinput_value(self); if !text.is_empty() { - // The implementation of get_selection_for_layout expects a 1:1 mapping of chars. + // The implementation of selection_for_layout expects a 1:1 mapping of chars. String::from(text) } else { String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone()) @@ -265,19 +265,19 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_size_for_layout(self) -> u32 { + unsafe fn size_for_layout(self) -> u32 { (*self.unsafe_get()).size.get() } #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_selection_for_layout(self) -> Option<Range<isize>> { + unsafe fn selection_for_layout(self) -> Option<Range<isize>> { if !(*self.unsafe_get()).upcast::<Element>().focus_state() { return None; } // Use the raw textinput to get the index as long as we use a 1:1 char mapping - // in get_value_for_layout. + // in value_for_layout. let raw = match (*self.unsafe_get()).input_type.get() { InputType::InputText | InputType::InputPassword => get_raw_textinput_value(self), @@ -293,18 +293,37 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_checked_state_for_layout(self) -> bool { + unsafe fn checked_state_for_layout(self) -> bool { self.upcast::<Element>().get_state_for_layout().contains(IN_CHECKED_STATE) } #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_indeterminate_state_for_layout(self) -> bool { + unsafe fn indeterminate_state_for_layout(self) -> bool { self.upcast::<Element>().get_state_for_layout().contains(IN_INDETERMINATE_STATE) } } impl HTMLInputElementMethods for HTMLInputElement { + + // https://html.spec.whatwg.org/multipage/#attr-input-accept + make_getter!(Accept, "accept"); + + // https://html.spec.whatwg.org/multipage/#attr-input-accept + make_setter!(SetAccept, "accept"); + + // https://html.spec.whatwg.org/multipage/#attr-input-alt + make_getter!(Alt, "alt"); + + // https://html.spec.whatwg.org/multipage/#attr-input-alt + make_setter!(SetAlt, "alt"); + + // https://html.spec.whatwg.org/multipage/#attr-input-dirName + make_getter!(DirName, "dirname"); + + // https://html.spec.whatwg.org/multipage/#attr-input-dirName + make_setter!(SetDirName, "dirname"); + // https://html.spec.whatwg.org/multipage/#dom-fe-disabled make_bool_getter!(Disabled, "disabled"); @@ -361,7 +380,7 @@ impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#dom-input-value fn Value(&self) -> DOMString { - match self.get_value_mode() { + match self.value_mode() { ValueMode::Value => self.textinput.borrow().get_content(), ValueMode::Default => { self.upcast::<Element>() @@ -384,7 +403,7 @@ impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#dom-input-value fn SetValue(&self, value: DOMString) -> ErrorResult { - match self.get_value_mode() { + match self.value_mode() { ValueMode::Value => { self.textinput.borrow_mut().set_content(value); self.value_dirty.set(true); @@ -458,12 +477,54 @@ impl HTMLInputElementMethods for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#attr-fs-formnovalidate make_bool_setter!(SetFormNoValidate, "formnovalidate"); + // https://html.spec.whatwg.org/multipage/#attr-input-max + make_getter!(Max, "max"); + + // https://html.spec.whatwg.org/multipage/#attr-input-max + make_setter!(SetMax, "max"); + // https://html.spec.whatwg.org/multipage/#dom-input-maxlength make_int_getter!(MaxLength, "maxlength", DEFAULT_MAX_LENGTH); // https://html.spec.whatwg.org/multipage/#dom-input-maxlength make_limited_int_setter!(SetMaxLength, "maxlength", DEFAULT_MAX_LENGTH); + // https://html.spec.whatwg.org/multipage/#attr-input-min + make_getter!(Min, "min"); + + // https://html.spec.whatwg.org/multipage/#attr-input-min + make_setter!(SetMin, "min"); + + // https://html.spec.whatwg.org/multipage/#attr-input-multiple + make_bool_getter!(Multiple, "multiple"); + + // https://html.spec.whatwg.org/multipage/#attr-input-multiple + make_bool_setter!(SetMultiple, "multiple"); + + // https://html.spec.whatwg.org/multipage/#attr-input-pattern + make_getter!(Pattern, "pattern"); + + // https://html.spec.whatwg.org/multipage/#attr-input-pattern + make_setter!(SetPattern, "pattern"); + + // https://html.spec.whatwg.org/multipage/#attr-input-required + make_bool_getter!(Required, "required"); + + // https://html.spec.whatwg.org/multipage/#attr-input-required + make_bool_setter!(SetRequired, "required"); + + // https://html.spec.whatwg.org/multipage/#attr-input-src + make_getter!(Src, "src"); + + // https://html.spec.whatwg.org/multipage/#attr-input-src + make_setter!(SetSrc, "src"); + + // https://html.spec.whatwg.org/multipage/#attr-input-step + make_getter!(Step, "step"); + + // https://html.spec.whatwg.org/multipage/#attr-input-step + make_setter!(SetStep, "step"); + // https://html.spec.whatwg.org/multipage/#dom-input-indeterminate fn Indeterminate(&self) -> bool { self.upcast::<Element>().state().contains(IN_INDETERMINATE_STATE) @@ -581,7 +642,7 @@ fn in_same_group(other: &HTMLInputElement, owner: Option<&HTMLFormElement>, other.input_type.get() == InputType::InputRadio && // TODO Both a and b are in the same home subtree. other.form_owner().r() == owner && - match (other.get_radio_group_name(), group) { + match (other.radio_group_name(), group) { (Some(ref s1), Some(s2)) => compatibility_caseless_match_str(s1, s2) && s2 != &atom!(""), _ => false } @@ -596,7 +657,7 @@ impl HTMLInputElement { /// https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set /// Steps range from 3.1 to 3.7 which related to the HTMLInputElement - pub fn get_form_datum(&self, submitter: Option<FormSubmitter>) -> Option<FormDatum> { + pub fn form_datum(&self, submitter: Option<FormSubmitter>) -> Option<FormDatum> { // Step 3.2 let ty = self.type_(); // Step 3.4 @@ -632,7 +693,7 @@ impl HTMLInputElement { } // https://html.spec.whatwg.org/multipage/#radio-button-group - fn get_radio_group_name(&self) -> Option<Atom> { + fn radio_group_name(&self) -> Option<Atom> { //TODO: determine form owner self.upcast::<Element>() .get_attribute(&ns!(), &atom!("name")) @@ -648,19 +709,15 @@ impl HTMLInputElement { if self.input_type.get() == InputType::InputRadio && checked { broadcast_radio_checked(self, - self.get_radio_group_name().as_ref()); + self.radio_group_name().as_ref()); } self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); //TODO: dispatch change event } - pub fn get_indeterminate_state(&self) -> bool { - self.Indeterminate() - } - // https://html.spec.whatwg.org/multipage/#concept-fe-mutable - fn mutable(&self) -> bool { + fn is_mutable(&self) -> bool { // https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable // https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable !(self.upcast::<Element>().disabled_state() || self.ReadOnly()) @@ -740,9 +797,9 @@ impl VirtualMethods for HTMLInputElement { }; // https://html.spec.whatwg.org/multipage/#input-type-change - let (old_value_mode, old_idl_value) = (self.get_value_mode(), self.Value()); + let (old_value_mode, old_idl_value) = (self.value_mode(), self.Value()); self.input_type.set(new_type); - let new_value_mode = self.get_value_mode(); + let new_value_mode = self.value_mode(); match (&old_value_mode, old_idl_value.is_empty(), new_value_mode) { @@ -774,7 +831,7 @@ impl VirtualMethods for HTMLInputElement { // Step 5 if new_type == InputType::InputRadio { self.radio_group_updated( - self.get_radio_group_name().as_ref()); + self.radio_group_name().as_ref()); } // TODO: Step 6 - value sanitization @@ -783,7 +840,7 @@ impl VirtualMethods for HTMLInputElement { if self.input_type.get() == InputType::InputRadio { broadcast_radio_checked( self, - self.get_radio_group_name().as_ref()); + self.radio_group_name().as_ref()); } self.input_type.set(InputType::InputText); } @@ -916,7 +973,7 @@ impl Activatable for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#checkbox-state-%28type=checkbox%29:activation-behaviour-2 // https://html.spec.whatwg.org/multipage/#radio-button-state-%28type=radio%29:activation-behaviour-2 InputType::InputSubmit | InputType::InputReset - | InputType::InputCheckbox | InputType::InputRadio => self.mutable(), + | InputType::InputCheckbox | InputType::InputRadio => self.is_mutable(), _ => false } } @@ -927,7 +984,7 @@ impl Activatable for HTMLInputElement { let mut cache = self.activation_state.borrow_mut(); let ty = self.input_type.get(); cache.old_type = ty; - cache.was_mutable = self.mutable(); + cache.was_mutable = self.is_mutable(); if cache.was_mutable { match ty { // https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior @@ -952,7 +1009,7 @@ impl Activatable for HTMLInputElement { let owner = self.form_owner(); let doc = document_from_node(self); let doc_node = doc.upcast::<Node>(); - let group = self.get_radio_group_name();; + let group = self.radio_group_name();; // Safe since we only manipulate the DOM tree after finding an element let checked_member = doc_node.query_selector_iter(DOMString::from("input[type=radio]")) @@ -998,16 +1055,12 @@ impl Activatable for HTMLInputElement { InputType::InputRadio => { // We want to restore state only if the element had been changed in the first place if cache.was_mutable { - let name = self.get_radio_group_name(); match cache.checked_radio.r() { Some(o) => { // Avoiding iterating through the whole tree here, instead // we can check if the conditions for radio group siblings apply - if name == o.get_radio_group_name() && // TODO should be compatibility caseless - self.form_owner() == o.form_owner() && - // TODO Both a and b are in the same home subtree - o.input_type.get() == InputType::InputRadio { - o.SetChecked(true); + if in_same_group(&o, self.form_owner().r(), self.radio_group_name().as_ref()) { + o.SetChecked(true); } else { self.SetChecked(false); } @@ -1024,8 +1077,8 @@ impl Activatable for HTMLInputElement { // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps fn activation_behavior(&self, _event: &Event, _target: &EventTarget) { let ty = self.input_type.get(); - if self.activation_state.borrow().old_type != ty { - // Type changed, abandon ship + if self.activation_state.borrow().old_type != ty || !self.is_mutable() { + // Type changed or input is immutable, abandon ship // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27414 return; } @@ -1033,34 +1086,31 @@ impl Activatable for HTMLInputElement { InputType::InputSubmit => { // https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior // FIXME (Manishearth): support document owners (needs ability to get parent browsing context) - if self.mutable() /* and document owner is fully active */ { - self.form_owner().map(|o| { - o.submit(SubmittedFrom::NotFromFormSubmitMethod, - FormSubmitter::InputElement(self.clone())) - }); - } + // Check if document owner is fully active + self.form_owner().map(|o| { + o.submit(SubmittedFrom::NotFromFormSubmitMethod, + FormSubmitter::InputElement(self.clone())) + }); }, InputType::InputReset => { // https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior // FIXME (Manishearth): support document owners (needs ability to get parent browsing context) - if self.mutable() /* and document owner is fully active */ { - self.form_owner().map(|o| { - o.reset(ResetFrom::NotFromFormResetMethod) - }); - } + // Check if document owner is fully active + self.form_owner().map(|o| { + o.reset(ResetFrom::NotFromFormResetMethod) + }); }, InputType::InputCheckbox | InputType::InputRadio => { // https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior // https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior - if self.mutable() { - let target = self.upcast::<EventTarget>(); - target.fire_event("input", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - target.fire_event("change", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - } + // Check if document owner is fully active + let target = self.upcast::<EventTarget>(); + target.fire_event("input", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); + target.fire_event("change", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); }, _ => () } diff --git a/components/script/dom/mimetype.rs b/components/script/dom/mimetype.rs new file mode 100644 index 00000000000..f29b40faa5a --- /dev/null +++ b/components/script/dom/mimetype.rs @@ -0,0 +1,36 @@ +/* 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::MimeTypeBinding::MimeTypeMethods; +use dom::bindings::js::Root; +use dom::bindings::reflector::{Reflector}; +use dom::plugin::Plugin; +use util::str::DOMString; + +#[dom_struct] +pub struct MimeType { + reflector_: Reflector, +} + +impl MimeTypeMethods for MimeType { + // https://html.spec.whatwg.org/multipage/#dom-mimetype-type + fn Type(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetype-description + fn Description(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetype-suffixes + fn Suffixes(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetype-enabledplugin + fn EnabledPlugin(&self) -> Root<Plugin> { + unreachable!() + } +} diff --git a/components/script/dom/mimetypearray.rs b/components/script/dom/mimetypearray.rs new file mode 100644 index 00000000000..ae11341e77b --- /dev/null +++ b/components/script/dom/mimetypearray.rs @@ -0,0 +1,62 @@ +/* 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::MimeTypeArrayBinding; +use dom::bindings::codegen::Bindings::MimeTypeArrayBinding::MimeTypeArrayMethods; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::Root; +use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::mimetype::MimeType; +use util::str::DOMString; + +#[dom_struct] +pub struct MimeTypeArray { + reflector_: Reflector, +} + +impl MimeTypeArray { + pub fn new_inherited() -> MimeTypeArray { + MimeTypeArray { + reflector_: Reflector::new() + } + } + + pub fn new(global: GlobalRef) -> Root<MimeTypeArray> { + reflect_dom_object(box MimeTypeArray::new_inherited(), + global, + MimeTypeArrayBinding::Wrap) + } +} + +impl MimeTypeArrayMethods for MimeTypeArray { + // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-length + fn Length(&self) -> u32 { + 0 + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-item + fn Item(&self, _index: u32) -> Option<Root<MimeType>> { + None + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-nameditem + fn NamedItem(&self, _name: DOMString) -> Option<Root<MimeType>> { + None + } + + // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-item + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<MimeType>> { + None + } + + // check-tidy: no specs after this line + fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<MimeType>> { + None + } + + // https://heycam.github.io/webidl/#dfn-supported-property-names + fn SupportedPropertyNames(&self) -> Vec<DOMString> { + vec![] + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 36921d8be89..853ac520b9a 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -342,6 +342,8 @@ pub mod imagedata; pub mod keyboardevent; pub mod location; pub mod messageevent; +pub mod mimetype; +pub mod mimetypearray; pub mod mouseevent; pub mod namednodemap; pub mod navigator; @@ -351,6 +353,8 @@ pub mod nodeiterator; pub mod nodelist; pub mod performance; pub mod performancetiming; +pub mod plugin; +pub mod pluginarray; pub mod processinginstruction; pub mod progressevent; pub mod radionodelist; diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index fe01105b787..c1874905a54 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -8,7 +8,9 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::{Reflector, Reflectable, reflect_dom_object}; use dom::bluetooth::Bluetooth; +use dom::mimetypearray::MimeTypeArray; use dom::navigatorinfo; +use dom::pluginarray::PluginArray; use dom::window::Window; use util::str::DOMString; @@ -16,6 +18,8 @@ use util::str::DOMString; pub struct Navigator { reflector_: Reflector, bluetooth: MutNullableHeap<JS<Bluetooth>>, + plugins: MutNullableHeap<JS<PluginArray>>, + mime_types: MutNullableHeap<JS<MimeTypeArray>>, } impl Navigator { @@ -23,6 +27,8 @@ impl Navigator { Navigator { reflector_: Reflector::new(), bluetooth: Default::default(), + plugins: Default::default(), + mime_types: Default::default(), } } @@ -78,4 +84,19 @@ impl NavigatorMethods for Navigator { fn Language(&self) -> DOMString { navigatorinfo::Language() } + + // https://html.spec.whatwg.org/multipage/#dom-navigator-plugins + fn Plugins(&self) -> Root<PluginArray> { + self.plugins.or_init(|| PluginArray::new(self.global().r())) + } + + // https://html.spec.whatwg.org/multipage/#dom-navigator-mimetypes + fn MimeTypes(&self) -> Root<MimeTypeArray> { + self.mime_types.or_init(|| MimeTypeArray::new(self.global().r())) + } + + // https://html.spec.whatwg.org/multipage/#dom-navigator-javaenabled + fn JavaEnabled(&self) -> bool { + false + } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 748b7b8249e..1e71966e4e7 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -594,12 +594,8 @@ impl Node { let html_element = document.GetDocumentElement(); - let is_body_element = html_element.r().and_then(|root| { - let node = root.upcast::<Node>(); - node.children().find(|child| { child.is::<HTMLBodyElement>() }).map(|node| { - *node.r() == *self - }) - }).unwrap_or(false); + let is_body_element = self.downcast::<HTMLBodyElement>() + .map_or(false, |e| e.is_the_html_body_element()); let scroll_area = window.scroll_area_query(self.to_trusted_node_address()); diff --git a/components/script/dom/plugin.rs b/components/script/dom/plugin.rs new file mode 100644 index 00000000000..0836bc32f0f --- /dev/null +++ b/components/script/dom/plugin.rs @@ -0,0 +1,61 @@ +/* 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::PluginBinding::PluginMethods; +use dom::bindings::js::Root; +use dom::bindings::reflector::{Reflector}; +use dom::mimetype::MimeType; +use util::str::DOMString; + +#[dom_struct] +pub struct Plugin { + reflector_: Reflector, +} + +impl PluginMethods for Plugin { + // https://html.spec.whatwg.org/multipage/#dom-plugin-name + fn Name(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-description + fn Description(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-filename + fn Filename(&self) -> DOMString { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-length + fn Length(&self) -> u32 { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-item + fn Item(&self, _index: u32) -> Option<Root<MimeType>> { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-nameditem + fn NamedItem(&self, _name: DOMString) -> Option<Root<MimeType>> { + unreachable!() + } + + // https://html.spec.whatwg.org/multipage/#dom-plugin-item + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<MimeType>> { + unreachable!() + } + + // check-tidy: no specs after this line + fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<MimeType>> { + unreachable!() + } + + // https://heycam.github.io/webidl/#dfn-supported-property-names + fn SupportedPropertyNames(&self) -> Vec<DOMString> { + unreachable!() + } +} diff --git a/components/script/dom/pluginarray.rs b/components/script/dom/pluginarray.rs new file mode 100644 index 00000000000..d94131b1a9f --- /dev/null +++ b/components/script/dom/pluginarray.rs @@ -0,0 +1,67 @@ +/* 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::PluginArrayBinding; +use dom::bindings::codegen::Bindings::PluginArrayBinding::PluginArrayMethods; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::Root; +use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::plugin::Plugin; +use util::str::DOMString; + +#[dom_struct] +pub struct PluginArray { + reflector_: Reflector, +} + +impl PluginArray { + pub fn new_inherited() -> PluginArray { + PluginArray { + reflector_: Reflector::new() + } + } + + pub fn new(global: GlobalRef) -> Root<PluginArray> { + reflect_dom_object(box PluginArray::new_inherited(), + global, + PluginArrayBinding::Wrap) + } +} + +impl PluginArrayMethods for PluginArray { + // https://html.spec.whatwg.org/multipage/#dom-pluginarray-refresh + fn Refresh(&self, _reload: bool) { + + } + + // https://html.spec.whatwg.org/multipage/#dom-pluginarray-length + fn Length(&self) -> u32 { + 0 + } + + // https://html.spec.whatwg.org/multipage/#dom-pluginarray-item + fn Item(&self, _index: u32) -> Option<Root<Plugin>> { + None + } + + // https://html.spec.whatwg.org/multipage/#dom-pluginarray-nameditem + fn NamedItem(&self, _name: DOMString) -> Option<Root<Plugin>> { + None + } + + // https://html.spec.whatwg.org/multipage/#dom-pluginarray-item + fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Root<Plugin>> { + None + } + + // check-tidy: no specs after this line + fn NamedGetter(&self, _name: DOMString, _found: &mut bool) -> Option<Root<Plugin>> { + None + } + + // https://heycam.github.io/webidl/#dfn-supported-property-names + fn SupportedPropertyNames(&self) -> Vec<DOMString> { + vec![] + } +} diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 996e6eb4cee..d288e9422c4 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -167,6 +167,17 @@ impl WebGLProgram { WebGLActiveInfo::new(self.global().r(), size, ty, DOMString::from(name))) } + /// glGetActiveAttrib + pub fn get_active_attrib(&self, index: u32) -> WebGLResult<Root<WebGLActiveInfo>> { + let (sender, receiver) = ipc::channel().unwrap(); + self.renderer + .send(CanvasMsg::WebGL(WebGLCommand::GetActiveAttrib(self.id, index, sender))) + .unwrap(); + + receiver.recv().unwrap().map(|(size, ty, name)| + WebGLActiveInfo::new(self.global().r(), size, ty, DOMString::from(name))) + } + /// glGetAttribLocation pub fn get_attrib_location(&self, name: DOMString) -> WebGLResult<Option<i32>> { if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN { diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 920fd91bbad..4c6996cbb90 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -31,7 +31,7 @@ use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; -use offscreen_gl_context::GLContextAttributes; +use offscreen_gl_context::{GLContextAttributes, GLLimits}; use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; use util::str::DOMString; @@ -71,6 +71,8 @@ pub struct WebGLRenderingContext { reflector_: Reflector, #[ignore_heap_size_of = "Defined in ipc-channel"] ipc_renderer: IpcSender<CanvasMsg>, + #[ignore_heap_size_of = "Defined in offscreen_gl_context"] + limits: GLLimits, canvas: JS<HTMLCanvasElement>, #[ignore_heap_size_of = "Defined in webrender_traits"] last_error: Cell<Option<WebGLError>>, @@ -95,10 +97,11 @@ impl WebGLRenderingContext { .unwrap(); let result = receiver.recv().unwrap(); - result.map(|ipc_renderer| { + result.map(|(ipc_renderer, context_limits)| { WebGLRenderingContext { reflector_: Reflector::new(), ipc_renderer: ipc_renderer, + limits: context_limits, canvas: JS::from_ref(canvas), last_error: Cell::new(None), texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE), @@ -139,6 +142,9 @@ impl WebGLRenderingContext { } pub fn webgl_error(&self, err: WebGLError) { + // TODO(emilio): Add useful debug messages to this + warn!("WebGL error: {:?}, previous error was {:?}", err, self.last_error.get()); + // If an error has been detected no further errors must be // recorded until `getError` has been called if self.last_error.get().is_none() { @@ -155,7 +161,7 @@ impl WebGLRenderingContext { if let Some(texture) = texture { handle_potential_webgl_error!(self, texture.tex_parameter(target, name, value)); } else { - return self.webgl_error(InvalidOperation); + self.webgl_error(InvalidOperation) } } @@ -164,6 +170,10 @@ impl WebGLRenderingContext { } fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) { + if indx > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w))) .unwrap(); @@ -680,6 +690,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn CreateShader(&self, shader_type: u32) -> Option<Root<WebGLShader>> { + match shader_type { + constants::VERTEX_SHADER | constants::FRAGMENT_SHADER => {}, + _ => { + self.webgl_error(InvalidEnum); + return None; + } + } WebGLShader::maybe_new(self.global().r(), self.ipc_renderer.clone(), shader_type) } @@ -737,13 +754,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } if first < 0 || count < 0 { - self.webgl_error(InvalidValue); - } else { - self.ipc_renderer - .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count))) - .unwrap(); - self.mark_as_dirty(); + return self.webgl_error(InvalidValue); } + + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count))) + .unwrap(); + self.mark_as_dirty(); }, _ => self.webgl_error(InvalidEnum), } @@ -790,6 +807,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn EnableVertexAttribArray(&self, attrib_id: u32) { + if attrib_id > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::EnableVertexAttribArray(attrib_id))) .unwrap() @@ -807,6 +828,17 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 + fn GetActiveAttrib(&self, program: Option<&WebGLProgram>, index: u32) -> Option<Root<WebGLActiveInfo>> { + program.and_then(|p| match p.get_active_attrib(index) { + Ok(ret) => Some(ret), + Err(error) => { + self.webgl_error(error); + None + }, + }) + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetAttribLocation(&self, program: Option<&WebGLProgram>, name: DOMString) -> i32 { if let Some(program) = program { handle_potential_webgl_error!(self, program.get_attrib_location(name), None).unwrap_or(-1) @@ -1188,7 +1220,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.vertex_attrib(indx, x, 0f32, 0f32, 1f32) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { @@ -1206,7 +1237,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.vertex_attrib(indx, x, y, 0f32, 1f32) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) { if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) { @@ -1257,6 +1287,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn VertexAttribPointer(&self, attrib_id: u32, size: i32, data_type: u32, normalized: bool, stride: i32, offset: i64) { + if attrib_id > self.limits.max_vertex_attribs { + return self.webgl_error(InvalidValue); + } + if let constants::FLOAT = data_type { let msg = CanvasMsg::WebGL( WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32)); diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index 804dc3cdcf8..495417065d7 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -101,6 +101,7 @@ impl WebGLShader { &BuiltInResources::default()).unwrap(); match validator.compile_and_translate(&[source]) { Ok(translated_source) => { + debug!("Shader translated: {}", translated_source); // NOTE: At this point we should be pretty sure that the compilation in the paint thread // will succeed. // It could be interesting to retrieve the info log from the paint thread though diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index dba69a515b0..10cf77ccc83 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -310,4 +310,5 @@ partial interface CSSStyleDeclaration { [SetterThrows, TreatNullAs=EmptyString] attribute DOMString flexDirection; [SetterThrows, TreatNullAs=EmptyString] attribute DOMString flex-direction; + [SetterThrows, TreatNullAs=EmptyString] attribute DOMString order; }; diff --git a/components/script/dom/webidls/HTMLHRElement.webidl b/components/script/dom/webidls/HTMLHRElement.webidl index f203527b2bf..e3ba6113748 100644 --- a/components/script/dom/webidls/HTMLHRElement.webidl +++ b/components/script/dom/webidls/HTMLHRElement.webidl @@ -10,7 +10,7 @@ interface HTMLHRElement : HTMLElement { // https://html.spec.whatwg.org/multipage/#HTMLHRElement-partial partial interface HTMLHRElement { - // attribute DOMString align; + attribute DOMString align; attribute DOMString color; // attribute boolean noShade; // attribute DOMString size; diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl index 2e1c6215f2b..66907c5cd23 100644 --- a/components/script/dom/webidls/HTMLInputElement.webidl +++ b/components/script/dom/webidls/HTMLInputElement.webidl @@ -5,13 +5,13 @@ // https://html.spec.whatwg.org/multipage/#htmlinputelement interface HTMLInputElement : HTMLElement { - // attribute DOMString accept; - // attribute DOMString alt; + attribute DOMString accept; + attribute DOMString alt; // attribute DOMString autocomplete; // attribute boolean autofocus; attribute boolean defaultChecked; attribute boolean checked; - // attribute DOMString dirName; + attribute DOMString dirName; attribute boolean disabled; readonly attribute HTMLFormElement? form; //readonly attribute FileList? files; @@ -24,21 +24,21 @@ interface HTMLInputElement : HTMLElement { attribute boolean indeterminate; // attribute DOMString inputMode; //readonly attribute HTMLElement? list; - // attribute DOMString max; + attribute DOMString max; [SetterThrows] attribute long maxLength; - // attribute DOMString min; + attribute DOMString min; // attribute long minLength; - // attribute boolean multiple; + attribute boolean multiple; attribute DOMString name; - // attribute DOMString pattern; + attribute DOMString pattern; attribute DOMString placeholder; attribute boolean readOnly; - // attribute boolean required; + attribute boolean required; [SetterThrows] attribute unsigned long size; - // attribute DOMString src; - // attribute DOMString step; + attribute DOMString src; + attribute DOMString step; attribute DOMString type; attribute DOMString defaultValue; [TreatNullAs=EmptyString, SetterThrows] diff --git a/components/script/dom/webidls/MimeType.webidl b/components/script/dom/webidls/MimeType.webidl new file mode 100644 index 00000000000..9972134f7c8 --- /dev/null +++ b/components/script/dom/webidls/MimeType.webidl @@ -0,0 +1,12 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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://html.spec.whatwg.org/multipage/#mimetype +interface MimeType { + readonly attribute DOMString type; + readonly attribute DOMString description; + readonly attribute DOMString suffixes; // comma-separated + readonly attribute Plugin enabledPlugin; +}; diff --git a/components/script/dom/webidls/MimeTypeArray.webidl b/components/script/dom/webidls/MimeTypeArray.webidl new file mode 100644 index 00000000000..6a4d8f1aa4e --- /dev/null +++ b/components/script/dom/webidls/MimeTypeArray.webidl @@ -0,0 +1,12 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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://html.spec.whatwg.org/multipage/#mimetypearray +[LegacyUnenumerableNamedProperties] +interface MimeTypeArray { + readonly attribute unsigned long length; + getter MimeType? item(unsigned long index); + getter MimeType? namedItem(DOMString name); +}; diff --git a/components/script/dom/webidls/Navigator.webidl b/components/script/dom/webidls/Navigator.webidl index 50f695279ff..b793af7a6f5 100644 --- a/components/script/dom/webidls/Navigator.webidl +++ b/components/script/dom/webidls/Navigator.webidl @@ -13,7 +13,7 @@ Navigator implements NavigatorLanguage; //Navigator implements NavigatorOnLine; //Navigator implements NavigatorContentUtils; //Navigator implements NavigatorStorageUtils; -//Navigator implements NavigatorPlugins; +Navigator implements NavigatorPlugins; // https://html.spec.whatwg.org/multipage/#navigatorid [NoInterfaceObject/*, Exposed=Window,Worker*/] @@ -39,3 +39,11 @@ interface NavigatorLanguage { // https://github.com/servo/servo/issues/10073 //readonly attribute DOMString[] languages; }; + +// https://html.spec.whatwg.org/multipage/#navigatorplugins +[NoInterfaceObject] +interface NavigatorPlugins { + [SameObject] readonly attribute PluginArray plugins; + [SameObject] readonly attribute MimeTypeArray mimeTypes; + boolean javaEnabled(); +}; diff --git a/components/script/dom/webidls/Plugin.webidl b/components/script/dom/webidls/Plugin.webidl new file mode 100644 index 00000000000..4fb172d45b9 --- /dev/null +++ b/components/script/dom/webidls/Plugin.webidl @@ -0,0 +1,15 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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://html.spec.whatwg.org/multipage/#dom-plugin +[LegacyUnenumerableNamedProperties] +interface Plugin { + readonly attribute DOMString name; + readonly attribute DOMString description; + readonly attribute DOMString filename; + readonly attribute unsigned long length; + getter MimeType? item(unsigned long index); + getter MimeType? namedItem(DOMString name); +}; diff --git a/components/script/dom/webidls/PluginArray.webidl b/components/script/dom/webidls/PluginArray.webidl new file mode 100644 index 00000000000..f2fde35fc4f --- /dev/null +++ b/components/script/dom/webidls/PluginArray.webidl @@ -0,0 +1,13 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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://html.spec.whatwg.org/multipage/#pluginarray +[LegacyUnenumerableNamedProperties] +interface PluginArray { + void refresh(optional boolean reload = false); + readonly attribute unsigned long length; + getter Plugin? item(unsigned long index); + getter Plugin? namedItem(DOMString name); +}; diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 7be7a82d41e..d2c93d9a3c5 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -567,7 +567,7 @@ interface WebGLRenderingContextBase void generateMipmap(GLenum target); - //WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index); + WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index); WebGLActiveInfo? getActiveUniform(WebGLProgram? program, GLuint index); //sequence<WebGLShader>? getAttachedShaders(WebGLProgram? program); diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index ab8f8f96413..1d7c2bffd34 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -350,7 +350,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { } // Step 2 - let base = self.global().r().get_url(); + let base = self.global().r().api_base_url(); // Step 6 let mut parsed_url = match base.join(&url.0) { Ok(parsed) => parsed, diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index 509a7e93e71..6147fc8bd2b 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -13,6 +13,8 @@ use js::glue::CollectServoSizes; use js::jsapi::{DisableIncrementalGC, GCDescription, GCProgress}; use js::jsapi::{JSContext, JS_GetRuntime, JSRuntime, JSTracer, SetDOMCallbacks, SetGCSliceCallback}; use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback}; +use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption}; +use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled}; use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback}; use js::rust::Runtime; use libc; @@ -130,6 +132,181 @@ pub fn new_rt_and_cx() -> Runtime { if let Some(val) = get_pref("js.ion.enabled").as_boolean() { rt_opts.set_ion_(val); } + if let Some(val) = get_pref("js.asmjs.enabled").as_boolean() { + rt_opts.set_asmJS_(val); + } + if let Some(val) = get_pref("js.strict.enabled").as_boolean() { + rt_opts.set_extraWarnings_(val); + } + // TODO: handle js.strict.debug.enabled + // TODO: handle js.throw_on_asmjs_validation_failure (needs new Spidermonkey) + if let Some(val) = get_pref("js.native_regexp.enabled").as_boolean() { + rt_opts.set_nativeRegExp_(val); + } + if let Some(val) = get_pref("js.parallel_parsing.enabled").as_boolean() { + unsafe { JS_SetParallelParsingEnabled(runtime.rt(), val); } + } + if let Some(val) = get_pref("js.offthread_compilation_enabled").as_boolean() { + unsafe { JS_SetOffthreadIonCompilationEnabled(runtime.rt(), val); } + } + if let Some(val) = get_pref("js.baseline.unsafe_eager_compilation.enabled").as_boolean() { + let trigger: i32 = if val { + 0 + } else { + -1 + }; + unsafe { + JS_SetGlobalJitCompilerOption(runtime.rt(), + JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER, + trigger as u32); + } + } + if let Some(val) = get_pref("js.ion.unsafe_eager_compilation.enabled").as_boolean() { + let trigger: i64 = if val { + 0 + } else { + -1 + }; + unsafe { + JS_SetGlobalJitCompilerOption(runtime.rt(), + JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER, + trigger as u32); + } + } + // TODO: handle js.discard_system_source.enabled + // TODO: handle js.asyncstack.enabled (needs new Spidermonkey) + // TODO: handle js.throw_on_debugee_would_run (needs new Spidermonkey) + // TODO: handle js.dump_stack_on_debugee_would_run (needs new Spidermonkey) + if let Some(val) = get_pref("js.werror.enabled").as_boolean() { + rt_opts.set_werror_(val); + } + // TODO: handle js.shared_memory.enabled + if let Some(val) = get_pref("js.mem.high_water_mark").as_i64() { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_MALLOC_BYTES, val as u32 * 1024 * 1024); + } + } + if let Some(val) = get_pref("js.mem.max").as_i64() { + let max = if val <= 0 || val >= 0x1000 { + -1 + } else { + val * 1024 * 1024 + }; + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_BYTES, max as u32); + } + } + // NOTE: This is disabled above, so enabling it here will do nothing for now. + if let Some(val) = get_pref("js.mem.gc.incremental.enabled").as_boolean() { + let compartment = if let Some(val) = get_pref("js.mem.gc.per_compartment.enabled").as_boolean() { + val + } else { + false + }; + let mode = if val { + JSGCMode::JSGC_MODE_INCREMENTAL + } else if compartment { + JSGCMode::JSGC_MODE_COMPARTMENT + } else { + JSGCMode::JSGC_MODE_GLOBAL + }; + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MODE, mode as u32); + } + } + if let Some(val) = get_pref("js.mem.gc.incremental.slice_ms").as_i64() { + if val >= 0 && val < 100000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_SLICE_TIME_BUDGET, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.compacting.enabled").as_boolean() { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_COMPACTING_ENABLED, val as u32); + } + } + if let Some(val) = get_pref("js.mem.gc.high_frequency_time_limit_ms").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.dynamic_mark_slice.enabled").as_boolean() { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_MARK_SLICE, val as u32); + } + } + // TODO: handle js.mem.gc.refresh_frame_slices.enabled + if let Some(val) = get_pref("js.mem.gc.dynamic_heap_growth.enabled").as_boolean() { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_HEAP_GROWTH, val as u32); + } + } + if let Some(val) = get_pref("js.mem.gc.low_frequency_heap_growth").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_min").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_max").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.high_frequency_low_limit_mb").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_LOW_LIMIT, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.high_frequency_high_limit_mb").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HIGH_LIMIT, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.allocation_threshold_mb").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_ALLOCATION_THRESHOLD, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.decommit_threshold_mb").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DECOMMIT_THRESHOLD, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_min").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32); + } + } + } + if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_max").as_i64() { + if val >= 0 && val < 10000 { + unsafe { + JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32); + } + } + } runtime } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index b9027c96390..7cb24e110bc 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -52,7 +52,8 @@ use hyper::mime::{Mime, SubLevel, TopLevel}; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::jsapi::{DOMProxyShadowsResult, HandleId, HandleObject, RootedValue}; -use js::jsapi::{JSAutoRequest, JSContext, JS_SetWrapObjectCallbacks, JSTracer}; +use js::jsapi::{JSAutoRequest, JS_SetWrapObjectCallbacks}; +use js::jsapi::{JSContext, JSTracer}; use js::jsval::UndefinedValue; use js::rust::Runtime; use layout_interface::{ReflowQueryType}; |