Issue #1118 - Part 5: Change the way document.open() works

This changes the work we do for document.open() in the following ways:
- We no longer create a new Window when doing document.open().
  We use the same Window but remove all the event listeners on the
  existing DOM tree and Window before removing the document's existing
  children to provide a clean slate document to use for .write().
- We no longer create a session history entry (previously would be a
  wyciwyg URI). We now replace the current one, effectively losing the
  entry for the original document.
- We now support document.open() on windowless documents.
This commit is contained in:
wolfbeast 2019-12-22 19:57:30 +01:00 committed by Roy Tam
commit fc5d61608c
9 changed files with 400 additions and 297 deletions

View file

@ -1968,22 +1968,10 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
}
void
nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
nsIPrincipal* aPrincipal)
{
NS_PRECONDITION(aURI, "Null URI passed to ResetToURI");
if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
PR_LogPrint("DOCUMENT %p ResetToURI %s", this,
aURI->GetSpecOrDefault().get());
}
mSecurityInfo = nullptr;
mDocumentLoadGroup = nullptr;
nsDocument::DisconnectNodeTree() {
// Delete references to sub-documents and kill the subdocument map,
// if any. It holds strong references
// if any. This is not strictly needed, but makes the node tree
// teardown a bit faster.
delete mSubDocuments;
mSubDocuments = nullptr;
@ -2019,6 +2007,22 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
"After removing all children, there should be no root elem");
}
mInUnlinkOrDeletion = oldVal;
}
void
nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
nsIPrincipal* aPrincipal)
{
NS_PRECONDITION(aURI, "Null URI passed to ResetToURI");
if (gDocumentLeakPRLog && MOZ_LOG_TEST(gDocumentLeakPRLog, LogLevel::Debug)) {
PR_LogPrint("DOCUMENT %p ResetToURI %s", this,
aURI->GetSpecOrDefault().get());
}
mSecurityInfo = nullptr;
mDocumentLoadGroup = nullptr;
// Reset our stylesheets
ResetStylesheetsToURI(aURI);
@ -2029,6 +2033,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
mListenerManager = nullptr;
}
DisconnectNodeTree();
// Release the stylesheets list.
mDOMStyleSheets = nullptr;
@ -9077,7 +9083,8 @@ nsDocument::CloneDocHelper(nsDocument* clone) const
}
void
nsDocument::SetReadyStateInternal(ReadyState rs)
nsDocument::SetReadyStateInternal(ReadyState rs,
bool updateTimingInformation)
{
mReadyState = rs;
if (rs == READYSTATE_UNINITIALIZED) {
@ -9086,7 +9093,12 @@ nsDocument::SetReadyStateInternal(ReadyState rs)
// transition undetectable by Web content.
return;
}
if (mTiming) {
if (updateTimingInformation && READYSTATE_LOADING == rs) {
mLoadingTimeStamp = mozilla::TimeStamp::Now();
}
if (updateTimingInformation && mTiming) {
switch (rs) {
case READYSTATE_LOADING:
mTiming->NotifyDOMLoading(nsIDocument::GetDocumentURI());
@ -9102,10 +9114,6 @@ nsDocument::SetReadyStateInternal(ReadyState rs)
break;
}
}
// At the time of loading start, we don't have timing object, record time.
if (READYSTATE_LOADING == rs) {
mLoadingTimeStamp = mozilla::TimeStamp::Now();
}
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, NS_LITERAL_STRING("readystatechange"),