aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs215
1 files changed, 209 insertions, 6 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index b2e93325236..722e0283d1e 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -16,6 +16,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
+use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter;
use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods;
@@ -131,7 +132,7 @@ use style::attr::AttrValue;
use style::context::{QuirksMode, ReflowGoal};
use style::restyle_hints::{RestyleHint, RESTYLE_STYLE_ATTRIBUTE};
use style::selector_parser::{RestyleDamage, Snapshot};
-use style::str::{split_html_space_chars, str_join};
+use style::str::{HTML_SPACE_CHARACTERS, split_html_space_chars, str_join};
use style::stylesheets::Stylesheet;
use task_source::TaskSource;
use time;
@@ -1756,6 +1757,37 @@ impl Document {
// TODO: client message queue.
}
+ // https://html.spec.whatwg.org/multipage/#abort-a-document
+ fn abort(&self) {
+ // We need to inhibit the loader before anything else.
+ self.loader.borrow_mut().inhibit_events();
+
+ // Step 1.
+ for iframe in self.iter_iframes() {
+ if let Some(document) = iframe.GetContentDocument() {
+ // TODO: abort the active documents of every child browsing context.
+ document.abort();
+ // TODO: salvageable flag.
+ }
+ }
+
+ // Step 2.
+ self.script_blocking_stylesheets_count.set(0);
+ *self.pending_parsing_blocking_script.borrow_mut() = None;
+ *self.asap_scripts_set.borrow_mut() = vec![];
+ self.asap_in_order_scripts_list.clear();
+ self.deferred_scripts.clear();
+
+ // TODO: https://github.com/servo/servo/issues/15236
+ self.window.cancel_all_tasks();
+
+ // Step 3.
+ if let Some(parser) = self.get_current_parser() {
+ parser.abort();
+ // TODO: salvageable flag.
+ }
+ }
+
pub fn notify_constellation_load(&self) {
let global_scope = self.window.upcast::<GlobalScope>();
let pipeline_id = global_scope.pipeline_id();
@@ -3280,6 +3312,149 @@ impl DocumentMethods for Document {
elements
}
+ // https://html.spec.whatwg.org/multipage/#dom-document-open
+ fn Open(&self, type_: DOMString, replace: DOMString) -> Fallible<Root<Document>> {
+ if !self.is_html_document() {
+ // Step 1.
+ return Err(Error::InvalidState);
+ }
+
+ // Step 2.
+ // TODO: handle throw-on-dynamic-markup-insertion counter.
+
+ if !self.is_active() {
+ // Step 3.
+ return Ok(Root::from_ref(self));
+ }
+
+ let entry_responsible_document = GlobalScope::entry().as_window().Document();
+
+ if !self.origin.same_origin(&entry_responsible_document.origin) {
+ // Step 4.
+ return Err(Error::Security);
+ }
+
+ if self.get_current_parser().map_or(false, |parser| parser.script_nesting_level() > 0) {
+ // Step 5.
+ return Ok(Root::from_ref(self));
+ }
+
+ // Step 6.
+ // TODO: ignore-opens-during-unload counter check.
+
+ // Step 7: first argument already bound to `type_`.
+
+ // Step 8.
+ // TODO: check session history's state.
+ let replace = replace.eq_ignore_ascii_case("replace");
+
+ // Step 9.
+ // TODO: salvageable flag.
+
+ // Step 10.
+ // TODO: prompt to unload.
+
+ // Step 11.
+ // TODO: unload.
+
+ // Step 12.
+ self.abort();
+
+ // Step 13.
+ for node in self.upcast::<Node>().traverse_preorder() {
+ node.upcast::<EventTarget>().remove_all_listeners();
+ }
+
+ // Step 14.
+ // TODO: remove any tasks associated with the Document in any task source.
+
+ // Step 15.
+ Node::replace_all(None, self.upcast::<Node>());
+
+ // Steps 16-18.
+ // Let's not?
+ // TODO: https://github.com/whatwg/html/issues/1698
+
+ // Step 19.
+ self.implementation.set(None);
+ self.location.set(None);
+ self.images.set(None);
+ self.embeds.set(None);
+ self.links.set(None);
+ self.forms.set(None);
+ self.scripts.set(None);
+ self.anchors.set(None);
+ self.applets.set(None);
+ *self.stylesheets.borrow_mut() = None;
+ self.stylesheets_changed_since_reflow.set(true);
+ self.animation_frame_ident.set(0);
+ self.animation_frame_list.borrow_mut().clear();
+ self.pending_restyles.borrow_mut().clear();
+ self.target_element.set(None);
+ *self.last_click_info.borrow_mut() = None;
+
+ // Step 20.
+ self.set_encoding(UTF_8);
+
+ // Step 21.
+ // TODO: reload override buffer.
+
+ // Step 22.
+ // TODO: salvageable flag.
+
+ let url = entry_responsible_document.url();
+
+ // Step 23.
+ self.set_url(url.clone());
+
+ // Step 24.
+ // TODO: mute iframe load.
+
+ // Step 27.
+ let type_ = if type_.eq_ignore_ascii_case("replace") {
+ "text/html"
+ } else if let Some(position) = type_.find(';') {
+ &type_[0..position]
+ } else {
+ &*type_
+ };
+ let type_ = type_.trim_matches(HTML_SPACE_CHARACTERS);
+
+ // Step 25.
+ let resource_threads =
+ self.window.upcast::<GlobalScope>().resource_threads().clone();
+ *self.loader.borrow_mut() =
+ DocumentLoader::new_with_threads(resource_threads, Some(url.clone()));
+ ServoParser::parse_html_script_input(self, url, type_);
+
+ // Step 26.
+ self.ready_state.set(DocumentReadyState::Interactive);
+
+ // Step 28 is handled when creating the parser in step 25.
+
+ // Step 29.
+ // TODO: truncate session history.
+
+ // Step 30.
+ // TODO: remove history traversal tasks.
+
+ // Step 31.
+ // TODO: remove earlier entries.
+
+ if !replace {
+ // Step 32.
+ // TODO: add history entry.
+ }
+
+ // Step 33.
+ // TODO: clear fired unload flag.
+
+ // Step 34 is handled when creating the parser in step 25.
+
+ // Step 35.
+ Ok(Root::from_ref(self))
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-document-write
fn Write(&self, text: Vec<DOMString>) -> ErrorResult {
if !self.is_html_document() {
@@ -3294,9 +3469,8 @@ impl DocumentMethods for Document {
return Ok(());
}
- let parser = self.get_current_parser();
- let parser = match parser.as_ref() {
- Some(parser) if parser.script_nesting_level() > 0 => parser,
+ let parser = match self.get_current_parser() {
+ Some(ref parser) if parser.can_write() => Root::from_ref(&**parser),
_ => {
// Either there is no parser, which means the parsing ended;
// or script nesting level is 0, which means the method was
@@ -3307,8 +3481,8 @@ impl DocumentMethods for Document {
return Ok(());
}
// Step 5.
- // TODO: call document.open().
- return Err(Error::InvalidState);
+ self.Open("text/html".into(), "".into())?;
+ self.get_current_parser().unwrap()
}
};
@@ -3328,6 +3502,30 @@ impl DocumentMethods for Document {
self.Write(text)
}
+ // https://html.spec.whatwg.org/multipage/#dom-document-close
+ fn Close(&self) -> ErrorResult {
+ if !self.is_html_document() {
+ // Step 1.
+ return Err(Error::InvalidState);
+ }
+
+ // Step 2.
+ // TODO: handle throw-on-dynamic-markup-insertion counter.
+
+ let parser = match self.get_current_parser() {
+ Some(ref parser) if parser.is_script_created() => Root::from_ref(&**parser),
+ _ => {
+ // Step 3.
+ return Ok(());
+ }
+ };
+
+ // Step 4-6.
+ parser.close();
+
+ Ok(())
+ }
+
// https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers
document_and_element_event_handlers!();
@@ -3496,6 +3694,7 @@ impl PendingInOrderScriptVec {
fn is_empty(&self) -> bool {
self.scripts.borrow().is_empty()
}
+
fn push(&self, element: &HTMLScriptElement) {
self.scripts.borrow_mut().push_back(PendingScript::new(element));
}
@@ -3515,6 +3714,10 @@ impl PendingInOrderScriptVec {
scripts.pop_front();
pair
}
+
+ fn clear(&self) {
+ *self.scripts.borrow_mut() = Default::default();
+ }
}
#[derive(HeapSizeOf, JSTraceable)]