aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py15
-rw-r--r--components/script/dom/event.rs5
-rw-r--r--components/script/dom/htmlimageelement.rs25
-rw-r--r--components/script/dom/htmlscriptelement.rs279
-rw-r--r--components/script/dom/performance.rs40
-rw-r--r--components/script/dom/webglrenderingcontext.rs4
-rw-r--r--components/script/dom/webidls/Event.webidl1
-rw-r--r--components/script/dom/webidls/Performance.webidl4
-rw-r--r--components/script/dom/webidls/PerformanceEntry.webidl3
-rw-r--r--components/script/dom/webidls/PerformanceNavigation.webidl2
-rw-r--r--components/script/dom/webidls/PerformanceNavigationTiming.webidl2
-rw-r--r--components/script/dom/webidls/PerformanceResourceTiming.webidl2
-rw-r--r--components/script/dom/window.rs21
-rw-r--r--components/script/dom/xrwebgllayer.rs64
14 files changed, 289 insertions, 178 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 4a8cc573416..dece9a763d9 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -492,7 +492,7 @@ class CGMethodCall(CGThing):
else:
# Just throw; we have no idea what we're supposed to
# do with this.
- caseBody.append(CGGeneric("throw_internal_error(*cx, \"Could not convert JavaScript argument\");\n"
+ caseBody.append(CGGeneric("throw_type_error(*cx, \"Could not convert JavaScript argument\");\n"
"return false;"))
argCountCases.append(CGCase(str(argCount),
@@ -2049,9 +2049,10 @@ class CGImports(CGWrapper):
if name != 'GlobalScope':
extras += [descriptor.path]
parentName = descriptor.getParentName()
- if parentName:
+ while parentName:
descriptor = descriptorProvider.getDescriptor(parentName)
extras += [descriptor.path, descriptor.bindingPath]
+ parentName = descriptor.getParentName()
elif t.isType() and t.isRecord():
extras += ['crate::dom::bindings::mozmap::MozMap']
elif isinstance(t, IDLPromiseType):
@@ -3662,6 +3663,7 @@ class CGDefaultToJSONMethod(CGSpecializedMethod):
def definition_body(self):
ret = dedent("""
+ use crate::dom::bindings::inheritance::HasParent;
rooted!(in(*cx) let result = JS_NewPlainObject(*cx));
if result.is_null() {
return false;
@@ -3676,16 +3678,19 @@ class CGDefaultToJSONMethod(CGSpecializedMethod):
jsonDescriptors.append(descriptor)
interface = interface.parent
+ parents = len(jsonDescriptors) - 1
form = """
- if !${parentclass}CollectJSONAttributes(cx, _obj, this, &result) {
+ if !${parentclass}CollectJSONAttributes(cx, _obj, this${asparent}, &result) {
return false;
}
"""
# Iterate the array in reverse: oldest ancestor first
for descriptor in jsonDescriptors[:0:-1]:
- ret += fill(form, parentclass=toBindingNamespace(descriptor.name) + "::")
- ret += fill(form, parentclass="")
+ ret += fill(form, parentclass=toBindingNamespace(descriptor.name) + "::",
+ asparent=".as_ref().unwrap()" + ".as_parent()" * parents)
+ parents -= 1
+ ret += fill(form, parentclass="", asparent="")
ret += ('(*args).rval().set(ObjectValue(*result));\n'
'return true;\n')
return CGGeneric(ret)
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index a14beccabe3..52c9af3b061 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -263,6 +263,11 @@ impl EventMethods for Event {
self.target.get()
}
+ // https://dom.spec.whatwg.org/#dom-event-srcelement
+ fn GetSrcElement(&self) -> Option<DomRoot<EventTarget>> {
+ self.target.get()
+ }
+
// https://dom.spec.whatwg.org/#dom-event-currenttarget
fn GetCurrentTarget(&self) -> Option<DomRoot<EventTarget>> {
self.current_target.get()
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index 4a9a94dccde..505b649e50c 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -22,7 +22,7 @@ use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::document::Document;
use crate::dom::element::{reflect_cross_origin_attribute, set_cross_origin_attribute};
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
-use crate::dom::event::{Event, EventBubbles, EventCancelable};
+use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlareaelement::HTMLAreaElement;
@@ -37,7 +37,6 @@ use crate::dom::node::{
document_from_node, window_from_node, BindContext, Node, NodeDamage, ShadowIncluding,
};
use crate::dom::performanceresourcetiming::InitiatorType;
-use crate::dom::progressevent::ProgressEvent;
use crate::dom::values::UNSIGNED_LONG_MAX;
use crate::dom::virtualmethods::VirtualMethods;
use crate::dom::window::Window;
@@ -809,26 +808,7 @@ impl HTMLImageElement {
return;
},
};
- // Step 10.
- let target = Trusted::new(self.upcast::<EventTarget>());
- // FIXME(nox): Why are errors silenced here?
- let _ = task_source.queue(
- task!(fire_progress_event: move || {
- let target = target.root();
-
- let event = ProgressEvent::new(
- &target.global(),
- atom!("loadstart"),
- EventBubbles::DoesNotBubble,
- EventCancelable::NotCancelable,
- false,
- 0,
- 0,
- );
- event.upcast::<Event>().fire(&target);
- }),
- window.upcast(),
- );
+
// Step 11
let base_url = document.base_url();
let parsed_url = base_url.join(&src.0);
@@ -850,7 +830,6 @@ impl HTMLImageElement {
current_request.source_url = Some(USVString(src))
}
this.upcast::<EventTarget>().fire_event(atom!("error"));
- this.upcast::<EventTarget>().fire_event(atom!("loadend"));
// FIXME(nox): According to the spec, setting the current
// request to the broken state is done prior to queuing a
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index dbfda59db02..7c9e3ebd42d 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -125,35 +125,44 @@ static SCRIPT_JS_MIMES: StaticStringVec = &[
"text/x-javascript",
];
+#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
+pub enum ScriptType {
+ Classic,
+ Module,
+}
+
#[derive(JSTraceable, MallocSizeOf)]
-pub struct ClassicScript {
+pub struct ScriptOrigin {
text: DOMString,
url: ServoUrl,
external: bool,
+ type_: ScriptType,
}
-impl ClassicScript {
- fn internal(text: DOMString, url: ServoUrl) -> ClassicScript {
- ClassicScript {
+impl ScriptOrigin {
+ fn internal(text: DOMString, url: ServoUrl, type_: ScriptType) -> ScriptOrigin {
+ ScriptOrigin {
text: text,
url: url,
external: false,
+ type_,
}
}
- fn external(text: DOMString, url: ServoUrl) -> ClassicScript {
- ClassicScript {
+ fn external(text: DOMString, url: ServoUrl, type_: ScriptType) -> ScriptOrigin {
+ ScriptOrigin {
text: text,
url: url,
external: true,
+ type_,
}
}
}
-pub type ScriptResult = Result<ClassicScript, NetworkError>;
+pub type ScriptResult = Result<ScriptOrigin, NetworkError>;
/// The context required for asynchronously loading an external script source.
-struct ScriptContext {
+struct ClassicContext {
/// The element that initiated the request.
elem: Trusted<HTMLScriptElement>,
/// The kind of external script.
@@ -173,7 +182,7 @@ struct ScriptContext {
resource_timing: ResourceFetchTiming,
}
-impl FetchResponseListener for ScriptContext {
+impl FetchResponseListener for ClassicContext {
fn process_request_body(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here?
fn process_request_eof(&mut self) {} // TODO(KiChjang): Perhaps add custom steps to perform fetch here?
@@ -226,7 +235,11 @@ impl FetchResponseListener for ScriptContext {
// Step 7.
let (source_text, _, _) = encoding.decode(&self.data);
- ClassicScript::external(DOMString::from(source_text), metadata.final_url)
+ ScriptOrigin::external(
+ DOMString::from(source_text),
+ metadata.final_url,
+ ScriptType::Classic,
+ )
});
// Step 9.
@@ -260,7 +273,7 @@ impl FetchResponseListener for ScriptContext {
}
}
-impl ResourceTimingListener for ScriptContext {
+impl ResourceTimingListener for ClassicContext {
fn resource_timing_information(&self) -> (InitiatorType, ServoUrl) {
let initiator_type = InitiatorType::LocalName(
self.elem
@@ -277,7 +290,7 @@ impl ResourceTimingListener for ScriptContext {
}
}
-impl PreInvoke for ScriptContext {}
+impl PreInvoke for ClassicContext {}
/// <https://html.spec.whatwg.org/multipage/#fetch-a-classic-script>
fn fetch_a_classic_script(
@@ -313,7 +326,7 @@ fn fetch_a_classic_script(
// TODO: Step 3, Add custom steps to perform fetch
- let context = Arc::new(Mutex::new(ScriptContext {
+ let context = Arc::new(Mutex::new(ClassicContext {
elem: Trusted::new(script),
kind: kind,
character_encoding: character_encoding,
@@ -364,47 +377,49 @@ impl HTMLScriptElement {
self.non_blocking.set(true);
}
- // Step 4.
+ // Step 4-5.
let text = self.Text();
if text.is_empty() && !element.has_attribute(&local_name!("src")) {
return;
}
- // Step 5.
+ // Step 6.
if !self.upcast::<Node>().is_connected() {
return;
}
- // Step 6.
- if !self.is_javascript() {
+ let script_type = if let Some(ty) = self.get_script_type() {
+ ty
+ } else {
+ // Step 7.
return;
- }
+ };
- // Step 7.
+ // Step 8.
if was_parser_inserted {
self.parser_inserted.set(true);
self.non_blocking.set(false);
}
- // Step 8.
+ // Step 9.
self.already_started.set(true);
- // Step 9.
+ // Step 10.
let doc = document_from_node(self);
if self.parser_inserted.get() && &*self.parser_document != &*doc {
return;
}
- // Step 10.
+ // Step 11.
if !doc.is_scripting_enabled() {
return;
}
- // TODO: Step 11: nomodule content attribute
+ // TODO: Step 12: nomodule content attribute
- // TODO(#4577): Step 12: CSP.
+ // TODO(#4577): Step 13: CSP.
- // Step 13.
+ // Step 14.
let for_attribute = element.get_attribute(&ns!(), &local_name!("for"));
let event_attribute = element.get_attribute(&ns!(), &local_name!("event"));
match (for_attribute, event_attribute) {
@@ -424,20 +439,20 @@ impl HTMLScriptElement {
(_, _) => (),
}
- // Step 14.
+ // Step 15.
let encoding = element
.get_attribute(&ns!(), &local_name!("charset"))
.and_then(|charset| Encoding::for_label(charset.value().as_bytes()))
.unwrap_or_else(|| doc.encoding());
- // Step 15.
+ // Step 16.
let cors_setting = cors_setting_for_element(element);
- // TODO: Step 16: Module script credentials mode.
+ // TODO: Step 17: Module script credentials mode.
- // TODO: Step 17: Nonce.
+ // TODO: Step 18: Nonce.
- // Step 18: Integrity metadata.
+ // Step 19: Integrity metadata.
let im_attribute = element.get_attribute(&ns!(), &local_name!("integrity"));
let integrity_val = im_attribute.as_ref().map(|a| a.value());
let integrity_metadata = match integrity_val {
@@ -445,26 +460,30 @@ impl HTMLScriptElement {
None => "",
};
- // TODO: Step 19: parser state.
+ // TODO: Step 20: referrer policy
+
+ // TODO: Step 21: parser state.
+
+ // TODO: Step 22: Fetch options
- // TODO: Step 20: environment settings object.
+ // TODO: Step 23: environment settings object.
let base_url = doc.base_url();
if let Some(src) = element.get_attribute(&ns!(), &local_name!("src")) {
- // Step 21.
+ // Step 24.
- // Step 21.1.
+ // Step 24.1.
let src = src.value();
- // Step 21.2.
+ // Step 24.2.
if src.is_empty() {
self.queue_error_event();
return;
}
- // Step 21.3: The "from an external file"" flag is stored in ClassicScript.
+ // Step 24.3: The "from an external file"" flag is stored in ScriptOrigin.
- // Step 21.4-21.5.
+ // Step 24.4-24.5.
let url = match base_url.join(&src) {
Ok(url) => url,
Err(_) => {
@@ -474,64 +493,89 @@ impl HTMLScriptElement {
},
};
- // Preparation for step 23.
- let kind = if element.has_attribute(&local_name!("defer")) &&
- was_parser_inserted &&
- !r#async
- {
- // Step 23.a: classic, has src, has defer, was parser-inserted, is not async.
- ExternalScriptKind::Deferred
- } else if was_parser_inserted && !r#async {
- // Step 23.c: classic, has src, was parser-inserted, is not async.
- ExternalScriptKind::ParsingBlocking
- } else if !r#async && !self.non_blocking.get() {
- // Step 23.d: classic, has src, is not async, is not non-blocking.
- ExternalScriptKind::AsapInOrder
- } else {
- // Step 23.f: classic, has src.
- ExternalScriptKind::Asap
- };
-
- // Step 21.6.
- fetch_a_classic_script(
- self,
- kind,
- url,
- cors_setting,
- integrity_metadata.to_owned(),
- encoding,
- );
-
- // Step 23.
- match kind {
- ExternalScriptKind::Deferred => doc.add_deferred_script(self),
- ExternalScriptKind::ParsingBlocking => {
- doc.set_pending_parsing_blocking_script(self, None)
+ match script_type {
+ ScriptType::Classic => {
+ // Preparation for step 26.
+ let kind = if element.has_attribute(&local_name!("defer")) &&
+ was_parser_inserted &&
+ !r#async
+ {
+ // Step 26.a: classic, has src, has defer, was parser-inserted, is not async.
+ ExternalScriptKind::Deferred
+ } else if was_parser_inserted && !r#async {
+ // Step 26.c: classic, has src, was parser-inserted, is not async.
+ ExternalScriptKind::ParsingBlocking
+ } else if !r#async && !self.non_blocking.get() {
+ // Step 26.d: classic, has src, is not async, is not non-blocking.
+ ExternalScriptKind::AsapInOrder
+ } else {
+ // Step 26.f: classic, has src.
+ ExternalScriptKind::Asap
+ };
+
+ // Step 24.6.
+ fetch_a_classic_script(
+ self,
+ kind,
+ url,
+ cors_setting,
+ integrity_metadata.to_owned(),
+ encoding,
+ );
+
+ // Step 23.
+ match kind {
+ ExternalScriptKind::Deferred => doc.add_deferred_script(self),
+ ExternalScriptKind::ParsingBlocking => {
+ doc.set_pending_parsing_blocking_script(self, None)
+ },
+ ExternalScriptKind::AsapInOrder => doc.push_asap_in_order_script(self),
+ ExternalScriptKind::Asap => doc.add_asap_script(self),
+ }
+ },
+ ScriptType::Module => {
+ warn!(
+ "{} is a module script. It should be fixed after #23545 landed.",
+ url.clone()
+ );
},
- ExternalScriptKind::AsapInOrder => doc.push_asap_in_order_script(self),
- ExternalScriptKind::Asap => doc.add_asap_script(self),
}
} else {
- // Step 22.
+ // Step 25.
assert!(!text.is_empty());
- let result = Ok(ClassicScript::internal(text, base_url));
- // Step 23.
+ // Step 25-1.
+ let result = Ok(ScriptOrigin::internal(
+ text.clone(),
+ base_url.clone(),
+ script_type.clone(),
+ ));
+
+ // TODO: Step 25-2.
+ if let ScriptType::Module = script_type {
+ warn!(
+ "{} is a module script. It should be fixed after #23545 landed.",
+ base_url.clone()
+ );
+ return;
+ }
+
+ // Step 26.
if was_parser_inserted &&
doc.get_current_parser()
.map_or(false, |parser| parser.script_nesting_level() <= 1) &&
doc.get_script_blocking_stylesheets_count() > 0
{
- // Step 23.h: classic, has no src, was parser-inserted, is blocked on stylesheet.
+ // Step 26.h: classic, has no src, was parser-inserted, is blocked on stylesheet.
doc.set_pending_parsing_blocking_script(self, Some(result));
} else {
- // Step 23.i: otherwise.
+ // Step 26.i: otherwise.
self.execute(result);
}
}
}
- fn unminify_js(&self, script: &mut ClassicScript) {
+ fn unminify_js(&self, script: &mut ScriptOrigin) {
if !self.parser_document.window().unminify_js() {
return;
}
@@ -584,7 +628,7 @@ impl HTMLScriptElement {
}
/// <https://html.spec.whatwg.org/multipage/#execute-the-script-block>
- pub fn execute(&self, result: Result<ClassicScript, NetworkError>) {
+ pub fn execute(&self, result: Result<ScriptOrigin, NetworkError>) {
// Step 1.
let doc = document_from_node(self);
if self.parser_inserted.get() && &*doc != &*self.parser_document {
@@ -639,7 +683,7 @@ impl HTMLScriptElement {
}
// https://html.spec.whatwg.org/multipage/#run-a-classic-script
- pub fn run_a_classic_script(&self, script: &ClassicScript) {
+ pub fn run_a_classic_script(&self, script: &ScriptOrigin) {
// TODO use a settings object rather than this element's document/window
// Step 2
let document = document_from_node(self);
@@ -688,45 +732,58 @@ impl HTMLScriptElement {
);
}
- pub fn is_javascript(&self) -> bool {
+ // https://html.spec.whatwg.org/multipage/#prepare-a-script Step 7.
+ pub fn get_script_type(&self) -> Option<ScriptType> {
let element = self.upcast::<Element>();
+
let type_attr = element.get_attribute(&ns!(), &local_name!("type"));
- let is_js = match type_attr.as_ref().map(|s| s.value()) {
- Some(ref s) if s.is_empty() => {
- // type attr exists, but empty means js
+ let language_attr = element.get_attribute(&ns!(), &local_name!("language"));
+
+ let script_type = match (
+ type_attr.as_ref().map(|t| t.value()),
+ language_attr.as_ref().map(|l| l.value()),
+ ) {
+ (Some(ref ty), _) if ty.is_empty() => {
debug!("script type empty, inferring js");
- true
+ Some(ScriptType::Classic)
},
- Some(s) => {
- debug!("script type={}", &**s);
- SCRIPT_JS_MIMES
- .contains(&s.to_ascii_lowercase().trim_matches(HTML_SPACE_CHARACTERS))
+ (None, Some(ref lang)) if lang.is_empty() => {
+ debug!("script type empty, inferring js");
+ Some(ScriptType::Classic)
},
- None => {
- debug!("no script type");
- let language_attr = element.get_attribute(&ns!(), &local_name!("language"));
- let is_js = match language_attr.as_ref().map(|s| s.value()) {
- Some(ref s) if s.is_empty() => {
- debug!("script language empty, inferring js");
- true
- },
- Some(s) => {
- debug!("script language={}", &**s);
- let mut language = format!("text/{}", &**s);
- language.make_ascii_lowercase();
- SCRIPT_JS_MIMES.contains(&&*language)
- },
- None => {
- debug!("no script type or language, inferring js");
- true
- },
- };
- // https://github.com/rust-lang/rust/issues/21114
- is_js
+ (None, None) => {
+ debug!("script type empty, inferring js");
+ Some(ScriptType::Classic)
+ },
+ (None, Some(ref lang)) => {
+ debug!("script language={}", &***lang);
+ let language = format!("text/{}", &***lang);
+
+ if SCRIPT_JS_MIMES.contains(&language.to_ascii_lowercase().as_str()) {
+ Some(ScriptType::Classic)
+ } else {
+ None
+ }
+ },
+ (Some(ref ty), _) => {
+ debug!("script type={}", &***ty);
+
+ if &***ty == String::from("module") {
+ return Some(ScriptType::Module);
+ }
+
+ if SCRIPT_JS_MIMES
+ .contains(&ty.to_ascii_lowercase().trim_matches(HTML_SPACE_CHARACTERS))
+ {
+ Some(ScriptType::Classic)
+ } else {
+ None
+ }
},
};
+
// https://github.com/rust-lang/rust/issues/21114
- is_js
+ script_type
}
pub fn set_parser_inserted(&self, parser_inserted: bool) {
diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs
index b29858fdca5..6c418b44316 100644
--- a/components/script/dom/performance.rs
+++ b/components/script/dom/performance.rs
@@ -57,6 +57,7 @@ const INVALID_ENTRY_NAMES: &'static [&'static str] = &[
/// Performance and PerformanceObserverEntryList interfaces implementations.
#[derive(JSTraceable, MallocSizeOf)]
pub struct PerformanceEntryList {
+ /// https://w3c.github.io/performance-timeline/#dfn-performance-entry-buffer
entries: DOMPerformanceEntryList,
}
@@ -137,10 +138,13 @@ struct PerformanceObserver {
#[dom_struct]
pub struct Performance {
eventtarget: EventTarget,
- entries: DomRefCell<PerformanceEntryList>,
+ buffer: DomRefCell<PerformanceEntryList>,
observers: DomRefCell<Vec<PerformanceObserver>>,
pending_notification_observers_task: Cell<bool>,
navigation_start_precise: u64,
+ /// https://w3c.github.io/performance-timeline/#dfn-maxbuffersize
+ /// The max-size of the buffer, set to 0 once the pipeline exits.
+ /// TODO: have one max-size per entry type.
resource_timing_buffer_size_limit: Cell<usize>,
resource_timing_buffer_current_size: Cell<usize>,
resource_timing_buffer_pending_full_event: Cell<bool>,
@@ -151,7 +155,7 @@ impl Performance {
fn new_inherited(navigation_start_precise: u64) -> Performance {
Performance {
eventtarget: EventTarget::new_inherited(),
- entries: DomRefCell::new(PerformanceEntryList::new(Vec::new())),
+ buffer: DomRefCell::new(PerformanceEntryList::new(Vec::new())),
observers: DomRefCell::new(Vec::new()),
pending_notification_observers_task: Cell::new(false),
navigation_start_precise,
@@ -170,6 +174,15 @@ impl Performance {
)
}
+ /// Clear all buffered performance entries, and disable the buffer.
+ /// Called as part of the window's "clear_js_runtime" workflow,
+ /// performed when exiting a pipeline.
+ pub fn clear_and_disable_performance_entry_buffer(&self) {
+ let mut buffer = self.buffer.borrow_mut();
+ buffer.entries.clear();
+ self.resource_timing_buffer_size_limit.set(0);
+ }
+
/// Add a PerformanceObserver to the list of observers with a set of
/// observed entry types.
pub fn add_observer(
@@ -179,10 +192,10 @@ impl Performance {
buffered: bool,
) {
if buffered {
- let entries = self.entries.borrow();
+ let buffer = self.buffer.borrow();
let mut new_entries = entry_types
.iter()
- .flat_map(|e| entries.get_entries_by_name_and_type(None, Some(e.clone())))
+ .flat_map(|e| buffer.get_entries_by_name_and_type(None, Some(e.clone())))
.collect::<DOMPerformanceEntryList>();
let mut obs_entries = observer.entries();
obs_entries.append(&mut new_entries);
@@ -221,6 +234,7 @@ impl Performance {
/// Also this algorithm has been extented according to :
/// <https://w3c.github.io/resource-timing/#sec-extensions-performance-interface>
pub fn queue_entry(&self, entry: &PerformanceEntry, add_to_performance_entries_buffer: bool) {
+ // https://w3c.github.io/performance-timeline/#dfn-determine-eligibility-for-adding-a-performance-entry
if entry.entry_type() == "resource" && !self.should_queue_resource_entry(entry) {
return;
}
@@ -242,7 +256,7 @@ impl Performance {
// If the "add to performance entry buffer flag" is set, add the
// new entry to the buffer.
if add_to_performance_entries_buffer {
- self.entries
+ self.buffer
.borrow_mut()
.entries
.push(DomRoot::from_ref(entry));
@@ -390,14 +404,14 @@ impl PerformanceMethods for Performance {
// https://www.w3.org/TR/performance-timeline-2/#dom-performance-getentries
fn GetEntries(&self) -> Vec<DomRoot<PerformanceEntry>> {
- self.entries
+ self.buffer
.borrow()
.get_entries_by_name_and_type(None, None)
}
// https://www.w3.org/TR/performance-timeline-2/#dom-performance-getentriesbytype
fn GetEntriesByType(&self, entry_type: DOMString) -> Vec<DomRoot<PerformanceEntry>> {
- self.entries
+ self.buffer
.borrow()
.get_entries_by_name_and_type(None, Some(entry_type))
}
@@ -408,7 +422,7 @@ impl PerformanceMethods for Performance {
name: DOMString,
entry_type: Option<DOMString>,
) -> Vec<DomRoot<PerformanceEntry>> {
- self.entries
+ self.buffer
.borrow()
.get_entries_by_name_and_type(Some(name), entry_type)
}
@@ -435,7 +449,7 @@ impl PerformanceMethods for Performance {
// https://w3c.github.io/user-timing/#dom-performance-clearmarks
fn ClearMarks(&self, mark_name: Option<DOMString>) {
- self.entries
+ self.buffer
.borrow_mut()
.clear_entries_by_name_and_type(mark_name, Some(DOMString::from("mark")));
}
@@ -450,7 +464,7 @@ impl PerformanceMethods for Performance {
// Steps 1 and 2.
let end_time = match end_mark {
Some(name) => self
- .entries
+ .buffer
.borrow()
.get_last_entry_start_time_with_name_and_type(DOMString::from("mark"), name),
None => self.now(),
@@ -459,7 +473,7 @@ impl PerformanceMethods for Performance {
// Step 3.
let start_time = match start_mark {
Some(name) => self
- .entries
+ .buffer
.borrow()
.get_last_entry_start_time_with_name_and_type(DOMString::from("mark"), name),
None => 0.,
@@ -485,13 +499,13 @@ impl PerformanceMethods for Performance {
// https://w3c.github.io/user-timing/#dom-performance-clearmeasures
fn ClearMeasures(&self, measure_name: Option<DOMString>) {
- self.entries
+ self.buffer
.borrow_mut()
.clear_entries_by_name_and_type(measure_name, Some(DOMString::from("measure")));
}
// https://w3c.github.io/resource-timing/#dom-performance-clearresourcetimings
fn ClearResourceTimings(&self) {
- self.entries
+ self.buffer
.borrow_mut()
.clear_entries_by_name_and_type(None, Some(DOMString::from("resource")));
self.resource_timing_buffer_current_size.set(0);
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index c4c580cda32..e50d70cb916 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -1102,6 +1102,10 @@ impl WebGLRenderingContext {
self.bound_framebuffer.get()
}
+ pub fn bound_renderbuffer(&self) -> Option<DomRoot<WebGLRenderbuffer>> {
+ self.bound_renderbuffer.get()
+ }
+
pub fn extension_manager(&self) -> &WebGLExtensions {
&self.extension_manager
}
diff --git a/components/script/dom/webidls/Event.webidl b/components/script/dom/webidls/Event.webidl
index c688daedb2e..f3d281813a1 100644
--- a/components/script/dom/webidls/Event.webidl
+++ b/components/script/dom/webidls/Event.webidl
@@ -11,6 +11,7 @@ interface Event {
[Pure]
readonly attribute DOMString type;
readonly attribute EventTarget? target;
+ readonly attribute EventTarget? srcElement;
readonly attribute EventTarget? currentTarget;
const unsigned short NONE = 0;
diff --git a/components/script/dom/webidls/Performance.webidl b/components/script/dom/webidls/Performance.webidl
index 77bca4392e7..0e2f7a960d5 100644
--- a/components/script/dom/webidls/Performance.webidl
+++ b/components/script/dom/webidls/Performance.webidl
@@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/*
* The origin of this IDL file is
- * https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#sec-window.performance-attribute
+ * https://w3c.github.io/hr-time/#sec-performance
*/
typedef double DOMHighResTimeStamp;
@@ -13,7 +13,7 @@ typedef sequence<PerformanceEntry> PerformanceEntryList;
interface Performance : EventTarget {
DOMHighResTimeStamp now();
readonly attribute DOMHighResTimeStamp timeOrigin;
- // [Default] object toJSON();
+ [Default] object toJSON();
};
// https://w3c.github.io/performance-timeline/#extensions-to-the-performance-interface
diff --git a/components/script/dom/webidls/PerformanceEntry.webidl b/components/script/dom/webidls/PerformanceEntry.webidl
index 23f2f9c155a..5f6fee1cabd 100644
--- a/components/script/dom/webidls/PerformanceEntry.webidl
+++ b/components/script/dom/webidls/PerformanceEntry.webidl
@@ -12,6 +12,5 @@ interface PerformanceEntry {
readonly attribute DOMString entryType;
readonly attribute DOMHighResTimeStamp startTime;
readonly attribute DOMHighResTimeStamp duration;
-
- // [Default] object toJSON();
+ [Default] object toJSON();
};
diff --git a/components/script/dom/webidls/PerformanceNavigation.webidl b/components/script/dom/webidls/PerformanceNavigation.webidl
index 5a1ccba61f1..3e5cba196f6 100644
--- a/components/script/dom/webidls/PerformanceNavigation.webidl
+++ b/components/script/dom/webidls/PerformanceNavigation.webidl
@@ -14,5 +14,5 @@ interface PerformanceNavigation {
const unsigned short TYPE_RESERVED = 255;
readonly attribute unsigned short type;
readonly attribute unsigned short redirectCount;
- // [Default] object toJSON();
+ [Default] object toJSON();
};
diff --git a/components/script/dom/webidls/PerformanceNavigationTiming.webidl b/components/script/dom/webidls/PerformanceNavigationTiming.webidl
index 0d2c808105b..5e369b4eb91 100644
--- a/components/script/dom/webidls/PerformanceNavigationTiming.webidl
+++ b/components/script/dom/webidls/PerformanceNavigationTiming.webidl
@@ -25,7 +25,7 @@ interface PerformanceNavigationTiming : PerformanceResourceTiming {
readonly attribute DOMHighResTimeStamp loadEventEnd;
readonly attribute NavigationType type;
readonly attribute unsigned short redirectCount;
- // [Default] object toJSON();
+ [Default] object toJSON();
/* Servo-only attribute for measuring when the top-level document (not iframes) is complete. */
[Pref="dom.testperf.enabled"]
readonly attribute DOMHighResTimeStamp topLevelDomComplete;
diff --git a/components/script/dom/webidls/PerformanceResourceTiming.webidl b/components/script/dom/webidls/PerformanceResourceTiming.webidl
index acf1682e800..e4f73197a8c 100644
--- a/components/script/dom/webidls/PerformanceResourceTiming.webidl
+++ b/components/script/dom/webidls/PerformanceResourceTiming.webidl
@@ -26,5 +26,5 @@ interface PerformanceResourceTiming : PerformanceEntry {
/// readonly attribute unsigned long long transferSize;
/// readonly attribute unsigned long long encodedBodySize;
/// readonly attribute unsigned long long decodedBodySize;
- // [Default] object toJSON();
+ [Default] object toJSON();
};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index ac261879079..a79669d6c2e 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -872,19 +872,10 @@ impl WindowMethods for Window {
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/
// NavigationTiming/Overview.html#sec-window.performance-attribute
fn Performance(&self) -> DomRoot<Performance> {
- match self.current_state.get() {
- WindowState::Alive => self.performance.or_init(|| {
- let global_scope = self.upcast::<GlobalScope>();
- Performance::new(global_scope, self.navigation_start_precise.get())
- }),
- WindowState::Zombie => {
- // Don't store in Zombie state,
- // as clear_js_runtime has already been called,
- // and we won't have another opportunity to drop it.
- let global_scope = self.upcast::<GlobalScope>();
- Performance::new(global_scope, self.navigation_start_precise.get())
- },
- }
+ self.performance.or_init(|| {
+ let global_scope = self.upcast::<GlobalScope>();
+ Performance::new(global_scope, self.navigation_start_precise.get())
+ })
}
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
@@ -1308,7 +1299,9 @@ impl Window {
self.current_state.set(WindowState::Zombie);
*self.js_runtime.borrow_mut() = None;
self.window_proxy.set(None);
- self.performance.set(None);
+ if let Some(performance) = self.performance.get() {
+ performance.clear_and_disable_performance_entry_buffer();
+ }
self.ignore_all_events();
}
diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs
index 713546e1129..a1e912252e9 100644
--- a/components/script/dom/xrwebgllayer.rs
+++ b/components/script/dom/xrwebgllayer.rs
@@ -91,20 +91,25 @@ impl XRWebGLLayer {
let cx = global.get_cx();
let old_fbo = context.bound_framebuffer();
+ let old_rbo = context.bound_renderbuffer();
let old_texture = context
.textures()
.active_texture_for_image_target(TexImageTarget::Texture2D);
- // Step 8.2. "Initialize layer’s framebuffer to a new opaque framebuffer created with context."
+ // Step 9.2. "Initialize layer’s framebuffer to a new opaque framebuffer created with
+ // context and layerInit’s depth, stencil, and alpha values."
let framebuffer = context.CreateFramebuffer().ok_or(Error::Operation)?;
- // Step 8.3. "Allocate and initialize resources compatible with session’s XR device,
+ // Step 9.3. "Allocate and initialize resources compatible with session’s XR device,
// including GPU accessible memory buffers, as required to support the compositing of layer."
// Create a new texture with size given by the session's recommended resolution
let texture = context.CreateTexture().ok_or(Error::Operation)?;
+ let render_buffer = context.CreateRenderbuffer().ok_or(Error::Operation)?;
let resolution = session.with_session(|s| s.recommended_framebuffer_resolution());
let mut pixels = CustomAutoRooter::new(None);
+ let mut clear_bits = constants::COLOR_BUFFER_BIT;
+
context.BindTexture(constants::TEXTURE_2D, Some(&texture));
let sc = context.TexImage2D(
constants::TEXTURE_2D,
@@ -128,15 +133,64 @@ impl XRWebGLLayer {
0,
);
+ // Create backing store and bind a renderbuffer if requested
+ if init.depth || init.stencil {
+ let (internal_format, attachment) = if init.depth && init.stencil {
+ clear_bits |= constants::DEPTH_BUFFER_BIT | constants::STENCIL_BUFFER_BIT;
+ (
+ constants::DEPTH_STENCIL,
+ constants::DEPTH_STENCIL_ATTACHMENT,
+ )
+ } else if init.depth {
+ clear_bits |= constants::DEPTH_BUFFER_BIT;
+ (constants::DEPTH_COMPONENT16, constants::DEPTH_ATTACHMENT)
+ } else {
+ clear_bits |= constants::STENCIL_BUFFER_BIT;
+ (constants::STENCIL_INDEX8, constants::STENCIL_ATTACHMENT)
+ };
+ context.BindRenderbuffer(constants::RENDERBUFFER, Some(&render_buffer));
+ context.RenderbufferStorage(
+ constants::RENDERBUFFER,
+ internal_format,
+ resolution.width,
+ resolution.height,
+ );
+ context.FramebufferRenderbuffer(
+ constants::FRAMEBUFFER,
+ attachment,
+ constants::RENDERBUFFER,
+ Some(&render_buffer),
+ );
+ }
+
+ context.initialize_framebuffer(clear_bits);
+
// Restore the WebGL state while complaining about global mutable state
+ let fb_status = context.CheckFramebufferStatus(constants::FRAMEBUFFER);
+ let gl_status = context.GetError();
context.BindTexture(constants::TEXTURE_2D, old_texture.as_ref().map(|t| &**t));
context.BindFramebuffer(constants::FRAMEBUFFER, old_fbo.as_ref().map(|f| &**f));
+ context.BindRenderbuffer(constants::RENDERBUFFER, old_rbo.as_ref().map(|f| &**f));
- // Step 8.4: "If layer’s resources were unable to be created for any reason,
+ // Step 9.4: "If layer’s resources were unable to be created for any reason,
// throw an OperationError and abort these steps."
- sc.or(Err(Error::Operation))?;
+ if let Err(err) = sc {
+ error!("TexImage2D error {:?} while creating XR context", err);
+ return Err(Error::Operation);
+ }
+ if fb_status != constants::FRAMEBUFFER_COMPLETE {
+ error!(
+ "Framebuffer error {:x} while creating XR context",
+ fb_status
+ );
+ return Err(Error::Operation);
+ }
+ if gl_status != constants::NO_ERROR {
+ error!("GL error {:x} while creating XR context", gl_status);
+ return Err(Error::Operation);
+ }
- // Step 9. "Return layer."
+ // Step 10. "Return layer."
Ok(XRWebGLLayer::new(
&global.global(),
session,