void MediaDocument::BecomeInteractive() { // Even though our readyState code isn't really reliable, here we pretend // that it is and conclude that we are restoring from the b/f cache if // GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE. if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) { MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING, "Bad readyState"); SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE); } }
void VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) { // Set the script global object on the superclass before doing // anything that might require it.... MediaDocument::SetScriptGlobalObject(aScriptGlobalObject); if (aScriptGlobalObject) { if (!GetRootElement()) { // Create synthetic document #ifdef DEBUG nsresult rv = #endif CreateSyntheticVideoDocument(); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic video document"); } if (!nsContentUtils::IsChildOfSameType(this) && GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) { LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css")); LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelVideoDocument.css")); LinkScript(NS_LITERAL_STRING("chrome://global/content/TopLevelVideoDocument.js")); } BecomeInteractive(); } }
void MediaDocument::InitialSetupDone() { MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING, "Bad readyState: we should still be doing our initial load"); mDidInitialDocumentSetup = true; nsContentUtils::AddScriptRunner( new nsDocElementCreatedNotificationRunner(this)); SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE); }
void VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) { // Set the script global object on the superclass before doing // anything that might require it.... MediaDocument::SetScriptGlobalObject(aScriptGlobalObject); if (aScriptGlobalObject) { if (!nsContentUtils::IsChildOfSameType(this) && GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) { LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css")); LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelVideoDocument.css")); } BecomeInteractive(); } }
void ImageDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) { // If the script global object is changing, we need to unhook our event // listeners on the window. nsCOMPtr<EventTarget> target; if (mScriptGlobalObject && aScriptGlobalObject != mScriptGlobalObject) { target = do_QueryInterface(mScriptGlobalObject); target->RemoveEventListener(NS_LITERAL_STRING("resize"), this, false); target->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, false); } // Set the script global object on the superclass before doing // anything that might require it.... MediaDocument::SetScriptGlobalObject(aScriptGlobalObject); if (aScriptGlobalObject) { if (!GetRootElement()) { // Create synthetic document #ifdef DEBUG nsresult rv = #endif CreateSyntheticDocument(); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic document"); target = do_QueryInterface(mImageContent); target->AddEventListener(NS_LITERAL_STRING("load"), this, false); target->AddEventListener(NS_LITERAL_STRING("click"), this, false); } target = do_QueryInterface(aScriptGlobalObject); target->AddEventListener(NS_LITERAL_STRING("resize"), this, false); target->AddEventListener(NS_LITERAL_STRING("keypress"), this, false); if (GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) { LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/ImageDocument.css")); if (!nsContentUtils::IsChildOfSameType(this)) { LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelImageDocument.css")); LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/media/TopLevelImageDocument.css")); } } BecomeInteractive(); } }
void MediaDocument::BecomeInteractive() { // In principle, if we knew the readyState code to work, we could infer // restoration from GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE. bool restoring = false; nsPIDOMWindow* window = GetWindow(); if (window) { nsIDocShell* docShell = window->GetDocShell(); if (docShell) { docShell->GetRestoringDocument(&restoring); } } if (!restoring) { MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING, "Bad readyState"); SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE); } }
NS_IMETHODIMP nsXMLDocument::Load(const nsAString& aUrl, bool *aReturn) { bool hasHadScriptObject = true; nsIScriptGlobalObject* scriptObject = GetScriptHandlingObject(hasHadScriptObject); NS_ENSURE_STATE(scriptObject || !hasHadScriptObject); ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning"); NS_ENSURE_ARG_POINTER(aReturn); *aReturn = false; nsCOMPtr<nsIDocument> callingDoc = do_QueryInterface(nsContentUtils::GetDocumentFromContext()); nsIURI *baseURI = mDocumentURI; nsAutoCString charset; if (callingDoc) { baseURI = callingDoc->GetDocBaseURI(); charset = callingDoc->GetDocumentCharacterSet(); } // Create a new URI nsCOMPtr<nsIURI> uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI); if (NS_FAILED(rv)) { return rv; } // Check to see whether the current document is allowed to load this URI. // It's important to use the current document's principal for this check so // that we don't end up in a case where code with elevated privileges is // calling us and changing the principal of this document. // Enforce same-origin even for chrome loaders to avoid someone accidentally // using a document that content has a reference to and turn that into a // chrome document. nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); if (!nsContentUtils::IsSystemPrincipal(principal)) { rv = principal->CheckMayLoad(uri, false, false); NS_ENSURE_SUCCESS(rv, rv); int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST, uri, principal, callingDoc ? callingDoc.get() : static_cast<nsIDocument*>(this), NS_LITERAL_CSTRING("application/xml"), nullptr, &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); NS_ENSURE_SUCCESS(rv, rv); if (NS_CP_REJECTED(shouldLoad)) { return NS_ERROR_CONTENT_BLOCKED; } } else { // We're called from chrome, check to make sure the URI we're // about to load is also chrome. bool isChrome = false; if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) { nsAutoCString spec; if (mDocumentURI) mDocumentURI->GetSpec(spec); nsAutoString error; error.AssignLiteral("Cross site loading using document.load is no " "longer supported. Use XMLHttpRequest instead."); nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = errorObject->InitWithWindowID(error, NS_ConvertUTF8toUTF16(spec), EmptyString(), 0, 0, nsIScriptError::warningFlag, "DOM", callingDoc ? callingDoc->InnerWindowID() : this->InnerWindowID()); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); if (consoleService) { consoleService->LogMessage(errorObject); } return NS_ERROR_DOM_SECURITY_ERR; } } // Partial Reset, need to restore principal for security reasons and // event listener manager so that load listeners etc. will // remain. This should be done before the security check is done to // ensure that the document is reset even if the new document can't // be loaded. Note that we need to hold a strong ref to |principal| // here, because ResetToURI will null out our node principal before // setting the new one. nsRefPtr<nsEventListenerManager> elm(mListenerManager); mListenerManager = nullptr; // When we are called from JS we can find the load group for the page, // and add ourselves to it. This way any pending requests // will be automatically aborted if the user leaves the page. nsCOMPtr<nsILoadGroup> loadGroup; if (callingDoc) { loadGroup = callingDoc->GetDocumentLoadGroup(); } ResetToURI(uri, loadGroup, principal); mListenerManager = elm; // Create a channel nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker(); NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY); nsCOMPtr<nsIChannel> channel; // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, // which in turn keeps STOP button from becoming active rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, nsIRequest::LOAD_BACKGROUND); if (NS_FAILED(rv)) { return rv; } // StartDocumentLoad asserts that readyState is uninitialized, so // uninitialize it. SetReadyStateInternal make this transition invisible to // Web content. But before doing that, assert that the current readyState // is complete as it should be after the call to ResetToURI() above. MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE, "Bad readyState"); SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED); // Prepare for loading the XML document "into oneself" nsCOMPtr<nsIStreamListener> listener; if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, loadGroup, nullptr, getter_AddRefs(listener), false))) { NS_ERROR("nsXMLDocument::Load: Failed to start the document load."); return rv; } // After this point, if we error out of this method we should clear // mChannelIsPending. // Start an asynchronous read of the XML document rv = channel->AsyncOpen(listener, nullptr); if (NS_FAILED(rv)) { mChannelIsPending = false; return rv; } if (!mAsync) { nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); nsAutoSyncOperation sync(this); mLoopingForSyncLoad = true; while (mLoopingForSyncLoad) { if (!NS_ProcessNextEvent(thread)) break; } // We set return to true unless there was a parsing error nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRootElement()); if (node) { nsAutoString name, ns; if (NS_SUCCEEDED(node->GetLocalName(name)) && name.EqualsLiteral("parsererror") && NS_SUCCEEDED(node->GetNamespaceURI(ns)) && ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { //return is already false } else { *aReturn = true; } } } else { *aReturn = true; } return NS_OK; }