Bug 434998 - Enable the usage of the execCommand API for <xul:editor> elements; r=roc
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 15 Jul 2011 08:17:56 -0400
changeset 72866 901d098a58c68672b8ba8cd712cf178725018dc1
parent 72865 7749420447fa3df5a5b4cb336dda9b9dfdbf9ff6
child 72867 eb3a8761eac6e7f6f320b48304b464ee82ab6129
push id20777
push usereakhgari@mozilla.com
push dateFri, 15 Jul 2011 12:20:20 +0000
treeherdermozilla-central@901d098a58c6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs434998
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 434998 - Enable the usage of the execCommand API for <xul:editor> elements; r=roc
editor/composer/src/nsEditingSession.cpp
editor/composer/test/Makefile.in
editor/composer/test/test_bug434998.xul
--- a/editor/composer/src/nsEditingSession.cpp
+++ b/editor/composer/src/nsEditingSession.cpp
@@ -369,16 +369,21 @@ nsEditingSession::SetupEditorOnWindow(ns
 
     // 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(PR_TRUE);
+        nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(document);
+        if (htmlDocument) {
+          // Enable usage of the execCommand API
+          htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode);
+        }
       }
     }
   }
   PRBool needHTMLController = PR_FALSE;
 
   const char *classString = "@mozilla.org/editor/htmleditor;1";
   if (mEditorType.EqualsLiteral("textmail"))
   {
@@ -606,16 +611,20 @@ nsEditingSession::TearDownEditorOnWindow
     RestoreAnimationMode(aWindow);
 
     if (mMakeWholeDocumentEditable)
     {
       nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       doc->SetEditableFlag(PR_FALSE);
+      nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(doc);
+      if (htmlDocument) {
+        htmlDocument->SetEditingState(nsIHTMLDocument::eOff);
+      }
     }
   }
 
   return rv;
 }
 
 /*---------------------------------------------------------------------------
 
--- a/editor/composer/test/Makefile.in
+++ b/editor/composer/test/Makefile.in
@@ -46,10 +46,17 @@ include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
 		test_bug348497.html \
 		test_bug384147.html \
 		test_bug389350.html \
 		test_bug519928.html \
 		$(NULL)
 
+_CHROME_TEST_FILES = \
+		test_bug434998.xul \
+		$(NULL)
+
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+
+libs:: $(_CHROME_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/editor/composer/test/test_bug434998.xul
@@ -0,0 +1,110 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin"
+                 type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=434998
+-->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Mozilla Bug 434998" onload="runTest();">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"/>
+  <script type="application/javascript"
+    src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=434998"
+     target="_blank">Mozilla Bug 434998</a>
+  <p/>
+  <editor xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+          id="editor"
+          type="content-primary"
+          editortype="html"
+          style="width: 400px; height: 100px; border: thin solid black"/>
+  <p/>
+  <pre id="test">
+  </pre>
+  </body>
+  <script class="testbody" type="application/javascript">
+  <![CDATA[
+
+  SimpleTest.waitForExplicitFinish();
+
+  function EditorContentListener(aEditor)
+  {
+    this.init(aEditor);
+  }
+
+  EditorContentListener.prototype = {
+    init : function(aEditor)
+    {
+      this.mEditor = aEditor;
+    },
+
+    QueryInterface : function(aIID)
+    {
+      if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
+          aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
+          aIID.equals(Components.interfaces.nsISupports))
+        return this;
+      throw Components.results.NS_NOINTERFACE;
+    },
+
+    onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
+    {
+      if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
+      {
+        var editor = this.mEditor.getEditor(this.mEditor.contentWindow);
+        if (editor) {
+          // Should not throw
+          var threw = false;
+          try {
+            this.mEditor.contentDocument.execCommand("bold", false, null);
+          } catch (e) {
+            threw = true;
+          }
+          ok(!threw, "The execCommand API should work on <xul:editor>");
+          SimpleTest.finish();
+        }
+      }
+    },
+
+
+    onProgressChange : function(aWebProgress, aRequest,
+                                aCurSelfProgress, aMaxSelfProgress,
+                                aCurTotalProgress, aMaxTotalProgress)
+    {
+    },
+
+    onLocationChange : function(aWebProgress, aRequest, aLocation)
+    {
+    },
+
+    onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
+    {
+    },
+
+    onSecurityChange : function(aWebProgress, aRequest, aState)
+    {
+    },
+
+    mEditor: null
+  };
+
+  var progress, progressListener;
+
+  function runTest() {
+    var newEditorElement = document.getElementById("editor");
+    newEditorElement.makeEditable("html", true);
+    var docShell = newEditorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
+    progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
+    progressListener = new EditorContentListener(newEditorElement);
+    progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+    newEditorElement.setAttribute("src", "data:text/html,");
+  }
+]]>
+</script>
+</window>