Skip to content

Commit

Permalink
Auto merge of #15303 - nox:open-your-heart-to-eternal-dimension, r=<try>
Browse files Browse the repository at this point in the history
[Do not merge] Implement document.open and document.close
  • Loading branch information
bors-servo committed Jan 30, 2017
2 parents 71deabc + 6111d92 commit 3d221da
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 33 deletions.
7 changes: 6 additions & 1 deletion components/script/dom/bindings/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,16 @@ impl DOMString {
self.0.push_str(string)
}

/// Truncates this `DOMString`, removing all contents.
/// Clears this `DOMString`, removing all contents.
pub fn clear(&mut self) {
self.0.clear()
}

/// Shortens this String to the specified length.
pub fn truncate(&mut self, new_len: usize) {
self.0.truncate(new_len);
}

/// An iterator over the bytes of this `DOMString`.
pub fn bytes(&self) -> Bytes {
self.0.bytes()
Expand Down
195 changes: 189 additions & 6 deletions components/script/dom/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -131,7 +132,7 @@ use style::attr::AttrValue;
use style::context::{QuirksMode, ReflowGoal};
use style::restyle_hints::RestyleHint;
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;
Expand Down Expand Up @@ -1756,6 +1757,35 @@ 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();
self.window.cancel_all_fetch_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();
Expand Down Expand Up @@ -3271,6 +3301,131 @@ impl DocumentMethods for Document {
elements
}

// https://html.spec.whatwg.org/multipage/#opening-the-input-stream:dom-document-open-4
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-19.
// Let's not?
// TODO: https://github.com/whatwg/html/issues/1698

// 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 25.
ServoParser::parse_html_script_input(self, url);

// Step 26.
self.ready_state.set(DocumentReadyState::Interactive);

// 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);

if !type_.eq_ignore_ascii_case("text/html") {
// Step 28.
// TODO: switch tokenizer to PLAINTEXT state.
}

// 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.
// TODO: set insertion point.

// 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() {
Expand All @@ -3285,9 +3440,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
Expand All @@ -3298,8 +3452,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()
}
};

Expand All @@ -3319,6 +3473,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!();

Expand Down Expand Up @@ -3487,6 +3665,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));
}
Expand All @@ -3506,6 +3685,10 @@ impl PendingInOrderScriptVec {
scripts.pop_front();
pair
}

fn clear(&self) {
*self.scripts.borrow_mut() = Default::default();
}
}

#[derive(HeapSizeOf, JSTraceable)]
Expand Down
4 changes: 4 additions & 0 deletions components/script/dom/eventtarget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ impl EventTarget {
event.dispatch(self, None)
}

pub fn remove_all_listeners(&self) {
*self.handlers.borrow_mut() = Default::default();
}

/// https://html.spec.whatwg.org/multipage/#event-handler-attributes:event-handlers-11
fn set_inline_event_listener(&self,
ty: Atom,
Expand Down
Loading

0 comments on commit 3d221da

Please sign in to comment.