Auto merge of #21882 - dguenther:update-document-open, r=nox

Update document.open to latest spec

<!-- Please describe your changes on the following line: -->

This is one of my first contributions, so I might need some direction cleaning it up -- I ran web-platform-tests locally, but the suite has several intermittent passes/failures for me. Thanks!

Few notes:

* I may have been wrong to eliminate all of the resets listed in what was formerly Step 18 (starts with `self.implementation.set(None);`). It's not clear to me that they're still needed or if so, what step they would fall under, but I didn't notice any web platform tests break as a result.
* <s>If I'm reading the spec right, there's a discrepancy in the error returned by the three-parameter overload of Document.open between the spec and web-platform-tests/implementations in other browsers. As written, I favored the spec, but it causes one web-platform-test to fail.</s> This has been resolved in https://github.com/whatwg/html/pull/4066
* I'm not 100% certain that tests pass as expected, I had several intermittent failures that disappeared when re-run.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #21445

<!-- Either: -->
- [x] There are tests for these changes (existing web-platform-tests)

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21882)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-10-16 04:50:43 -04:00 committed by GitHub
commit 4625160f0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 59 additions and 163 deletions

View file

@ -4196,151 +4196,108 @@ impl DocumentMethods for Document {
}
// https://html.spec.whatwg.org/multipage/#dom-document-open
fn Open(&self, _type: Option<DOMString>, replace: DOMString) -> Fallible<DomRoot<Document>> {
fn Open(&self, _unused1: Option<DOMString>, _unused2: Option<DOMString>) -> Fallible<DomRoot<Document>> {
// Step 1
if !self.is_html_document() {
// Step 1.
return Err(Error::InvalidState);
}
// Step 2.
// Step 2
if self.throw_on_dynamic_markup_insertion_counter.get() > 0 {
return Err(Error::InvalidState);
}
if !self.is_active() {
// Step 3.
return Ok(DomRoot::from_ref(self));
}
// Step 3
let entry_responsible_document = GlobalScope::entry().as_window().Document();
// Step 4
// This check is same-origin not same-origin-domain.
// https://github.com/whatwg/html/issues/2282
// https://github.com/whatwg/html/pull/2288
if !self.origin.same_origin(&entry_responsible_document.origin) {
// Step 4.
return Err(Error::Security);
}
// Step 5
if self
.get_current_parser()
.map_or(false, |parser| parser.is_active())
{
// Step 5.
return Ok(DomRoot::from_ref(self));
}
// Step 6.
// TODO: ignore-opens-during-unload counter check.
// Step 7, 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 6
if self.is_prompting_or_unloading() {
return Ok(DomRoot::from_ref(self));
}
window_from_node(self).set_navigation_start();
// Step 11.
// TODO: unload.
// Step 7
// TODO: https://github.com/servo/servo/issues/21937
if self.has_browsing_context() {
self.abort();
}
// Step 12.
self.abort();
// Step 13.
// Step 8
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 9
if self.window.Document() == DomRoot::from_ref(self) {
self.window.upcast::<EventTarget>().remove_all_listeners();
}
// Step 15.
// Step 10
// TODO: https://github.com/servo/servo/issues/21936
Node::replace_all(None, self.upcast::<Node>());
// Steps 16, 17.
// Let's not?
// TODO: https://github.com/whatwg/html/issues/1698
// Step 11
if self.is_fully_active() {
let mut new_url = entry_responsible_document.url();
if entry_responsible_document != DomRoot::from_ref(self) {
new_url.set_fragment(None);
}
// TODO: https://github.com/servo/servo/issues/21939
self.set_url(new_url);
}
// Step 18.
self.implementation.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() = DocumentStylesheetSet::new();
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 12
// TODO: https://github.com/servo/servo/issues/21938
// Step 19.
// TODO: Set the active document of document's browsing context to document with window.
// Step 13
self.set_quirks_mode(QuirksMode::NoQuirks);
// Step 20.
// TODO: Replace document's singleton objects with new instances of those objects, created in window's Realm.
// Step 21.
self.set_encoding(UTF_8);
// Step 22.
// TODO: reload override buffer.
// Step 23.
// TODO: salvageable flag.
let url = entry_responsible_document.url();
// Step 24.
self.set_url(url.clone());
// Step 25.
// TODO: mute iframe load.
// Step 26.
// Step 14
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, "text/html");
DocumentLoader::new_with_threads(resource_threads, Some(self.url()));
ServoParser::parse_html_script_input(self, self.url(), "text/html");
// Step 27.
self.ready_state.set(DocumentReadyState::Interactive);
// Step 15
self.ready_state.set(DocumentReadyState::Loading);
// Step 28.
// TODO: remove history traversal tasks.
// Step 16
// Handled when creating the parser in step 14
// Step 29.
// TODO: truncate session history.
// Step 30.
// TODO: remove earlier entries.
if !replace {
// Step 31.
// TODO: add history entry.
}
// Step 32.
// TODO: clear fired unload flag.
// Step 33 is handled when creating the parser in step 26.
// Step 34.
// Step 17
Ok(DomRoot::from_ref(self))
}
// https://html.spec.whatwg.org/multipage/#dom-document-open-window
fn Open_(&self, url: DOMString, target: DOMString, features: DOMString) -> Fallible<DomRoot<WindowProxy>> {
// WhatWG spec states this should always return a WindowProxy, but the spec for WindowProxy.open states
// it optionally returns a WindowProxy. Assume an error if window.open returns none.
// See https://github.com/whatwg/html/issues/4091
let context = self.browsing_context().ok_or(Error::InvalidAccess)?;
context.open(url, target, features).ok_or(Error::InvalidAccess)
}
// https://html.spec.whatwg.org/multipage/#dom-document-write
fn Write(&self, text: Vec<DOMString>) -> ErrorResult {
if !self.is_html_document() {
@ -4364,13 +4321,12 @@ impl DocumentMethods for Document {
// Either there is no parser, which means the parsing ended;
// or script nesting level is 0, which means the method was
// called from outside a parser-executed script.
if self.ignore_destructive_writes_counter.get() > 0 {
if self.is_prompting_or_unloading() || self.ignore_destructive_writes_counter.get() > 0 {
// Step 4.
// TODO: handle ignore-opens-during-unload counter.
return Ok(());
}
// Step 5.
self.Open(None, "".into())?;
self.Open(None, None)?;
self.get_current_parser().unwrap()
},
};

View file

@ -118,8 +118,9 @@ partial /*sealed*/ interface Document {
// dynamic markup insertion
[CEReactions, Throws]
Document open(optional DOMString type, optional DOMString replace = "");
// WindowProxy open(DOMString url, DOMString name, DOMString features, optional boolean replace = false);
Document open(optional DOMString unused1, optional DOMString unused2);
[CEReactions, Throws]
WindowProxy open(DOMString url, DOMString name, DOMString features);
[CEReactions, Throws]
void close();
[CEReactions, Throws]