Bug 703965 - Use View Source styling when viewing plain text source. r=smaug.
authorHenri Sivonen <hsivonen@iki.fi>
Wed, 30 Nov 2011 19:44:31 +0200
changeset 81826 1b3b8bd50be90c63201ff10c934439bb85da942d
parent 81825 38814e0bafb91e05f847f7e82f5b305b40e1deaa
child 81827 fe8a47afa807887719e428cfff62d8637dbaf187
push idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs703965
milestone11.0a1
Bug 703965 - Use View Source styling when viewing plain text source. r=smaug.
content/html/document/src/nsHTMLDocument.cpp
parser/html/Makefile.in
parser/html/nsHtml5Highlighter.cpp
parser/html/nsHtml5Highlighter.h
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeBuilderHSupplement.h
parser/html/nsHtml5ViewSourceUtils.cpp
parser/html/nsHtml5ViewSourceUtils.h
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -743,17 +743,21 @@ nsHTMLDocument::StartDocumentLoad(const 
   }
 
   nsCOMPtr<nsICachingChannel> cachingChan = do_QueryInterface(aChannel);
 
   if (needsParser) {
     if (loadAsHtml5) {
       mParser = nsHtml5Module::NewHtml5Parser();
       if (plainText) {
-        mParser->MarkAsNotScriptCreated("plain-text");
+        if (viewSource) {
+          mParser->MarkAsNotScriptCreated("view-source-plain");
+        } else {
+          mParser->MarkAsNotScriptCreated("plain-text");
+        }
       } else if (viewSource && !contentType.EqualsLiteral("text/html")) {
         mParser->MarkAsNotScriptCreated("view-source-xml");
       } else {
         mParser->MarkAsNotScriptCreated(aCommand);
       }
     } else {
       mParser = do_CreateInstance(kCParserCID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
--- a/parser/html/Makefile.in
+++ b/parser/html/Makefile.in
@@ -71,16 +71,17 @@ EXPORTS		= \
 		nsHtml5TreeOperation.h \
 		nsHtml5TreeOpExecutor.h \
 		nsAHtml5TreeOpSink.h \
 		nsHtml5TreeOpStage.h \
 		nsHtml5UTF16Buffer.h \
 		nsHtml5UTF16BufferHSupplement.h \
 		nsHtml5DependentUTF16Buffer.h \
 		nsHtml5OwningUTF16Buffer.h \
+		nsHtml5ViewSourceUtils.h \
 		$(NULL)
 
 CPPSRCS		= \
 		nsHtml5Atoms.cpp \
 		nsHtml5Atom.cpp \
 		nsHtml5AtomTable.cpp \
 		nsHtml5Parser.cpp \
 		nsHtml5AttributeName.cpp \
@@ -103,16 +104,17 @@ CPPSRCS		= \
 		nsHtml5TreeOpStage.cpp \
 		nsHtml5StateSnapshot.cpp \
 		nsHtml5TreeOpExecutor.cpp \
 		nsHtml5StreamParser.cpp \
 		nsHtml5Speculation.cpp \
 		nsHtml5SpeculativeLoad.cpp \
 		nsHtml5SVGLoadDispatcher.cpp \
 		nsHtml5Highlighter.cpp \
+		nsHtml5ViewSourceUtils.cpp \
 		$(NULL)
 
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES	+= \
 		-I$(srcdir)/../../content/base/src \
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -36,16 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHtml5Highlighter.h"
 #include "nsDebug.h"
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5AttributeName.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
+#include "nsHtml5ViewSourceUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 // The old code had a limit of 16 tokens. 1300 is a number picked my measuring
 // the size of 16 tokens on cnn.com.
 #define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
 
@@ -83,18 +84,16 @@ nsHtml5Highlighter::nsHtml5Highlighter(n
  , mPos(0)
  , mLineNumber(1)
  , mUnicharsInThisPre(0)
  , mInlinesOpen(0)
  , mInCharacters(false)
  , mBuffer(nsnull)
  , mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
                                          true))
- , mWrapLongLines(Preferences::GetBool("view_source.wrap_long_lines", true))
- , mTabSize(Preferences::GetInt("view_source.tab_size", 4))
  , mOpSink(aOpSink)
  , mCurrentRun(nsnull)
  , mAmpersand(nsnull)
  , mSlash(nsnull)
  , mHandles(new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH])
  , mHandlesUsed(0)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@@ -123,48 +122,25 @@ nsHtml5Highlighter::Start(const nsAutoSt
   // XUL will add the "Source of: " prefix.
   PRUint32 length = aTitle.Length();
   if (length > PR_INT32_MAX) {
     length = PR_INT32_MAX;
   }
   AppendCharacters(aTitle.get(), 0, (PRInt32)length);
   Pop(); // title
 
-  nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
-  nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet"));
-  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel);
-  nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
-  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type);
-  nsString* href = new nsString(
-      NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
-  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href);
-  Push(nsGkAtoms::link, linkAttrs);
+  Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
 
   mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
 
   Pop(); // link
 
   Pop(); // head
 
-  nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
-  nsString* id = new nsString(NS_LITERAL_STRING("viewsource"));
-  bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id);
-
-  if (mWrapLongLines) {
-    nsString* klass = new nsString(NS_LITERAL_STRING("wrap"));
-    bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass);
-  }
-
-  if (mTabSize > 0) {
-    nsString* style = new nsString(NS_LITERAL_STRING("-moz-tab-size: "));
-    style->AppendInt(mTabSize);
-    bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_STYLE, style);
-  }
-
-  Push(nsGkAtoms::body, bodyAttrs);
+  Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
 
   nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
   nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
   preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId);
   Push(nsGkAtoms::pre, preAttrs);
 
   StartCharacters();
 
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -345,26 +345,16 @@ class nsHtml5Highlighter
     nsHtml5UTF16Buffer* mBuffer;
 
     /**
      * Whether to highlight syntax visibly initially.
      */
     bool mSyntaxHighlight;
 
     /**
-     * Whether to wrap long lines.
-     */
-    bool mWrapLongLines;
-
-    /**
-     * The tab size pref.
-     */
-    PRInt32 mTabSize;
-
-    /**
      * The outgoing tree op queue.
      */
     nsTArray<nsHtml5TreeOperation> mOpQueue;
 
     /**
      * The tree op stage for the tree op executor.
      */
     nsAHtml5TreeOpSink* mOpSink;
--- a/parser/html/nsHtml5Parser.cpp
+++ b/parser/html/nsHtml5Parser.cpp
@@ -709,16 +709,18 @@ void
 nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
 {
   NS_PRECONDITION(!mStreamParser, "Must not call this twice.");
   eParserMode mode = NORMAL;
   if (!nsCRT::strcmp(aCommand, "view-source")) {
     mode = VIEW_SOURCE_HTML;
   } else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
     mode = VIEW_SOURCE_XML;
+  } else if (!nsCRT::strcmp(aCommand, "view-source-plain")) {
+    mode = VIEW_SOURCE_PLAIN;
   } else if (!nsCRT::strcmp(aCommand, "plain-text")) {
     mode = PLAIN_TEXT;
   } else if (!nsCRT::strcmp(aCommand, kLoadAsData)) {
     mode = LOAD_AS_DATA;
   }
 #ifdef DEBUG
   else {
     NS_ASSERTION(!nsCRT::strcmp(aCommand, "view") ||
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -917,16 +917,19 @@ nsHtml5StreamParser::OnStartRequest(nsIR
   mTreeBuilder->setScriptingEnabled(scriptingEnabled);
   mTokenizer->start();
   mExecutor->Start();
   mExecutor->StartReadingFromStage();
 
   if (mMode == PLAIN_TEXT) {
     mTreeBuilder->StartPlainText();
     mTokenizer->StartPlainText();
+  } else if (mMode == VIEW_SOURCE_PLAIN) {
+    mTreeBuilder->StartPlainTextViewSource(NS_ConvertUTF8toUTF16(mViewSourceTitle));
+    mTokenizer->StartPlainText();
   }
 
   /*
    * If you move the following line, be very careful not to cause 
    * WillBuildModel to be called before the document has had its 
    * script global object set.
    */
   mExecutor->WillBuildModel(eDTDMode_unknown);
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -72,16 +72,21 @@ enum eParserMode {
   VIEW_SOURCE_HTML,
 
   /**
    * View document as XML source
    */
   VIEW_SOURCE_XML,
 
   /**
+   * View document as plain text source
+   */
+  VIEW_SOURCE_PLAIN,
+
+  /**
    * View document as plain text
    */
   PLAIN_TEXT,
 
   /**
    * Load as data (XHR)
    */
   LOAD_AS_DATA
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -47,16 +47,17 @@
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5PendingNotification.h"
 #include "nsHtml5StateSnapshot.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5StreamParser.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Highlighter.h"
+#include "nsHtml5ViewSourceUtils.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -48,16 +48,17 @@
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5PendingNotification.h"
 #include "nsHtml5StateSnapshot.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5StreamParser.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Highlighter.h"
+#include "nsHtml5ViewSourceUtils.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -696,16 +696,42 @@ nsHtml5TreeBuilder::DropHandles()
 void
 nsHtml5TreeBuilder::MarkAsBroken()
 {
   mOpQueue.Clear(); // Previous ops don't matter anymore
   mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken);
 }
 
 void
+nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
+{
+  startTag(nsHtml5ElementName::ELT_TITLE,
+           nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
+           false);
+
+  // XUL will add the "Source of: " prefix.
+  PRUint32 length = aTitle.Length();
+  if (length > PR_INT32_MAX) {
+    length = PR_INT32_MAX;
+  }
+  characters(aTitle.get(), 0, (PRInt32)length);
+  endTag(nsHtml5ElementName::ELT_TITLE);
+
+  startTag(nsHtml5ElementName::ELT_LINK,
+           nsHtml5ViewSourceUtils::NewLinkAttributes(),
+           false);
+
+  startTag(nsHtml5ElementName::ELT_BODY,
+           nsHtml5ViewSourceUtils::NewBodyAttributes(),
+           false);
+
+  StartPlainText();
+}
+
+void
 nsHtml5TreeBuilder::StartPlainText()
 {
   startTag(nsHtml5ElementName::ELT_PRE,
            nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
            false);
   needToDropLF = false;
 }
 
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -90,16 +90,18 @@
 
   public:
 
     nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
                        nsHtml5TreeOpStage* aStage);
 
     ~nsHtml5TreeBuilder();
     
+    void StartPlainTextViewSource(const nsAutoString& aTitle);
+
     void StartPlainText();
 
     bool HasScript();
     
     void SetOpSink(nsAHtml5TreeOpSink* aOpSink) {
       mOpSink = aOpSink;
     }
 
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5ViewSourceUtils.cpp
@@ -0,0 +1,79 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is HTML5 View Source code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Henri Sivonen <hsivonen@iki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsHtml5ViewSourceUtils.h"
+#include "nsHtml5AttributeName.h"
+#include "mozilla/Preferences.h"
+
+// static
+nsHtml5HtmlAttributes*
+nsHtml5ViewSourceUtils::NewBodyAttributes()
+{
+  nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
+  nsString* id = new nsString(NS_LITERAL_STRING("viewsource"));
+  bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id);
+
+  if (mozilla::Preferences::GetBool("view_source.wrap_long_lines", true)) {
+    nsString* klass = new nsString(NS_LITERAL_STRING("wrap"));
+    bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass);
+  }
+
+  PRInt32 tabSize = mozilla::Preferences::GetInt("view_source.tab_size", 4);
+  if (tabSize > 0) {
+    nsString* style = new nsString(NS_LITERAL_STRING("-moz-tab-size: "));
+    style->AppendInt(tabSize);
+    bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_STYLE, style);
+  }
+
+  return bodyAttrs;
+}
+
+// static
+nsHtml5HtmlAttributes*
+nsHtml5ViewSourceUtils::NewLinkAttributes()
+{
+  nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
+  nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet"));
+  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel);
+  nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
+  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type);
+  nsString* href = new nsString(
+      NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
+  linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href);
+  return linkAttrs;
+}
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5ViewSourceUtils.h
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is HTML5 View Source code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Henri Sivonen <hsivonen@iki.fi>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsHtml5ViewSourceUtils_h_
+#define nsHtml5ViewSourceUtils_h_
+
+#include "nsHtml5HtmlAttributes.h"
+
+class nsHtml5ViewSourceUtils
+{
+  public:
+    static nsHtml5HtmlAttributes* NewBodyAttributes();
+    static nsHtml5HtmlAttributes* NewLinkAttributes();
+};
+
+#endif // nsHtml5ViewSourceUtils_h_