LCOV - code coverage report
Current view: top level - editor/composer - nsEditingSession.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 510 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sw=2 et tw=78: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include <string.h>                     // for nullptr, strcmp
       8             : 
       9             : #include "imgIContainer.h"              // for imgIContainer, etc
      10             : #include "mozilla/FlushType.h"          // for FlushType::Frames
      11             : #include "mozilla/mozalloc.h"           // for operator new
      12             : #include "nsAString.h"
      13             : #include "nsComponentManagerUtils.h"    // for do_CreateInstance
      14             : #include "nsComposerCommandsUpdater.h"  // for nsComposerCommandsUpdater
      15             : #include "nsContentUtils.h"
      16             : #include "nsDebug.h"                    // for NS_ENSURE_SUCCESS, etc
      17             : #include "nsEditingSession.h"
      18             : #include "nsError.h"                    // for NS_ERROR_FAILURE, NS_OK, etc
      19             : #include "nsIChannel.h"                 // for nsIChannel
      20             : #include "nsICommandManager.h"          // for nsICommandManager
      21             : #include "nsIContentViewer.h"           // for nsIContentViewer
      22             : #include "nsIController.h"              // for nsIController
      23             : #include "nsIControllerContext.h"       // for nsIControllerContext
      24             : #include "nsIControllers.h"             // for nsIControllers
      25             : #include "nsID.h"                       // for NS_GET_IID, etc
      26             : #include "nsIDOMDocument.h"             // for nsIDOMDocument
      27             : #include "nsIDOMHTMLDocument.h"         // for nsIDOMHTMLDocument
      28             : #include "nsIDOMWindow.h"               // for nsIDOMWindow
      29             : #include "nsIDocShell.h"                // for nsIDocShell
      30             : #include "nsIDocument.h"                // for nsIDocument
      31             : #include "nsIDocumentStateListener.h"
      32             : #include "nsIEditor.h"                  // for nsIEditor
      33             : #include "nsIHTMLDocument.h"            // for nsIHTMLDocument, etc
      34             : #include "nsIInterfaceRequestorUtils.h"  // for do_GetInterface
      35             : #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
      36             : #include "nsIPresShell.h"               // for nsIPresShell
      37             : #include "nsIRefreshURI.h"              // for nsIRefreshURI
      38             : #include "nsIRequest.h"                 // for nsIRequest
      39             : #include "nsISelection.h"               // for nsISelection
      40             : #include "nsISelectionPrivate.h"        // for nsISelectionPrivate
      41             : #include "nsITimer.h"                   // for nsITimer, etc
      42             : #include "nsITransactionManager.h"      // for nsITransactionManager
      43             : #include "nsIWeakReference.h"           // for nsISupportsWeakReference, etc
      44             : #include "nsIWebNavigation.h"           // for nsIWebNavigation
      45             : #include "nsIWebProgress.h"             // for nsIWebProgress, etc
      46             : #include "nsLiteralString.h"            // for NS_LITERAL_STRING
      47             : #include "nsPICommandUpdater.h"         // for nsPICommandUpdater
      48             : #include "nsPIDOMWindow.h"              // for nsPIDOMWindow
      49             : #include "nsPresContext.h"              // for nsPresContext
      50             : #include "nsReadableUtils.h"            // for AppendUTF16toUTF8
      51             : #include "nsStringFwd.h"                // for nsString
      52             : #include "mozilla/dom/Selection.h"      // for AutoHideSelectionChanges
      53             : #include "nsFrameSelection.h"           // for nsFrameSelection
      54             : 
      55             : class nsISupports;
      56             : class nsIURI;
      57             : 
      58             : /*---------------------------------------------------------------------------
      59             : 
      60             :   nsEditingSession
      61             : 
      62             : ----------------------------------------------------------------------------*/
      63           0 : nsEditingSession::nsEditingSession()
      64             : : mDoneSetup(false)
      65             : , mCanCreateEditor(false)
      66             : , mInteractive(false)
      67             : , mMakeWholeDocumentEditable(true)
      68             : , mDisabledJSAndPlugins(false)
      69             : , mScriptsEnabled(true)
      70             : , mPluginsEnabled(true)
      71             : , mProgressListenerRegistered(false)
      72             : , mImageAnimationMode(0)
      73             : , mEditorFlags(0)
      74             : , mEditorStatus(eEditorOK)
      75             : , mBaseCommandControllerId(0)
      76             : , mDocStateControllerId(0)
      77           0 : , mHTMLCommandControllerId(0)
      78             : {
      79           0 : }
      80             : 
      81             : /*---------------------------------------------------------------------------
      82             : 
      83             :   ~nsEditingSession
      84             : 
      85             : ----------------------------------------------------------------------------*/
      86           0 : nsEditingSession::~nsEditingSession()
      87             : {
      88             :   // Must cancel previous timer?
      89           0 :   if (mLoadBlankDocTimer)
      90           0 :     mLoadBlankDocTimer->Cancel();
      91           0 : }
      92             : 
      93           0 : NS_IMPL_ISUPPORTS(nsEditingSession, nsIEditingSession, nsIWebProgressListener,
      94             :                   nsISupportsWeakReference)
      95             : 
      96             : /*---------------------------------------------------------------------------
      97             : 
      98             :   MakeWindowEditable
      99             : 
     100             :   aEditorType string, "html" "htmlsimple" "text" "textsimple"
     101             :   void makeWindowEditable(in nsIDOMWindow aWindow, in string aEditorType,
     102             :                           in boolean aDoAfterUriLoad,
     103             :                           in boolean aMakeWholeDocumentEditable,
     104             :                           in boolean aInteractive);
     105             : ----------------------------------------------------------------------------*/
     106             : #define DEFAULT_EDITOR_TYPE "html"
     107             : 
     108             : NS_IMETHODIMP
     109           0 : nsEditingSession::MakeWindowEditable(mozIDOMWindowProxy* aWindow,
     110             :                                      const char *aEditorType,
     111             :                                      bool aDoAfterUriLoad,
     112             :                                      bool aMakeWholeDocumentEditable,
     113             :                                      bool aInteractive)
     114             : {
     115           0 :   mEditorType.Truncate();
     116           0 :   mEditorFlags = 0;
     117             : 
     118           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
     119           0 :   auto* window = nsPIDOMWindowOuter::From(aWindow);
     120             : 
     121             :   // disable plugins
     122           0 :   nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
     123           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     124             : 
     125           0 :   mDocShell = do_GetWeakReference(docShell);
     126           0 :   mInteractive = aInteractive;
     127           0 :   mMakeWholeDocumentEditable = aMakeWholeDocumentEditable;
     128             : 
     129             :   nsresult rv;
     130           0 :   if (!mInteractive) {
     131           0 :     rv = DisableJSAndPlugins(aWindow);
     132           0 :     NS_ENSURE_SUCCESS(rv, rv);
     133             :   }
     134             : 
     135             :   // Always remove existing editor
     136           0 :   TearDownEditorOnWindow(aWindow);
     137             : 
     138             :   // Tells embedder that startup is in progress
     139           0 :   mEditorStatus = eEditorCreationInProgress;
     140             : 
     141             :   //temporary to set editor type here. we will need different classes soon.
     142           0 :   if (!aEditorType)
     143           0 :     aEditorType = DEFAULT_EDITOR_TYPE;
     144           0 :   mEditorType = aEditorType;
     145             : 
     146             :   // if all this does is setup listeners and I don't need listeners,
     147             :   // can't this step be ignored?? (based on aDoAfterURILoad)
     148           0 :   rv = PrepareForEditing(window);
     149           0 :   NS_ENSURE_SUCCESS(rv, rv);
     150             : 
     151             :   // set the flag on the docShell to say that it's editable
     152           0 :   rv = docShell->MakeEditable(aDoAfterUriLoad);
     153           0 :   NS_ENSURE_SUCCESS(rv, rv);
     154             : 
     155             :   // Setup commands common to plaintext and html editors,
     156             :   //  including the document creation observers
     157             :   // the first is an editing controller
     158           0 :   rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1",
     159             :                                     aWindow,
     160             :                                     static_cast<nsIEditingSession*>(this),
     161           0 :                                     &mBaseCommandControllerId);
     162           0 :   NS_ENSURE_SUCCESS(rv, rv);
     163             : 
     164             :   // The second is a controller to monitor doc state,
     165             :   // such as creation and "dirty flag"
     166           0 :   rv = SetupEditorCommandController("@mozilla.org/editor/editordocstatecontroller;1",
     167             :                                     aWindow,
     168             :                                     static_cast<nsIEditingSession*>(this),
     169           0 :                                     &mDocStateControllerId);
     170           0 :   NS_ENSURE_SUCCESS(rv, rv);
     171             : 
     172             :   // aDoAfterUriLoad can be false only when making an existing window editable
     173           0 :   if (!aDoAfterUriLoad) {
     174           0 :     rv = SetupEditorOnWindow(aWindow);
     175             : 
     176             :     // mEditorStatus is set to the error reason
     177             :     // Since this is used only when editing an existing page,
     178             :     //  it IS ok to destroy current editor
     179           0 :     if (NS_FAILED(rv)) {
     180           0 :       TearDownEditorOnWindow(aWindow);
     181             :     }
     182             :   }
     183           0 :   return rv;
     184             : }
     185             : 
     186             : NS_IMETHODIMP
     187           0 : nsEditingSession::DisableJSAndPlugins(mozIDOMWindowProxy* aWindow)
     188             : {
     189           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
     190           0 :   nsIDocShell *docShell = nsPIDOMWindowOuter::From(aWindow)->GetDocShell();
     191           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     192             : 
     193             :   bool tmp;
     194           0 :   nsresult rv = docShell->GetAllowJavascript(&tmp);
     195           0 :   NS_ENSURE_SUCCESS(rv, rv);
     196             : 
     197           0 :   mScriptsEnabled = tmp;
     198             : 
     199           0 :   rv = docShell->SetAllowJavascript(false);
     200           0 :   NS_ENSURE_SUCCESS(rv, rv);
     201             : 
     202             :   // Disable plugins in this document:
     203           0 :   mPluginsEnabled = docShell->PluginsAllowedInCurrentDoc();
     204             : 
     205           0 :   rv = docShell->SetAllowPlugins(false);
     206           0 :   NS_ENSURE_SUCCESS(rv, rv);
     207             : 
     208           0 :   mDisabledJSAndPlugins = true;
     209             : 
     210           0 :   return NS_OK;
     211             : }
     212             : 
     213             : NS_IMETHODIMP
     214           0 : nsEditingSession::RestoreJSAndPlugins(mozIDOMWindowProxy* aWindow)
     215             : {
     216           0 :   if (!mDisabledJSAndPlugins) {
     217           0 :     return NS_OK;
     218             :   }
     219             : 
     220           0 :   mDisabledJSAndPlugins = false;
     221             : 
     222           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
     223           0 :   nsIDocShell *docShell = nsPIDOMWindowOuter::From(aWindow)->GetDocShell();
     224           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     225             : 
     226           0 :   nsresult rv = docShell->SetAllowJavascript(mScriptsEnabled);
     227           0 :   NS_ENSURE_SUCCESS(rv, rv);
     228             : 
     229             :   // Disable plugins in this document:
     230           0 :   return docShell->SetAllowPlugins(mPluginsEnabled);
     231             : }
     232             : 
     233             : NS_IMETHODIMP
     234           0 : nsEditingSession::GetJsAndPluginsDisabled(bool *aResult)
     235             : {
     236           0 :   NS_ENSURE_ARG_POINTER(aResult);
     237           0 :   *aResult = mDisabledJSAndPlugins;
     238           0 :   return NS_OK;
     239             : }
     240             : 
     241             : /*---------------------------------------------------------------------------
     242             : 
     243             :   WindowIsEditable
     244             : 
     245             :   boolean windowIsEditable (in nsIDOMWindow aWindow);
     246             : ----------------------------------------------------------------------------*/
     247             : NS_IMETHODIMP
     248           0 : nsEditingSession::WindowIsEditable(mozIDOMWindowProxy* aWindow,
     249             :                                    bool *outIsEditable)
     250             : {
     251           0 :   NS_ENSURE_STATE(aWindow);
     252           0 :   nsCOMPtr<nsIDocShell> docShell = nsPIDOMWindowOuter::From(aWindow)->GetDocShell();
     253           0 :   NS_ENSURE_STATE(docShell);
     254             : 
     255           0 :   return docShell->GetEditable(outIsEditable);
     256             : }
     257             : 
     258             : 
     259             : // These are MIME types that are automatically parsed as "text/plain"
     260             : //   and thus we can edit them as plaintext
     261             : // Note: in older versions, we attempted to convert the mimetype of
     262             : //   the network channel for these and "text/xml" to "text/plain",
     263             : //   but further investigation reveals that strategy doesn't work
     264             : const char* const gSupportedTextTypes[] = {
     265             :   "text/plain",
     266             :   "text/css",
     267             :   "text/rdf",
     268             :   "text/xsl",
     269             :   "text/javascript",           // obsolete type
     270             :   "text/ecmascript",           // obsolete type
     271             :   "application/javascript",
     272             :   "application/ecmascript",
     273             :   "application/x-javascript",  // obsolete type
     274             :   "text/xul",                  // obsolete type
     275             :   "application/vnd.mozilla.xul+xml",
     276             :   nullptr   // IMPORTANT! Null must be at end
     277             : };
     278             : 
     279             : bool
     280           0 : IsSupportedTextType(const char* aMIMEType)
     281             : {
     282           0 :   NS_ENSURE_TRUE(aMIMEType, false);
     283             : 
     284           0 :   for (size_t i = 0; gSupportedTextTypes[i]; ++i) {
     285           0 :     if (!strcmp(gSupportedTextTypes[i], aMIMEType)) {
     286           0 :       return true;
     287             :     }
     288             :   }
     289             : 
     290           0 :   return false;
     291             : }
     292             : 
     293             : /*---------------------------------------------------------------------------
     294             : 
     295             :   SetupEditorOnWindow
     296             : 
     297             :   nsIEditor setupEditorOnWindow (in nsIDOMWindow aWindow);
     298             : ----------------------------------------------------------------------------*/
     299             : NS_IMETHODIMP
     300           0 : nsEditingSession::SetupEditorOnWindow(mozIDOMWindowProxy* aWindow)
     301             : {
     302           0 :   mDoneSetup = true;
     303             : 
     304           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
     305           0 :   auto* window = nsPIDOMWindowOuter::From(aWindow);
     306             : 
     307             :   nsresult rv;
     308             : 
     309             :   //MIME CHECKING
     310             :   //must get the content type
     311             :   // Note: the doc gets this from the network channel during StartPageLoad,
     312             :   //    so we don't have to get it from there ourselves
     313           0 :   nsAutoCString mimeCType;
     314             : 
     315             :   //then lets check the mime type
     316           0 :   if (nsCOMPtr<nsIDocument> doc = window->GetDoc()) {
     317           0 :     nsAutoString mimeType;
     318           0 :     if (NS_SUCCEEDED(doc->GetContentType(mimeType)))
     319           0 :       AppendUTF16toUTF8(mimeType, mimeCType);
     320             : 
     321           0 :     if (IsSupportedTextType(mimeCType.get())) {
     322           0 :       mEditorType.AssignLiteral("text");
     323           0 :       mimeCType = "text/plain";
     324           0 :     } else if (!mimeCType.EqualsLiteral("text/html") &&
     325           0 :                !mimeCType.EqualsLiteral("application/xhtml+xml")) {
     326             :       // Neither an acceptable text or html type.
     327           0 :       mEditorStatus = eEditorErrorCantEditMimeType;
     328             : 
     329             :       // Turn editor into HTML -- we will load blank page later
     330           0 :       mEditorType.AssignLiteral("html");
     331           0 :       mimeCType.AssignLiteral("text/html");
     332             :     }
     333             : 
     334             :     // Flush out frame construction to make sure that the subframe's
     335             :     // presshell is set up if it needs to be.
     336           0 :     nsCOMPtr<nsIDocument> document = do_QueryInterface(doc);
     337           0 :     if (document) {
     338           0 :       document->FlushPendingNotifications(mozilla::FlushType::Frames);
     339           0 :       if (mMakeWholeDocumentEditable) {
     340           0 :         document->SetEditableFlag(true);
     341           0 :         nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(document);
     342           0 :         if (htmlDocument) {
     343             :           // Enable usage of the execCommand API
     344           0 :           htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode);
     345             :         }
     346             :       }
     347             :     }
     348             :   }
     349           0 :   bool needHTMLController = false;
     350             : 
     351           0 :   const char *classString = "@mozilla.org/editor/htmleditor;1";
     352           0 :   if (mEditorType.EqualsLiteral("textmail")) {
     353           0 :     mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask |
     354             :                    nsIPlaintextEditor::eEditorEnableWrapHackMask |
     355             :                    nsIPlaintextEditor::eEditorMailMask;
     356           0 :   } else if (mEditorType.EqualsLiteral("text")) {
     357           0 :     mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask |
     358             :                    nsIPlaintextEditor::eEditorEnableWrapHackMask;
     359           0 :   } else if (mEditorType.EqualsLiteral("htmlmail")) {
     360           0 :     if (mimeCType.EqualsLiteral("text/html")) {
     361           0 :       needHTMLController = true;
     362           0 :       mEditorFlags = nsIPlaintextEditor::eEditorMailMask;
     363             :     } else {
     364             :       // Set the flags back to textplain.
     365           0 :       mEditorFlags = nsIPlaintextEditor::eEditorPlaintextMask |
     366             :                      nsIPlaintextEditor::eEditorEnableWrapHackMask;
     367             :     }
     368             :   } else {
     369             :     // Defaulted to html
     370           0 :     needHTMLController = true;
     371             :   }
     372             : 
     373           0 :   if (mInteractive) {
     374           0 :     mEditorFlags |= nsIPlaintextEditor::eEditorAllowInteraction;
     375             :   }
     376             : 
     377             :   // make the UI state maintainer
     378           0 :   mStateMaintainer = new nsComposerCommandsUpdater();
     379             : 
     380             :   // now init the state maintainer
     381             :   // This allows notification of error state
     382             :   //  even if we don't create an editor
     383           0 :   rv = mStateMaintainer->Init(window);
     384           0 :   NS_ENSURE_SUCCESS(rv, rv);
     385             : 
     386           0 :   if (mEditorStatus != eEditorCreationInProgress) {
     387           0 :     mStateMaintainer->NotifyDocumentCreated();
     388           0 :     return NS_ERROR_FAILURE;
     389             :   }
     390             : 
     391             :   // Create editor and do other things
     392             :   //  only if we haven't found some error above,
     393           0 :   nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
     394           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     395           0 :   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
     396           0 :   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
     397             : 
     398           0 :   if (!mInteractive) {
     399             :     // Disable animation of images in this document:
     400           0 :     nsPresContext* presContext = presShell->GetPresContext();
     401           0 :     NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
     402             : 
     403           0 :     mImageAnimationMode = presContext->ImageAnimationMode();
     404           0 :     presContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
     405             :   }
     406             : 
     407             :   // Hide selection changes during initialization, in order to hide this
     408             :   // from web pages.
     409           0 :   RefPtr<nsFrameSelection> fs = presShell->FrameSelection();
     410           0 :   NS_ENSURE_TRUE(fs, NS_ERROR_FAILURE);
     411           0 :   mozilla::dom::AutoHideSelectionChanges hideSelectionChanges(fs);
     412             : 
     413             :   // create and set editor
     414             :   // Try to reuse an existing editor
     415           0 :   nsCOMPtr<nsIEditor> editor = do_QueryReferent(mExistingEditor);
     416           0 :   if (editor) {
     417           0 :     editor->PreDestroy(false);
     418             :   } else {
     419           0 :     editor = do_CreateInstance(classString, &rv);
     420           0 :     NS_ENSURE_SUCCESS(rv, rv);
     421           0 :     mExistingEditor = do_GetWeakReference(editor);
     422             :   }
     423             :   // set the editor on the docShell. The docShell now owns it.
     424           0 :   rv = docShell->SetEditor(editor);
     425           0 :   NS_ENSURE_SUCCESS(rv, rv);
     426             : 
     427             :   // setup the HTML editor command controller
     428           0 :   if (needHTMLController) {
     429             :     // The third controller takes an nsIEditor as the context
     430           0 :     rv = SetupEditorCommandController("@mozilla.org/editor/htmleditorcontroller;1",
     431             :                                       aWindow, editor,
     432           0 :                                       &mHTMLCommandControllerId);
     433           0 :     NS_ENSURE_SUCCESS(rv, rv);
     434             :   }
     435             : 
     436             :   // Set mimetype on editor
     437           0 :   rv = editor->SetContentsMIMEType(mimeCType.get());
     438           0 :   NS_ENSURE_SUCCESS(rv, rv);
     439             : 
     440           0 :   nsCOMPtr<nsIContentViewer> contentViewer;
     441           0 :   rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
     442           0 :   NS_ENSURE_SUCCESS(rv, rv);
     443           0 :   NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE);
     444             : 
     445           0 :   nsCOMPtr<nsIDOMDocument> domDoc;
     446           0 :   rv = contentViewer->GetDOMDocument(getter_AddRefs(domDoc));
     447           0 :   NS_ENSURE_SUCCESS(rv, rv);
     448           0 :   NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
     449             : 
     450             :   // Set up as a doc state listener
     451             :   // Important! We must have this to broadcast the "obs_documentCreated" message
     452           0 :   rv = editor->AddDocumentStateListener(mStateMaintainer);
     453           0 :   NS_ENSURE_SUCCESS(rv, rv);
     454             : 
     455           0 :   rv = editor->Init(domDoc, nullptr /* root content */,
     456           0 :                     nullptr, mEditorFlags, EmptyString());
     457           0 :   NS_ENSURE_SUCCESS(rv, rv);
     458             : 
     459           0 :   nsCOMPtr<nsISelection> selection;
     460           0 :   editor->GetSelection(getter_AddRefs(selection));
     461           0 :   nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
     462           0 :   NS_ENSURE_TRUE(selPriv, NS_ERROR_FAILURE);
     463             : 
     464           0 :   rv = selPriv->AddSelectionListener(mStateMaintainer);
     465           0 :   NS_ENSURE_SUCCESS(rv, rv);
     466             : 
     467             :   // and as a transaction listener
     468           0 :   nsCOMPtr<nsITransactionManager> txnMgr;
     469           0 :   editor->GetTransactionManager(getter_AddRefs(txnMgr));
     470           0 :   if (txnMgr) {
     471           0 :     txnMgr->AddListener(mStateMaintainer);
     472             :   }
     473             : 
     474             :   // Set context on all controllers to be the editor
     475           0 :   rv = SetEditorOnControllers(aWindow, editor);
     476           0 :   NS_ENSURE_SUCCESS(rv, rv);
     477             : 
     478             :   // Everything went fine!
     479           0 :   mEditorStatus = eEditorOK;
     480             : 
     481             :   // This will trigger documentCreation notification
     482           0 :   return editor->PostCreate();
     483             : }
     484             : 
     485             : // Removes all listeners and controllers from aWindow and aEditor.
     486             : void
     487           0 : nsEditingSession::RemoveListenersAndControllers(nsPIDOMWindowOuter* aWindow,
     488             :                                                 nsIEditor *aEditor)
     489             : {
     490           0 :   if (!mStateMaintainer || !aEditor) {
     491           0 :     return;
     492             :   }
     493             : 
     494             :   // Remove all the listeners
     495           0 :   nsCOMPtr<nsISelection> selection;
     496           0 :   aEditor->GetSelection(getter_AddRefs(selection));
     497           0 :   nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
     498           0 :   if (selPriv)
     499           0 :     selPriv->RemoveSelectionListener(mStateMaintainer);
     500             : 
     501           0 :   aEditor->RemoveDocumentStateListener(mStateMaintainer);
     502             : 
     503           0 :   nsCOMPtr<nsITransactionManager> txnMgr;
     504           0 :   aEditor->GetTransactionManager(getter_AddRefs(txnMgr));
     505           0 :   if (txnMgr) {
     506           0 :     txnMgr->RemoveListener(mStateMaintainer);
     507             :   }
     508             : 
     509             :   // Remove editor controllers from the window now that we're not
     510             :   // editing in that window any more.
     511           0 :   RemoveEditorControllers(aWindow);
     512             : }
     513             : 
     514             : /*---------------------------------------------------------------------------
     515             : 
     516             :   TearDownEditorOnWindow
     517             : 
     518             :   void tearDownEditorOnWindow (in nsIDOMWindow aWindow);
     519             : ----------------------------------------------------------------------------*/
     520             : NS_IMETHODIMP
     521           0 : nsEditingSession::TearDownEditorOnWindow(mozIDOMWindowProxy *aWindow)
     522             : {
     523           0 :   if (!mDoneSetup) {
     524           0 :     return NS_OK;
     525             :   }
     526             : 
     527           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_NULL_POINTER);
     528             : 
     529             :   nsresult rv;
     530             : 
     531             :   // Kill any existing reload timer
     532           0 :   if (mLoadBlankDocTimer) {
     533           0 :     mLoadBlankDocTimer->Cancel();
     534           0 :     mLoadBlankDocTimer = nullptr;
     535             :   }
     536             : 
     537           0 :   mDoneSetup = false;
     538             : 
     539             :   // Check if we're turning off editing (from contentEditable or designMode).
     540           0 :   auto* window = nsPIDOMWindowOuter::From(aWindow);
     541             : 
     542           0 :   nsCOMPtr<nsIDocument> doc = window->GetDoc();
     543           0 :   nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
     544           0 :   bool stopEditing = htmlDoc && htmlDoc->IsEditingOn();
     545           0 :   if (stopEditing) {
     546           0 :     RemoveWebProgressListener(window);
     547             :   }
     548             : 
     549           0 :   nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
     550           0 :   NS_ENSURE_STATE(docShell);
     551             : 
     552           0 :   nsCOMPtr<nsIEditor> editor;
     553           0 :   rv = docShell->GetEditor(getter_AddRefs(editor));
     554           0 :   NS_ENSURE_SUCCESS(rv, rv);
     555             : 
     556           0 :   if (stopEditing) {
     557           0 :     htmlDoc->TearingDownEditor(editor);
     558             :   }
     559             : 
     560           0 :   if (mStateMaintainer && editor) {
     561             :     // Null out the editor on the controllers first to prevent their weak
     562             :     // references from pointing to a destroyed editor.
     563           0 :     SetEditorOnControllers(aWindow, nullptr);
     564             :   }
     565             : 
     566             :   // Null out the editor on the docShell to trigger PreDestroy which
     567             :   // needs to happen before document state listeners are removed below.
     568           0 :   docShell->SetEditor(nullptr);
     569             : 
     570           0 :   RemoveListenersAndControllers(window, editor);
     571             : 
     572           0 :   if (stopEditing) {
     573             :     // Make things the way they were before we started editing.
     574           0 :     RestoreJSAndPlugins(aWindow);
     575           0 :     RestoreAnimationMode(window);
     576             : 
     577           0 :     if (mMakeWholeDocumentEditable) {
     578           0 :       doc->SetEditableFlag(false);
     579           0 :       nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(doc);
     580           0 :       if (htmlDocument) {
     581           0 :         htmlDocument->SetEditingState(nsIHTMLDocument::eOff);
     582             :       }
     583             :     }
     584             :   }
     585             : 
     586           0 :   return rv;
     587             : }
     588             : 
     589             : /*---------------------------------------------------------------------------
     590             : 
     591             :   GetEditorForFrame
     592             : 
     593             :   nsIEditor getEditorForFrame (in nsIDOMWindow aWindow);
     594             : ----------------------------------------------------------------------------*/
     595             : NS_IMETHODIMP
     596           0 : nsEditingSession::GetEditorForWindow(mozIDOMWindowProxy* aWindow,
     597             :                                      nsIEditor **outEditor)
     598             : {
     599           0 :   NS_ENSURE_STATE(aWindow);
     600           0 :   nsCOMPtr<nsIDocShell> docShell = nsPIDOMWindowOuter::From(aWindow)->GetDocShell();
     601           0 :   NS_ENSURE_STATE(docShell);
     602             : 
     603           0 :   return docShell->GetEditor(outEditor);
     604             : }
     605             : 
     606             : /*---------------------------------------------------------------------------
     607             : 
     608             :   OnStateChange
     609             : 
     610             : ----------------------------------------------------------------------------*/
     611             : NS_IMETHODIMP
     612           0 : nsEditingSession::OnStateChange(nsIWebProgress *aWebProgress,
     613             :                                 nsIRequest *aRequest,
     614             :                                 uint32_t aStateFlags, nsresult aStatus)
     615             : {
     616             : 
     617             : #ifdef NOISY_DOC_LOADING
     618             :   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
     619             :   if (channel) {
     620             :     nsAutoCString contentType;
     621             :     channel->GetContentType(contentType);
     622             :     if (!contentType.IsEmpty()) {
     623             :       printf(" ++++++ MIMETYPE = %s\n", contentType.get());
     624             :     }
     625             :   }
     626             : #endif
     627             : 
     628             :   //
     629             :   // A Request has started...
     630             :   //
     631           0 :   if (aStateFlags & nsIWebProgressListener::STATE_START) {
     632             : #ifdef NOISY_DOC_LOADING
     633             :     {
     634             :       nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
     635             :       if (channel) {
     636             :         nsCOMPtr<nsIURI> uri;
     637             :         channel->GetURI(getter_AddRefs(uri));
     638             :         if (uri) {
     639             :           nsXPIDLCString spec;
     640             :           uri->GetSpec(spec);
     641             :           printf(" **** STATE_START: CHANNEL URI=%s, flags=%x\n",
     642             :                  spec.get(), aStateFlags);
     643             :         }
     644             :       } else {
     645             :         printf("    STATE_START: NO CHANNEL flags=%x\n", aStateFlags);
     646             :       }
     647             :     }
     648             : #endif
     649             :     // Page level notification...
     650           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) {
     651           0 :       nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
     652           0 :       StartPageLoad(channel);
     653             : #ifdef NOISY_DOC_LOADING
     654             :       printf("STATE_START & STATE_IS_NETWORK flags=%x\n", aStateFlags);
     655             : #endif
     656             :     }
     657             : 
     658             :     // Document level notification...
     659           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT &&
     660           0 :         !(aStateFlags & nsIWebProgressListener::STATE_RESTORING)) {
     661             : #ifdef NOISY_DOC_LOADING
     662             :       printf("STATE_START & STATE_IS_DOCUMENT flags=%x\n", aStateFlags);
     663             : #endif
     664             : 
     665             :       bool progressIsForTargetDocument =
     666           0 :         IsProgressForTargetDocument(aWebProgress);
     667             : 
     668           0 :       if (progressIsForTargetDocument) {
     669           0 :         nsCOMPtr<mozIDOMWindowProxy> window;
     670           0 :         aWebProgress->GetDOMWindow(getter_AddRefs(window));
     671             : 
     672           0 :         auto* piWindow = nsPIDOMWindowOuter::From(window);
     673           0 :         nsCOMPtr<nsIDocument> doc = piWindow->GetDoc();
     674             : 
     675           0 :         nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
     676             : 
     677           0 :         if (htmlDoc && htmlDoc->IsWriting()) {
     678           0 :           nsCOMPtr<nsIDOMHTMLDocument> htmlDomDoc = do_QueryInterface(doc);
     679           0 :           nsAutoString designMode;
     680           0 :           htmlDomDoc->GetDesignMode(designMode);
     681             : 
     682           0 :           if (designMode.EqualsLiteral("on")) {
     683             :             // This notification is for data coming in through
     684             :             // document.open/write/close(), ignore it.
     685             : 
     686           0 :             return NS_OK;
     687             :           }
     688             :         }
     689             : 
     690           0 :         mCanCreateEditor = true;
     691           0 :         StartDocumentLoad(aWebProgress, progressIsForTargetDocument);
     692             :       }
     693             :     }
     694             :   }
     695             :   //
     696             :   // A Request is being processed
     697             :   //
     698           0 :   else if (aStateFlags & nsIWebProgressListener::STATE_TRANSFERRING) {
     699           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT) {
     700             :       // document transfer started
     701             :     }
     702             :   }
     703             :   //
     704             :   // Got a redirection
     705             :   //
     706           0 :   else if (aStateFlags & nsIWebProgressListener::STATE_REDIRECTING) {
     707           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT) {
     708             :       // got a redirect
     709             :     }
     710             :   }
     711             :   //
     712             :   // A network or document Request has finished...
     713             :   //
     714           0 :   else if (aStateFlags & nsIWebProgressListener::STATE_STOP) {
     715             : #ifdef NOISY_DOC_LOADING
     716             :     {
     717             :       nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
     718             :       if (channel) {
     719             :         nsCOMPtr<nsIURI> uri;
     720             :         channel->GetURI(getter_AddRefs(uri));
     721             :         if (uri) {
     722             :           nsXPIDLCString spec;
     723             :           uri->GetSpec(spec);
     724             :           printf(" **** STATE_STOP: CHANNEL URI=%s, flags=%x\n",
     725             :                  spec.get(), aStateFlags);
     726             :         }
     727             :       } else {
     728             :         printf("     STATE_STOP: NO CHANNEL  flags=%x\n", aStateFlags);
     729             :       }
     730             :     }
     731             : #endif
     732             : 
     733             :     // Document level notification...
     734           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT) {
     735           0 :       nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     736           0 :       EndDocumentLoad(aWebProgress, channel, aStatus,
     737           0 :                       IsProgressForTargetDocument(aWebProgress));
     738             : #ifdef NOISY_DOC_LOADING
     739             :       printf("STATE_STOP & STATE_IS_DOCUMENT flags=%x\n", aStateFlags);
     740             : #endif
     741             :     }
     742             : 
     743             :     // Page level notification...
     744           0 :     if (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) {
     745           0 :       nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     746           0 :       (void)EndPageLoad(aWebProgress, channel, aStatus);
     747             : #ifdef NOISY_DOC_LOADING
     748             :       printf("STATE_STOP & STATE_IS_NETWORK flags=%x\n", aStateFlags);
     749             : #endif
     750             :     }
     751             :   }
     752             : 
     753           0 :   return NS_OK;
     754             : }
     755             : 
     756             : /*---------------------------------------------------------------------------
     757             : 
     758             :   OnProgressChange
     759             : 
     760             : ----------------------------------------------------------------------------*/
     761             : NS_IMETHODIMP
     762           0 : nsEditingSession::OnProgressChange(nsIWebProgress *aWebProgress,
     763             :                                    nsIRequest *aRequest,
     764             :                                    int32_t aCurSelfProgress,
     765             :                                    int32_t aMaxSelfProgress,
     766             :                                    int32_t aCurTotalProgress,
     767             :                                    int32_t aMaxTotalProgress)
     768             : {
     769           0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     770           0 :     return NS_OK;
     771             : }
     772             : 
     773             : /*---------------------------------------------------------------------------
     774             : 
     775             :   OnLocationChange
     776             : 
     777             : ----------------------------------------------------------------------------*/
     778             : NS_IMETHODIMP
     779           0 : nsEditingSession::OnLocationChange(nsIWebProgress *aWebProgress,
     780             :                                    nsIRequest *aRequest, nsIURI *aURI,
     781             :                                    uint32_t aFlags)
     782             : {
     783           0 :   nsCOMPtr<mozIDOMWindowProxy> domWindow;
     784           0 :   nsresult rv = aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
     785           0 :   NS_ENSURE_SUCCESS(rv, rv);
     786             : 
     787           0 :   auto* piWindow = nsPIDOMWindowOuter::From(domWindow);
     788             : 
     789           0 :   nsCOMPtr<nsIDocument> doc = piWindow->GetDoc();
     790           0 :   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
     791             : 
     792           0 :   doc->SetDocumentURI(aURI);
     793             : 
     794             :   // Notify the location-changed observer that
     795             :   //  the document URL has changed
     796           0 :   nsIDocShell *docShell = piWindow->GetDocShell();
     797           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
     798             : 
     799           0 :   nsCOMPtr<nsICommandManager> commandManager = docShell->GetCommandManager();
     800             :   nsCOMPtr<nsPICommandUpdater> commandUpdater =
     801           0 :                                   do_QueryInterface(commandManager);
     802           0 :   NS_ENSURE_TRUE(commandUpdater, NS_ERROR_FAILURE);
     803             : 
     804           0 :   return commandUpdater->CommandStatusChanged("obs_documentLocationChanged");
     805             : }
     806             : 
     807             : /*---------------------------------------------------------------------------
     808             : 
     809             :   OnStatusChange
     810             : 
     811             : ----------------------------------------------------------------------------*/
     812             : NS_IMETHODIMP
     813           0 : nsEditingSession::OnStatusChange(nsIWebProgress *aWebProgress,
     814             :                                  nsIRequest *aRequest,
     815             :                                  nsresult aStatus,
     816             :                                  const char16_t *aMessage)
     817             : {
     818           0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     819           0 :     return NS_OK;
     820             : }
     821             : 
     822             : /*---------------------------------------------------------------------------
     823             : 
     824             :   OnSecurityChange
     825             : 
     826             : ----------------------------------------------------------------------------*/
     827             : NS_IMETHODIMP
     828           0 : nsEditingSession::OnSecurityChange(nsIWebProgress *aWebProgress,
     829             :                                    nsIRequest *aRequest, uint32_t state)
     830             : {
     831           0 :     NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     832           0 :     return NS_OK;
     833             : }
     834             : 
     835             : 
     836             : /*---------------------------------------------------------------------------
     837             : 
     838             :   IsProgressForTargetDocument
     839             : 
     840             :   Check that this notification is for our document.
     841             : ----------------------------------------------------------------------------*/
     842             : 
     843             : bool
     844           0 : nsEditingSession::IsProgressForTargetDocument(nsIWebProgress *aWebProgress)
     845             : {
     846           0 :   nsCOMPtr<nsIWebProgress> editedWebProgress = do_QueryReferent(mDocShell);
     847           0 :   return editedWebProgress == aWebProgress;
     848             : }
     849             : 
     850             : 
     851             : /*---------------------------------------------------------------------------
     852             : 
     853             :   GetEditorStatus
     854             : 
     855             :   Called during GetCommandStateParams("obs_documentCreated"...)
     856             :   to determine if editor was created and document
     857             :   was loaded successfully
     858             : ----------------------------------------------------------------------------*/
     859             : NS_IMETHODIMP
     860           0 : nsEditingSession::GetEditorStatus(uint32_t *aStatus)
     861             : {
     862           0 :   NS_ENSURE_ARG_POINTER(aStatus);
     863           0 :   *aStatus = mEditorStatus;
     864           0 :   return NS_OK;
     865             : }
     866             : 
     867             : /*---------------------------------------------------------------------------
     868             : 
     869             :   StartDocumentLoad
     870             : 
     871             :   Called on start of load in a single frame
     872             : ----------------------------------------------------------------------------*/
     873             : nsresult
     874           0 : nsEditingSession::StartDocumentLoad(nsIWebProgress *aWebProgress,
     875             :                                     bool aIsToBeMadeEditable)
     876             : {
     877             : #ifdef NOISY_DOC_LOADING
     878             :   printf("======= StartDocumentLoad ========\n");
     879             : #endif
     880             : 
     881           0 :   NS_ENSURE_ARG_POINTER(aWebProgress);
     882             : 
     883           0 :   if (aIsToBeMadeEditable) {
     884           0 :     mEditorStatus = eEditorCreationInProgress;
     885             :   }
     886             : 
     887           0 :   return NS_OK;
     888             : }
     889             : 
     890             : /*---------------------------------------------------------------------------
     891             : 
     892             :   EndDocumentLoad
     893             : 
     894             :   Called on end of load in a single frame
     895             : ----------------------------------------------------------------------------*/
     896             : nsresult
     897           0 : nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress,
     898             :                                   nsIChannel* aChannel, nsresult aStatus,
     899             :                                   bool aIsToBeMadeEditable)
     900             : {
     901           0 :   NS_ENSURE_ARG_POINTER(aWebProgress);
     902             : 
     903             : #ifdef NOISY_DOC_LOADING
     904             :   printf("======= EndDocumentLoad ========\n");
     905             :   printf("with status %d, ", aStatus);
     906             :   nsCOMPtr<nsIURI> uri;
     907             :   nsXPIDLCString spec;
     908             :   if (NS_SUCCEEDED(aChannel->GetURI(getter_AddRefs(uri)))) {
     909             :     uri->GetSpec(spec);
     910             :     printf(" uri %s\n", spec.get());
     911             :   }
     912             : #endif
     913             : 
     914             :   // We want to call the base class EndDocumentLoad,
     915             :   // but avoid some of the stuff
     916             :   // that nsDocShell does (need to refactor).
     917             : 
     918             :   // OK, time to make an editor on this document
     919           0 :   nsCOMPtr<mozIDOMWindowProxy> domWindow;
     920           0 :   aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
     921           0 :   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
     922             : 
     923             :   // Set the error state -- we will create an editor
     924             :   // anyway and load empty doc later
     925           0 :   if (aIsToBeMadeEditable && aStatus == NS_ERROR_FILE_NOT_FOUND) {
     926           0 :     mEditorStatus = eEditorErrorFileNotFound;
     927             :   }
     928             : 
     929           0 :   nsIDocShell *docShell = nsPIDOMWindowOuter::From(domWindow)->GetDocShell();
     930           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);       // better error handling?
     931             : 
     932             :   // cancel refresh from meta tags
     933             :   // we need to make sure that all pages in editor (whether editable or not)
     934             :   // can't refresh contents being edited
     935           0 :   nsCOMPtr<nsIRefreshURI> refreshURI = do_QueryInterface(docShell);
     936           0 :   if (refreshURI) {
     937           0 :     refreshURI->CancelRefreshURITimers();
     938             :   }
     939             : 
     940           0 :   nsresult rv = NS_OK;
     941             : 
     942             :   // did someone set the flag to make this shell editable?
     943           0 :   if (aIsToBeMadeEditable && mCanCreateEditor) {
     944             :     bool    makeEditable;
     945           0 :     docShell->GetEditable(&makeEditable);
     946             : 
     947           0 :     if (makeEditable) {
     948             :       // To keep pre Gecko 1.9 behavior, setup editor always when
     949             :       // mMakeWholeDocumentEditable.
     950           0 :       bool needsSetup = false;
     951           0 :       if (mMakeWholeDocumentEditable) {
     952           0 :         needsSetup = true;
     953             :       } else {
     954             :         // do we already have an editor here?
     955           0 :         nsCOMPtr<nsIEditor> editor;
     956           0 :         rv = docShell->GetEditor(getter_AddRefs(editor));
     957           0 :         NS_ENSURE_SUCCESS(rv, rv);
     958             : 
     959           0 :         needsSetup = !editor;
     960             :       }
     961             : 
     962           0 :       if (needsSetup) {
     963           0 :         mCanCreateEditor = false;
     964           0 :         rv = SetupEditorOnWindow(domWindow);
     965           0 :         if (NS_FAILED(rv)) {
     966             :           // If we had an error, setup timer to load a blank page later
     967           0 :           if (mLoadBlankDocTimer) {
     968             :             // Must cancel previous timer?
     969           0 :             mLoadBlankDocTimer->Cancel();
     970           0 :             mLoadBlankDocTimer = nullptr;
     971             :           }
     972             : 
     973           0 :           mLoadBlankDocTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
     974           0 :           NS_ENSURE_SUCCESS(rv, rv);
     975             : 
     976           0 :           mEditorStatus = eEditorCreationInProgress;
     977           0 :           mLoadBlankDocTimer->InitWithNamedFuncCallback(
     978             :             nsEditingSession::TimerCallback,
     979           0 :             static_cast<void*>(mDocShell.get()),
     980             :             10,
     981             :             nsITimer::TYPE_ONE_SHOT,
     982           0 :             "nsEditingSession::EndDocumentLoad");
     983             :         }
     984             :       }
     985             :     }
     986             :   }
     987           0 :   return rv;
     988             : }
     989             : 
     990             : 
     991             : void
     992           0 : nsEditingSession::TimerCallback(nsITimer* aTimer, void* aClosure)
     993             : {
     994           0 :   nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(static_cast<nsIWeakReference*> (aClosure));
     995           0 :   if (docShell) {
     996           0 :     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
     997           0 :     if (webNav) {
     998           0 :       webNav->LoadURI(u"about:blank", 0, nullptr, nullptr, nullptr,
     999           0 :                       nsContentUtils::GetSystemPrincipal());
    1000             :     }
    1001             :   }
    1002           0 : }
    1003             : 
    1004             : /*---------------------------------------------------------------------------
    1005             : 
    1006             :   StartPageLoad
    1007             : 
    1008             :   Called on start load of the entire page (incl. subframes)
    1009             : ----------------------------------------------------------------------------*/
    1010             : nsresult
    1011           0 : nsEditingSession::StartPageLoad(nsIChannel *aChannel)
    1012             : {
    1013             : #ifdef NOISY_DOC_LOADING
    1014             :   printf("======= StartPageLoad ========\n");
    1015             : #endif
    1016           0 :   return NS_OK;
    1017             : }
    1018             : 
    1019             : /*---------------------------------------------------------------------------
    1020             : 
    1021             :   EndPageLoad
    1022             : 
    1023             :   Called on end load of the entire page (incl. subframes)
    1024             : ----------------------------------------------------------------------------*/
    1025             : nsresult
    1026           0 : nsEditingSession::EndPageLoad(nsIWebProgress *aWebProgress,
    1027             :                               nsIChannel* aChannel, nsresult aStatus)
    1028             : {
    1029             : #ifdef NOISY_DOC_LOADING
    1030             :   printf("======= EndPageLoad ========\n");
    1031             :   printf("  with status %d, ", aStatus);
    1032             :   nsCOMPtr<nsIURI> uri;
    1033             :   nsXPIDLCString spec;
    1034             :   if (NS_SUCCEEDED(aChannel->GetURI(getter_AddRefs(uri)))) {
    1035             :     uri->GetSpec(spec);
    1036             :     printf("uri %s\n", spec.get());
    1037             :   }
    1038             : 
    1039             :   nsAutoCString contentType;
    1040             :   aChannel->GetContentType(contentType);
    1041             :   if (!contentType.IsEmpty()) {
    1042             :     printf("   flags = %d, status = %d, MIMETYPE = %s\n",
    1043             :                mEditorFlags, mEditorStatus, contentType.get());
    1044             :   }
    1045             : #endif
    1046             : 
    1047             :   // Set the error state -- we will create an editor anyway
    1048             :   // and load empty doc later
    1049           0 :   if (aStatus == NS_ERROR_FILE_NOT_FOUND) {
    1050           0 :     mEditorStatus = eEditorErrorFileNotFound;
    1051             :   }
    1052             : 
    1053           0 :   nsCOMPtr<mozIDOMWindowProxy> domWindow;
    1054           0 :   aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
    1055             : 
    1056             :   nsIDocShell *docShell =
    1057           0 :     domWindow ? nsPIDOMWindowOuter::From(domWindow)->GetDocShell() : nullptr;
    1058           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
    1059             : 
    1060             :   // cancel refresh from meta tags
    1061             :   // we need to make sure that all pages in editor (whether editable or not)
    1062             :   // can't refresh contents being edited
    1063           0 :   nsCOMPtr<nsIRefreshURI> refreshURI = do_QueryInterface(docShell);
    1064           0 :   if (refreshURI) {
    1065           0 :     refreshURI->CancelRefreshURITimers();
    1066             :   }
    1067             : 
    1068             : #if 0
    1069             :   // Shouldn't we do this when we want to edit sub-frames?
    1070             :   return MakeWindowEditable(domWindow, "html", false, mInteractive);
    1071             : #else
    1072           0 :   return NS_OK;
    1073             : #endif
    1074             : }
    1075             : 
    1076             : /*---------------------------------------------------------------------------
    1077             : 
    1078             :   PrepareForEditing
    1079             : 
    1080             :   Set up this editing session for one or more editors
    1081             : ----------------------------------------------------------------------------*/
    1082             : nsresult
    1083           0 : nsEditingSession::PrepareForEditing(nsPIDOMWindowOuter* aWindow)
    1084             : {
    1085           0 :   if (mProgressListenerRegistered) {
    1086           0 :     return NS_OK;
    1087             :   }
    1088             : 
    1089           0 :   nsIDocShell *docShell = aWindow ? aWindow->GetDocShell() : nullptr;
    1090             : 
    1091             :   // register callback
    1092           0 :   nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
    1093           0 :   NS_ENSURE_TRUE(webProgress, NS_ERROR_FAILURE);
    1094             : 
    1095             :   nsresult rv =
    1096           0 :     webProgress->AddProgressListener(this,
    1097             :                                      (nsIWebProgress::NOTIFY_STATE_NETWORK  |
    1098             :                                       nsIWebProgress::NOTIFY_STATE_DOCUMENT |
    1099           0 :                                       nsIWebProgress::NOTIFY_LOCATION));
    1100             : 
    1101           0 :   mProgressListenerRegistered = NS_SUCCEEDED(rv);
    1102             : 
    1103           0 :   return rv;
    1104             : }
    1105             : 
    1106             : /*---------------------------------------------------------------------------
    1107             : 
    1108             :   SetupEditorCommandController
    1109             : 
    1110             :   Create a command controller, append to controllers,
    1111             :   get and return the controller ID, and set the context
    1112             : ----------------------------------------------------------------------------*/
    1113             : nsresult
    1114           0 : nsEditingSession::SetupEditorCommandController(
    1115             :                                   const char *aControllerClassName,
    1116             :                                   mozIDOMWindowProxy *aWindow,
    1117             :                                   nsISupports *aContext,
    1118             :                                   uint32_t *aControllerId)
    1119             : {
    1120           0 :   NS_ENSURE_ARG_POINTER(aControllerClassName);
    1121           0 :   NS_ENSURE_ARG_POINTER(aWindow);
    1122           0 :   NS_ENSURE_ARG_POINTER(aContext);
    1123           0 :   NS_ENSURE_ARG_POINTER(aControllerId);
    1124             : 
    1125           0 :   auto* piWindow = nsPIDOMWindowOuter::From(aWindow);
    1126           0 :   MOZ_ASSERT(piWindow);
    1127             : 
    1128           0 :   nsCOMPtr<nsIControllers> controllers;
    1129           0 :   nsresult rv = piWindow->GetControllers(getter_AddRefs(controllers));
    1130           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1131             : 
    1132             :   // We only have to create each singleton controller once
    1133             :   // We know this has happened once we have a controllerId value
    1134           0 :   if (!*aControllerId) {
    1135           0 :     nsCOMPtr<nsIController> controller;
    1136           0 :     controller = do_CreateInstance(aControllerClassName, &rv);
    1137           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1138             : 
    1139             :     // We must insert at head of the list to be sure our
    1140             :     //   controller is found before other implementations
    1141             :     //   (e.g., not-implemented versions by browser)
    1142           0 :     rv = controllers->InsertControllerAt(0, controller);
    1143           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1144             : 
    1145             :     // Remember the ID for the controller
    1146           0 :     rv = controllers->GetControllerId(controller, aControllerId);
    1147           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1148             :   }
    1149             : 
    1150             :   // Set the context
    1151           0 :   return SetContextOnControllerById(controllers, aContext, *aControllerId);
    1152             : }
    1153             : 
    1154             : /*---------------------------------------------------------------------------
    1155             : 
    1156             :   SetEditorOnControllers
    1157             : 
    1158             :   Set the editor on the controller(s) for this window
    1159             : ----------------------------------------------------------------------------*/
    1160             : NS_IMETHODIMP
    1161           0 : nsEditingSession::SetEditorOnControllers(mozIDOMWindowProxy* aWindow,
    1162             :                                          nsIEditor* aEditor)
    1163             : {
    1164           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_NULL_POINTER);
    1165             : 
    1166           0 :   auto* piWindow = nsPIDOMWindowOuter::From(aWindow);
    1167             : 
    1168           0 :   nsCOMPtr<nsIControllers> controllers;
    1169           0 :   nsresult rv = piWindow->GetControllers(getter_AddRefs(controllers));
    1170           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1171             : 
    1172           0 :   nsCOMPtr<nsISupports> editorAsISupports = do_QueryInterface(aEditor);
    1173           0 :   if (mBaseCommandControllerId) {
    1174           0 :     rv = SetContextOnControllerById(controllers, editorAsISupports,
    1175           0 :                                     mBaseCommandControllerId);
    1176           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1177             :   }
    1178             : 
    1179           0 :   if (mDocStateControllerId) {
    1180           0 :     rv = SetContextOnControllerById(controllers, editorAsISupports,
    1181           0 :                                     mDocStateControllerId);
    1182           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1183             :   }
    1184             : 
    1185           0 :   if (mHTMLCommandControllerId) {
    1186           0 :     rv = SetContextOnControllerById(controllers, editorAsISupports,
    1187           0 :                                     mHTMLCommandControllerId);
    1188             :   }
    1189             : 
    1190           0 :   return rv;
    1191             : }
    1192             : 
    1193             : nsresult
    1194           0 : nsEditingSession::SetContextOnControllerById(nsIControllers* aControllers,
    1195             :                                              nsISupports* aContext,
    1196             :                                              uint32_t aID)
    1197             : {
    1198           0 :   NS_ENSURE_ARG_POINTER(aControllers);
    1199             : 
    1200             :   // aContext can be null (when destroying editor)
    1201           0 :   nsCOMPtr<nsIController> controller;
    1202           0 :   aControllers->GetControllerById(aID, getter_AddRefs(controller));
    1203             : 
    1204             :   // ok with nil controller
    1205             :   nsCOMPtr<nsIControllerContext> editorController =
    1206           0 :                                        do_QueryInterface(controller);
    1207           0 :   NS_ENSURE_TRUE(editorController, NS_ERROR_FAILURE);
    1208             : 
    1209           0 :   return editorController->SetCommandContext(aContext);
    1210             : }
    1211             : 
    1212             : void
    1213           0 : nsEditingSession::RemoveEditorControllers(nsPIDOMWindowOuter* aWindow)
    1214             : {
    1215             :   // Remove editor controllers from the aWindow, call when we're
    1216             :   // tearing down/detaching editor.
    1217             : 
    1218           0 :   nsCOMPtr<nsIControllers> controllers;
    1219           0 :   if (aWindow) {
    1220           0 :     aWindow->GetControllers(getter_AddRefs(controllers));
    1221             :   }
    1222             : 
    1223           0 :   if (controllers) {
    1224           0 :     nsCOMPtr<nsIController> controller;
    1225           0 :     if (mBaseCommandControllerId) {
    1226           0 :       controllers->GetControllerById(mBaseCommandControllerId,
    1227           0 :                                      getter_AddRefs(controller));
    1228           0 :       if (controller) {
    1229           0 :         controllers->RemoveController(controller);
    1230             :       }
    1231             :     }
    1232             : 
    1233           0 :     if (mDocStateControllerId) {
    1234           0 :       controllers->GetControllerById(mDocStateControllerId,
    1235           0 :                                      getter_AddRefs(controller));
    1236           0 :       if (controller) {
    1237           0 :         controllers->RemoveController(controller);
    1238             :       }
    1239             :     }
    1240             : 
    1241           0 :     if (mHTMLCommandControllerId) {
    1242           0 :       controllers->GetControllerById(mHTMLCommandControllerId,
    1243           0 :                                      getter_AddRefs(controller));
    1244           0 :       if (controller) {
    1245           0 :         controllers->RemoveController(controller);
    1246             :       }
    1247             :     }
    1248             :   }
    1249             : 
    1250             :   // Clear IDs to trigger creation of new controllers.
    1251           0 :   mBaseCommandControllerId = 0;
    1252           0 :   mDocStateControllerId = 0;
    1253           0 :   mHTMLCommandControllerId = 0;
    1254           0 : }
    1255             : 
    1256             : void
    1257           0 : nsEditingSession::RemoveWebProgressListener(nsPIDOMWindowOuter* aWindow)
    1258             : {
    1259           0 :   nsIDocShell *docShell = aWindow ? aWindow->GetDocShell() : nullptr;
    1260           0 :   nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
    1261           0 :   if (webProgress) {
    1262           0 :     webProgress->RemoveProgressListener(this);
    1263           0 :     mProgressListenerRegistered = false;
    1264             :   }
    1265           0 : }
    1266             : 
    1267             : void
    1268           0 : nsEditingSession::RestoreAnimationMode(nsPIDOMWindowOuter* aWindow)
    1269             : {
    1270           0 :   if (mInteractive) {
    1271           0 :     return;
    1272             :   }
    1273             : 
    1274           0 :   nsCOMPtr<nsIDocShell> docShell = aWindow ? aWindow->GetDocShell() : nullptr;
    1275           0 :   NS_ENSURE_TRUE_VOID(docShell);
    1276           0 :   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
    1277           0 :   NS_ENSURE_TRUE_VOID(presShell);
    1278           0 :   nsPresContext* presContext = presShell->GetPresContext();
    1279           0 :   NS_ENSURE_TRUE_VOID(presContext);
    1280             : 
    1281           0 :   presContext->SetImageAnimationMode(mImageAnimationMode);
    1282             : }
    1283             : 
    1284             : nsresult
    1285           0 : nsEditingSession::DetachFromWindow(mozIDOMWindowProxy* aWindow)
    1286             : {
    1287           0 :   NS_ENSURE_TRUE(mDoneSetup, NS_OK);
    1288             : 
    1289           0 :   NS_ASSERTION(mStateMaintainer, "mStateMaintainer should exist.");
    1290             : 
    1291             :   // Kill any existing reload timer
    1292           0 :   if (mLoadBlankDocTimer) {
    1293           0 :     mLoadBlankDocTimer->Cancel();
    1294           0 :     mLoadBlankDocTimer = nullptr;
    1295             :   }
    1296             : 
    1297           0 :   auto* window = nsPIDOMWindowOuter::From(aWindow);
    1298             : 
    1299             :   // Remove controllers, webprogress listener, and otherwise
    1300             :   // make things the way they were before we started editing.
    1301           0 :   RemoveEditorControllers(window);
    1302           0 :   RemoveWebProgressListener(window);
    1303           0 :   RestoreJSAndPlugins(aWindow);
    1304           0 :   RestoreAnimationMode(window);
    1305             : 
    1306             :   // Kill our weak reference to our original window, in case
    1307             :   // it changes on restore, or otherwise dies.
    1308           0 :   mDocShell = nullptr;
    1309             : 
    1310           0 :   return NS_OK;
    1311             : }
    1312             : 
    1313             : nsresult
    1314           0 : nsEditingSession::ReattachToWindow(mozIDOMWindowProxy* aWindow)
    1315             : {
    1316           0 :   NS_ENSURE_TRUE(mDoneSetup, NS_OK);
    1317           0 :   NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
    1318             : 
    1319           0 :   NS_ASSERTION(mStateMaintainer, "mStateMaintainer should exist.");
    1320             : 
    1321             :   // Imitate nsEditorDocShell::MakeEditable() to reattach the
    1322             :   // old editor ot the window.
    1323             :   nsresult rv;
    1324             : 
    1325           0 :   auto* window = nsPIDOMWindowOuter::From(aWindow);
    1326           0 :   nsIDocShell *docShell = window->GetDocShell();
    1327           0 :   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
    1328           0 :   mDocShell = do_GetWeakReference(docShell);
    1329             : 
    1330             :   // Disable plugins.
    1331           0 :   if (!mInteractive) {
    1332           0 :     rv = DisableJSAndPlugins(aWindow);
    1333           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1334             :   }
    1335             : 
    1336             :   // Tells embedder that startup is in progress.
    1337           0 :   mEditorStatus = eEditorCreationInProgress;
    1338             : 
    1339             :   // Adds back web progress listener.
    1340           0 :   rv = PrepareForEditing(window);
    1341           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1342             : 
    1343             :   // Setup the command controllers again.
    1344           0 :   rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1",
    1345             :                                     aWindow,
    1346             :                                     static_cast<nsIEditingSession*>(this),
    1347           0 :                                     &mBaseCommandControllerId);
    1348           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1349             : 
    1350           0 :   rv = SetupEditorCommandController("@mozilla.org/editor/editordocstatecontroller;1",
    1351             :                                     aWindow,
    1352             :                                     static_cast<nsIEditingSession*>(this),
    1353           0 :                                     &mDocStateControllerId);
    1354           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1355             : 
    1356           0 :   if (mStateMaintainer) {
    1357           0 :     mStateMaintainer->Init(window);
    1358             :   }
    1359             : 
    1360             :   // Get editor
    1361           0 :   nsCOMPtr<nsIEditor> editor;
    1362           0 :   rv = GetEditorForWindow(aWindow, getter_AddRefs(editor));
    1363           0 :   NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE);
    1364             : 
    1365           0 :   if (!mInteractive) {
    1366             :     // Disable animation of images in this document:
    1367           0 :     nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
    1368           0 :     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
    1369           0 :     nsPresContext* presContext = presShell->GetPresContext();
    1370           0 :     NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
    1371             : 
    1372           0 :     mImageAnimationMode = presContext->ImageAnimationMode();
    1373           0 :     presContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
    1374             :   }
    1375             : 
    1376             :   // The third controller takes an nsIEditor as the context
    1377           0 :   rv = SetupEditorCommandController("@mozilla.org/editor/htmleditorcontroller;1",
    1378             :                                     aWindow, editor,
    1379           0 :                                     &mHTMLCommandControllerId);
    1380           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1381             : 
    1382             :   // Set context on all controllers to be the editor
    1383           0 :   rv = SetEditorOnControllers(aWindow, editor);
    1384           0 :   NS_ENSURE_SUCCESS(rv, rv);
    1385             : 
    1386             : #ifdef DEBUG
    1387             :   {
    1388             :     bool isEditable;
    1389           0 :     rv = WindowIsEditable(aWindow, &isEditable);
    1390           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1391           0 :     NS_ASSERTION(isEditable, "Window is not editable after reattaching editor.");
    1392             :   }
    1393             : #endif // DEBUG
    1394             : 
    1395           0 :   return NS_OK;
    1396             : }

Generated by: LCOV version 1.13