/*--------------------------------------------------------------------------- StartDocumentLoad Called on start of load in a single frame ----------------------------------------------------------------------------*/ nsresult nsEditingSession::StartDocumentLoad(nsIWebProgress *aWebProgress, bool aIsToBeMadeEditable) { #ifdef NOISY_DOC_LOADING printf("======= StartDocumentLoad ========\n"); #endif NS_ENSURE_ARG_POINTER(aWebProgress); // If we have an editor here, then we got a reload after making the editor. // We need to blow it away and make a new one at the end of the load. nsCOMPtr<nsIDOMWindow> domWindow; aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); if (domWindow) { nsIDocShell *docShell = GetDocShellFromWindow(domWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); docShell->DetachEditorFromWindow(); } if (aIsToBeMadeEditable) mEditorStatus = eEditorCreationInProgress; return NS_OK; }
NS_IMETHODIMP nsEditingSession::DisableJSAndPlugins(nsIDOMWindow *aWindow) { nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); bool tmp; nsresult rv = docShell->GetAllowJavascript(&tmp); NS_ENSURE_SUCCESS(rv, rv); mScriptsEnabled = tmp; rv = docShell->SetAllowJavascript(false); NS_ENSURE_SUCCESS(rv, rv); // Disable plugins in this document: mPluginsEnabled = docShell->PluginsAllowedInCurrentDoc(); rv = docShell->SetAllowPlugins(false); NS_ENSURE_SUCCESS(rv, rv); mDisabledJSAndPlugins = true; return NS_OK; }
/*--------------------------------------------------------------------------- OnLocationChange ----------------------------------------------------------------------------*/ NS_IMETHODIMP nsEditingSession::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *aURI, PRUint32 aFlags) { nsCOMPtr<nsIDOMWindow> domWindow; nsresult rv = aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDOMDocument> domDoc; rv = domWindow->GetDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc); NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); doc->SetDocumentURI(aURI); // Notify the location-changed observer that // the document URL has changed nsIDocShell *docShell = GetDocShellFromWindow(domWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShell); nsCOMPtr<nsPICommandUpdater> commandUpdater = do_QueryInterface(commandManager); NS_ENSURE_TRUE(commandUpdater, NS_ERROR_FAILURE); return commandUpdater->CommandStatusChanged("obs_documentLocationChanged"); }
NS_IMETHODIMP nsRegressionTester::DumpFrameModel(nsIDOMWindow *aWindowToDump, nsIFile *aDestFile, uint32_t aFlagsMask, int32_t *aResult) { NS_ENSURE_ARG(aWindowToDump); NS_ENSURE_ARG_POINTER(aResult); *aResult = DUMP_RESULT_ERROR; #ifndef DEBUG return NS_ERROR_NOT_AVAILABLE; #else nsresult rv = NS_ERROR_NOT_AVAILABLE; uint32_t busyFlags; bool stillLoading; nsCOMPtr<nsIDocShell> docShell; rv = GetDocShellFromWindow(aWindowToDump, getter_AddRefs(docShell)); if (NS_FAILED(rv)) return rv; // find out if the document is loaded docShell->GetBusyFlags(&busyFlags); stillLoading = busyFlags & (nsIDocShell::BUSY_FLAGS_BUSY | nsIDocShell::BUSY_FLAGS_PAGE_LOADING); if (stillLoading) { *aResult = DUMP_RESULT_LOADING; return NS_OK; } nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); nsIFrame* root = presShell->GetRootFrame(); FILE* fp = stdout; if (aDestFile) { rv = aDestFile->OpenANSIFileDesc("w", &fp); if (NS_FAILED(rv)) return rv; } if (aFlagsMask & DUMP_FLAGS_MASK_PRINT_MODE) { nsCOMPtr <nsIContentViewer> viewer; docShell->GetContentViewer(getter_AddRefs(viewer)); if (viewer){ nsCOMPtr<nsIContentViewerFile> viewerFile = do_QueryInterface(viewer); if (viewerFile) { viewerFile->Print(true, fp, nullptr); } } } else { root->DumpRegressionData(presShell->GetPresContext(), fp, 0); } if (fp != stdout) fclose(fp); *aResult = DUMP_RESULT_COMPLETED; return NS_OK; #endif }
NS_IMETHODIMP nsEditingSession::DisableJSAndPlugins(nsIDOMWindow *aWindow) { nsIDocShell *docShell = GetDocShellFromWindow(aWindow); if (!docShell) return NS_ERROR_FAILURE; PRBool tmp; nsresult rv = docShell->GetAllowJavascript(&tmp); NS_ENSURE_SUCCESS(rv, rv); mScriptsEnabled = tmp; rv = docShell->SetAllowJavascript(PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); // Disable plugins in this document: rv = docShell->GetAllowPlugins(&tmp); NS_ENSURE_SUCCESS(rv, rv); mPluginsEnabled = tmp; rv = docShell->SetAllowPlugins(PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); mDisabledJSAndPlugins = PR_TRUE; return NS_OK; }
/*--------------------------------------------------------------------------- GetEditorDocShellFromWindow Utility method. This will always return an error if no docShell is returned. ----------------------------------------------------------------------------*/ nsresult nsEditingSession::GetEditorDocShellFromWindow(nsIDOMWindow *aWindow, nsIEditorDocShell** outDocShell) { nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); return docShell->QueryInterface(NS_GET_IID(nsIEditorDocShell), (void **)outDocShell); }
void nsEditingSession::RemoveWebProgressListener(nsIDOMWindow *aWindow) { nsIDocShell *docShell = GetDocShellFromWindow(aWindow); nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell); if (webProgress) { webProgress->RemoveProgressListener(this); mProgressListenerRegistered = false; } }
NS_IMETHODIMP nsEditingSession::RestoreJSAndPlugins(nsIDOMWindow *aWindow) { NS_ENSURE_TRUE(mDisabledJSAndPlugins, NS_OK); mDisabledJSAndPlugins = false; nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); nsresult rv = docShell->SetAllowJavascript(mScriptsEnabled); NS_ENSURE_SUCCESS(rv, rv); // Disable plugins in this document: return docShell->SetAllowPlugins(mPluginsEnabled); }
/*--------------------------------------------------------------------------- EndPageLoad Called on end load of the entire page (incl. subframes) ----------------------------------------------------------------------------*/ nsresult nsEditingSession::EndPageLoad(nsIWebProgress *aWebProgress, nsIChannel* aChannel, nsresult aStatus) { #ifdef NOISY_DOC_LOADING printf("======= EndPageLoad ========\n"); printf(" with status %d, ", aStatus); nsCOMPtr<nsIURI> uri; nsXPIDLCString spec; if (NS_SUCCEEDED(aChannel->GetURI(getter_AddRefs(uri)))) { uri->GetSpec(spec); printf("uri %s\n", spec.get()); } nsCAutoString contentType; aChannel->GetContentType(contentType); if (!contentType.IsEmpty()) printf(" flags = %d, status = %d, MIMETYPE = %s\n", mEditorFlags, mEditorStatus, contentType.get()); #endif // Set the error state -- we will create an editor anyway // and load empty doc later if (aStatus == NS_ERROR_FILE_NOT_FOUND) mEditorStatus = eEditorErrorFileNotFound; nsCOMPtr<nsIDOMWindow> domWindow; aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); nsIDocShell *docShell = GetDocShellFromWindow(domWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); // cancel refresh from meta tags // we need to make sure that all pages in editor (whether editable or not) // can't refresh contents being edited nsCOMPtr<nsIRefreshURI> refreshURI = do_QueryInterface(docShell); if (refreshURI) refreshURI->CancelRefreshURITimers(); #if 0 // Shouldn't we do this when we want to edit sub-frames? return MakeWindowEditable(domWindow, "html", false, mInteractive); #else return NS_OK; #endif }
NS_IMETHODIMP nsEditingSession::RestoreJSAndPlugins(nsIDOMWindow *aWindow) { if (!mDisabledJSAndPlugins) return NS_OK; mDisabledJSAndPlugins = PR_FALSE; nsIDocShell *docShell = GetDocShellFromWindow(aWindow); if (!docShell) return NS_ERROR_FAILURE; nsresult rv = docShell->SetAllowJavascript(mScriptsEnabled); NS_ENSURE_SUCCESS(rv, rv); // Disable plugins in this document: return docShell->SetAllowPlugins(mPluginsEnabled); }
/*--------------------------------------------------------------------------- PrepareForEditing Set up this editing session for one or more editors ----------------------------------------------------------------------------*/ nsresult nsEditingSession::PrepareForEditing(nsIDOMWindow *aWindow) { if (mProgressListenerRegistered) return NS_OK; nsIDocShell *docShell = GetDocShellFromWindow(aWindow); // register callback nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell); NS_ENSURE_TRUE(webProgress, NS_ERROR_FAILURE); nsresult rv = webProgress->AddProgressListener(this, (nsIWebProgress::NOTIFY_STATE_NETWORK | nsIWebProgress::NOTIFY_STATE_DOCUMENT | nsIWebProgress::NOTIFY_LOCATION)); mProgressListenerRegistered = NS_SUCCEEDED(rv); return rv; }
/* boolean findNext (); */ NS_IMETHODIMP nsWebBrowserFind::FindNext(bool *outDidFind) { NS_ENSURE_ARG_POINTER(outDidFind); *outDidFind = false; NS_ENSURE_TRUE(CanFindNext(), NS_ERROR_NOT_INITIALIZED); nsresult rv = NS_OK; nsCOMPtr<nsIDOMWindow> searchFrame = do_QueryReferent(mCurrentSearchFrame); NS_ENSURE_TRUE(searchFrame, NS_ERROR_NOT_INITIALIZED); nsCOMPtr<nsIDOMWindow> rootFrame = do_QueryReferent(mRootSearchFrame); NS_ENSURE_TRUE(rootFrame, NS_ERROR_NOT_INITIALIZED); // first, if there's a "cmd_findagain" observer around, check to see if it // wants to perform the find again command . If it performs the find again // it will return true, in which case we exit ::FindNext() early. // Otherwise, nsWebBrowserFind needs to perform the find again command itself // this is used by nsTypeAheadFind, which controls find again when it was // the last executed find in the current window. nsCOMPtr<nsIObserverService> observerSvc = mozilla::services::GetObserverService(); if (observerSvc) { nsCOMPtr<nsISupportsInterfacePointer> windowSupportsData = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsISupports> searchWindowSupports = do_QueryInterface(rootFrame); windowSupportsData->SetData(searchWindowSupports); NS_NAMED_LITERAL_STRING(dnStr, "down"); NS_NAMED_LITERAL_STRING(upStr, "up"); observerSvc->NotifyObservers(windowSupportsData, "nsWebBrowserFind_FindAgain", mFindBackwards? upStr.get(): dnStr.get()); windowSupportsData->GetData(getter_AddRefs(searchWindowSupports)); // findnext performed if search window data cleared out *outDidFind = searchWindowSupports == nullptr; if (*outDidFind) return NS_OK; } // next, look in the current frame. If found, return. // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. rv = SearchInFrame(searchFrame, false, outDidFind); if (NS_FAILED(rv)) return rv; if (*outDidFind) return OnFind(searchFrame); // we are done // if we are not searching other frames, return if (!mSearchSubFrames && !mSearchParentFrames) return NS_OK; nsIDocShell *rootDocShell = GetDocShellFromWindow(rootFrame); if (!rootDocShell) return NS_ERROR_FAILURE; int32_t enumDirection; if (mFindBackwards) enumDirection = nsIDocShell::ENUMERATE_BACKWARDS; else enumDirection = nsIDocShell::ENUMERATE_FORWARDS; nsCOMPtr<nsISimpleEnumerator> docShellEnumerator; rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll, enumDirection, getter_AddRefs(docShellEnumerator)); if (NS_FAILED(rv)) return rv; // remember where we started nsCOMPtr<nsIDocShellTreeItem> startingItem = do_QueryInterface(GetDocShellFromWindow(searchFrame), &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIDocShellTreeItem> curItem; // XXX We should avoid searching in frameset documents here. // We also need to honour mSearchSubFrames and mSearchParentFrames. bool hasMore, doFind = false; while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) && hasMore) { nsCOMPtr<nsISupports> curSupports; rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports)); if (NS_FAILED(rv)) break; curItem = do_QueryInterface(curSupports, &rv); if (NS_FAILED(rv)) break; if (doFind) { searchFrame = do_GetInterface(curItem, &rv); if (NS_FAILED(rv)) break; OnStartSearchFrame(searchFrame); // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. rv = SearchInFrame(searchFrame, false, outDidFind); if (NS_FAILED(rv)) return rv; if (*outDidFind) return OnFind(searchFrame); // we are done OnEndSearchFrame(searchFrame); } if (curItem.get() == startingItem.get()) doFind = true; // start looking in frames after this one }; if (!mWrapFind) { // remember where we left off SetCurrentSearchFrame(searchFrame); return NS_OK; } // From here on, we're wrapping, first through the other frames, // then finally from the beginning of the starting frame back to // the starting point. // because nsISimpleEnumerator is totally lame and isn't resettable, I // have to make a new one docShellEnumerator = nullptr; rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll, enumDirection, getter_AddRefs(docShellEnumerator)); if (NS_FAILED(rv)) return rv; while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) && hasMore) { nsCOMPtr<nsISupports> curSupports; rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports)); if (NS_FAILED(rv)) break; curItem = do_QueryInterface(curSupports, &rv); if (NS_FAILED(rv)) break; searchFrame = do_GetInterface(curItem, &rv); if (NS_FAILED(rv)) break; if (curItem.get() == startingItem.get()) { // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. rv = SearchInFrame(searchFrame, true, outDidFind); if (NS_FAILED(rv)) return rv; if (*outDidFind) return OnFind(searchFrame); // we are done break; } OnStartSearchFrame(searchFrame); // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. rv = SearchInFrame(searchFrame, false, outDidFind); if (NS_FAILED(rv)) return rv; if (*outDidFind) return OnFind(searchFrame); // we are done OnEndSearchFrame(searchFrame); } // remember where we left off SetCurrentSearchFrame(searchFrame); NS_ASSERTION(NS_SUCCEEDED(rv), "Something failed"); return rv; }
/*--------------------------------------------------------------------------- EndDocumentLoad Called on end of load in a single frame ----------------------------------------------------------------------------*/ nsresult nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress, nsIChannel* aChannel, nsresult aStatus, bool aIsToBeMadeEditable) { NS_ENSURE_ARG_POINTER(aWebProgress); #ifdef NOISY_DOC_LOADING printf("======= EndDocumentLoad ========\n"); printf("with status %d, ", aStatus); nsCOMPtr<nsIURI> uri; nsXPIDLCString spec; if (NS_SUCCEEDED(aChannel->GetURI(getter_AddRefs(uri)))) { uri->GetSpec(spec); printf(" uri %s\n", spec.get()); } #endif // We want to call the base class EndDocumentLoad, // but avoid some of the stuff // that nsDocShell does (need to refactor). // OK, time to make an editor on this document nsCOMPtr<nsIDOMWindow> domWindow; aWebProgress->GetDOMWindow(getter_AddRefs(domWindow)); // Set the error state -- we will create an editor // anyway and load empty doc later if (aIsToBeMadeEditable) { if (aStatus == NS_ERROR_FILE_NOT_FOUND) mEditorStatus = eEditorErrorFileNotFound; } nsIDocShell *docShell = GetDocShellFromWindow(domWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); // better error handling? // cancel refresh from meta tags // we need to make sure that all pages in editor (whether editable or not) // can't refresh contents being edited nsCOMPtr<nsIRefreshURI> refreshURI = do_QueryInterface(docShell); if (refreshURI) refreshURI->CancelRefreshURITimers(); nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(docShell); nsresult rv = NS_OK; // did someone set the flag to make this shell editable? if (aIsToBeMadeEditable && mCanCreateEditor && editorDocShell) { bool makeEditable; editorDocShell->GetEditable(&makeEditable); if (makeEditable) { // To keep pre Gecko 1.9 behavior, setup editor always when // mMakeWholeDocumentEditable. bool needsSetup = false; if (mMakeWholeDocumentEditable) { needsSetup = true; } else { // do we already have an editor here? nsCOMPtr<nsIEditor> editor; rv = editorDocShell->GetEditor(getter_AddRefs(editor)); NS_ENSURE_SUCCESS(rv, rv); needsSetup = !editor; } if (needsSetup) { mCanCreateEditor = false; rv = SetupEditorOnWindow(domWindow); if (NS_FAILED(rv)) { // If we had an error, setup timer to load a blank page later if (mLoadBlankDocTimer) { // Must cancel previous timer? mLoadBlankDocTimer->Cancel(); mLoadBlankDocTimer = NULL; } mLoadBlankDocTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); NS_ENSURE_SUCCESS(rv, rv); mEditorStatus = eEditorCreationInProgress; mLoadBlankDocTimer->InitWithFuncCallback( nsEditingSession::TimerCallback, static_cast<void*> (mDocShell.get()), 10, nsITimer::TYPE_ONE_SHOT); } } } } return rv; }
/*--------------------------------------------------------------------------- SetupEditorOnWindow nsIEditor setupEditorOnWindow (in nsIDOMWindow aWindow); ----------------------------------------------------------------------------*/ NS_IMETHODIMP nsEditingSession::SetupEditorOnWindow(nsIDOMWindow *aWindow) { mDoneSetup = true; nsresult rv; //MIME CHECKING //must get the content type // Note: the doc gets this from the network channel during StartPageLoad, // so we don't have to get it from there ourselves nsCOMPtr<nsIDOMDocument> doc; nsCAutoString mimeCType; //then lets check the mime type if (NS_SUCCEEDED(aWindow->GetDocument(getter_AddRefs(doc))) && doc) { nsAutoString mimeType; if (NS_SUCCEEDED(doc->GetContentType(mimeType))) AppendUTF16toUTF8(mimeType, mimeCType); if (IsSupportedTextType(mimeCType.get())) { mEditorType.AssignLiteral("text"); mimeCType = "text/plain"; } else if (!mimeCType.EqualsLiteral("text/html") && !mimeCType.EqualsLiteral("application/xhtml+xml")) { // Neither an acceptable text or html type. mEditorStatus = eEditorErrorCantEditMimeType; // Turn editor into HTML -- we will load blank page later mEditorType.AssignLiteral("html"); mimeCType.AssignLiteral("text/html"); } // Flush out frame construction to make sure that the subframe's // presshell is set up if it needs to be. nsCOMPtr<nsIDocument> document = do_QueryInterface(doc); if (document) { document->FlushPendingNotifications(Flush_Frames); if (mMakeWholeDocumentEditable) { document->SetEditableFlag(true); nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(document); if (htmlDocument) { // Enable usage of the execCommand API htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode); } } } } bool needHTMLController = false; const char *classString = "@mozilla.org/editor/htmleditor;1"; if (mEditorType.EqualsLiteral("textmail")) { mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask | nsIPlaintextEditor::eEditorEnableWrapHackMask | nsIPlaintextEditor::eEditorMailMask; } else if (mEditorType.EqualsLiteral("text")) { mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask | nsIPlaintextEditor::eEditorEnableWrapHackMask; } else if (mEditorType.EqualsLiteral("htmlmail")) { if (mimeCType.EqualsLiteral("text/html")) { needHTMLController = true; mEditorFlags = nsIPlaintextEditor::eEditorMailMask; } else //set the flags back to textplain. mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask | nsIPlaintextEditor::eEditorEnableWrapHackMask; } else // Defaulted to html { needHTMLController = true; } if (mInteractive) { mEditorFlags |= nsIPlaintextEditor::eEditorAllowInteraction; } // make the UI state maintainer mStateMaintainer = new nsComposerCommandsUpdater(); // now init the state maintainer // This allows notification of error state // even if we don't create an editor rv = mStateMaintainer->Init(aWindow); NS_ENSURE_SUCCESS(rv, rv); if (mEditorStatus != eEditorCreationInProgress) { mStateMaintainer->NotifyDocumentCreated(); return NS_ERROR_FAILURE; } // Create editor and do other things // only if we haven't found some error above, nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); if (!mInteractive) { // Disable animation of images in this document: nsCOMPtr<nsIDOMWindowUtils> utils(do_GetInterface(aWindow)); NS_ENSURE_TRUE(utils, NS_ERROR_FAILURE); rv = utils->GetImageAnimationMode(&mImageAnimationMode); NS_ENSURE_SUCCESS(rv, rv); utils->SetImageAnimationMode(imgIContainer::kDontAnimMode); } // create and set editor nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(docShell, &rv); NS_ENSURE_SUCCESS(rv, rv); // Try to reuse an existing editor nsCOMPtr<nsIEditor> editor = do_QueryReferent(mExistingEditor); if (editor) { editor->PreDestroy(false); } else { editor = do_CreateInstance(classString, &rv); NS_ENSURE_SUCCESS(rv, rv); mExistingEditor = do_GetWeakReference(editor); } // set the editor on the docShell. The docShell now owns it. rv = editorDocShell->SetEditor(editor); NS_ENSURE_SUCCESS(rv, rv); // setup the HTML editor command controller if (needHTMLController) { // The third controller takes an nsIEditor as the context rv = SetupEditorCommandController("@mozilla.org/editor/htmleditorcontroller;1", aWindow, editor, &mHTMLCommandControllerId); NS_ENSURE_SUCCESS(rv, rv); } // Set mimetype on editor rv = editor->SetContentsMIMEType(mimeCType.get()); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIContentViewer> contentViewer; rv = docShell->GetContentViewer(getter_AddRefs(contentViewer)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE); nsCOMPtr<nsIDOMDocument> domDoc; rv = contentViewer->GetDOMDocument(getter_AddRefs(domDoc)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE); // Set up as a doc state listener // Important! We must have this to broadcast the "obs_documentCreated" message rv = editor->AddDocumentStateListener(mStateMaintainer); NS_ENSURE_SUCCESS(rv, rv); rv = editor->Init(domDoc, nullptr /* root content */, nullptr, mEditorFlags); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsISelection> selection; editor->GetSelection(getter_AddRefs(selection)); nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection); NS_ENSURE_TRUE(selPriv, NS_ERROR_FAILURE); rv = selPriv->AddSelectionListener(mStateMaintainer); NS_ENSURE_SUCCESS(rv, rv); // and as a transaction listener nsCOMPtr<nsITransactionManager> txnMgr; editor->GetTransactionManager(getter_AddRefs(txnMgr)); if (txnMgr) txnMgr->AddListener(mStateMaintainer); // Set context on all controllers to be the editor rv = SetEditorOnControllers(aWindow, editor); NS_ENSURE_SUCCESS(rv, rv); // Everything went fine! mEditorStatus = eEditorOK; // This will trigger documentCreation notification return editor->PostCreate(); }
nsresult nsEditingSession::ReattachToWindow(nsIDOMWindow* aWindow) { NS_ENSURE_TRUE(mDoneSetup, NS_OK); NS_ASSERTION(mStateMaintainer, "mStateMaintainer should exist."); // Imitate nsEditorDocShell::MakeEditable() to reattach the // old editor ot the window. nsresult rv; nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); mDocShell = do_GetWeakReference(docShell); // Disable plugins. if (!mInteractive) { rv = DisableJSAndPlugins(aWindow); NS_ENSURE_SUCCESS(rv, rv); } // Tells embedder that startup is in progress. mEditorStatus = eEditorCreationInProgress; // Adds back web progress listener. rv = PrepareForEditing(aWindow); NS_ENSURE_SUCCESS(rv, rv); // Setup the command controllers again. rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1", aWindow, static_cast<nsIEditingSession*>(this), &mBaseCommandControllerId); NS_ENSURE_SUCCESS(rv, rv); rv = SetupEditorCommandController("@mozilla.org/editor/editordocstatecontroller;1", aWindow, static_cast<nsIEditingSession*>(this), &mDocStateControllerId); NS_ENSURE_SUCCESS(rv, rv); if (mStateMaintainer) mStateMaintainer->Init(aWindow); // Get editor nsCOMPtr<nsIEditor> editor; rv = GetEditorForWindow(aWindow, getter_AddRefs(editor)); NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE); if (!mInteractive) { // Disable animation of images in this document: nsCOMPtr<nsIDOMWindowUtils> utils(do_GetInterface(aWindow)); NS_ENSURE_TRUE(utils, NS_ERROR_FAILURE); rv = utils->GetImageAnimationMode(&mImageAnimationMode); NS_ENSURE_SUCCESS(rv, rv); utils->SetImageAnimationMode(imgIContainer::kDontAnimMode); } // The third controller takes an nsIEditor as the context rv = SetupEditorCommandController("@mozilla.org/editor/htmleditorcontroller;1", aWindow, editor, &mHTMLCommandControllerId); NS_ENSURE_SUCCESS(rv, rv); // Set context on all controllers to be the editor rv = SetEditorOnControllers(aWindow, editor); NS_ENSURE_SUCCESS(rv, rv); #ifdef DEBUG { bool isEditable; rv = WindowIsEditable(aWindow, &isEditable); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(isEditable, "Window is not editable after reattaching editor."); } #endif // DEBUG return NS_OK; }
NS_IMETHODIMP nsEditingSession::MakeWindowEditable(nsIDOMWindow *aWindow, const char *aEditorType, bool aDoAfterUriLoad, bool aMakeWholeDocumentEditable, bool aInteractive) { mEditorType.Truncate(); mEditorFlags = 0; // disable plugins nsIDocShell *docShell = GetDocShellFromWindow(aWindow); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); mDocShell = do_GetWeakReference(docShell); mInteractive = aInteractive; mMakeWholeDocumentEditable = aMakeWholeDocumentEditable; nsresult rv; if (!mInteractive) { rv = DisableJSAndPlugins(aWindow); NS_ENSURE_SUCCESS(rv, rv); } // Always remove existing editor TearDownEditorOnWindow(aWindow); // Tells embedder that startup is in progress mEditorStatus = eEditorCreationInProgress; //temporary to set editor type here. we will need different classes soon. if (!aEditorType) aEditorType = DEFAULT_EDITOR_TYPE; mEditorType = aEditorType; // if all this does is setup listeners and I don't need listeners, // can't this step be ignored?? (based on aDoAfterURILoad) rv = PrepareForEditing(aWindow); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIEditorDocShell> editorDocShell; rv = GetEditorDocShellFromWindow(aWindow, getter_AddRefs(editorDocShell)); NS_ENSURE_SUCCESS(rv, rv); // set the flag on the docShell to say that it's editable rv = editorDocShell->MakeEditable(aDoAfterUriLoad); NS_ENSURE_SUCCESS(rv, rv); // Setup commands common to plaintext and html editors, // including the document creation observers // the first is an editing controller rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1", aWindow, static_cast<nsIEditingSession*>(this), &mBaseCommandControllerId); NS_ENSURE_SUCCESS(rv, rv); // The second is a controller to monitor doc state, // such as creation and "dirty flag" rv = SetupEditorCommandController("@mozilla.org/editor/editordocstatecontroller;1", aWindow, static_cast<nsIEditingSession*>(this), &mDocStateControllerId); NS_ENSURE_SUCCESS(rv, rv); // aDoAfterUriLoad can be false only when making an existing window editable if (!aDoAfterUriLoad) { rv = SetupEditorOnWindow(aWindow); // mEditorStatus is set to the error reason // Since this is used only when editing an existing page, // it IS ok to destroy current editor if (NS_FAILED(rv)) TearDownEditorOnWindow(aWindow); } return rv; }