Bug 699356 - Show the URL of the page in the title of the View Source window. r=smaug.
authorHenri Sivonen <hsivonen@iki.fi>
Wed, 30 Nov 2011 19:44:31 +0200
changeset 81050 b03e24707280
parent 81049 414534199a74
child 81051 b6d8f601d865
push id21551
push usermak77@bonardo.net
push date2011-12-01 11:17 +0000
treeherdermozilla-central@66a1db693790 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs699356
milestone11.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 699356 - Show the URL of the page in the title of the View Source window. r=smaug.
parser/html/nsHtml5Highlighter.cpp
parser/html/nsHtml5Highlighter.h
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5Parser.h
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5StreamParser.h
parser/html/nsHtml5TokenizerCppSupplement.h
parser/html/nsHtml5TokenizerHSupplement.h
toolkit/components/viewsource/test/browser/browser_bug699356.js
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -101,32 +101,36 @@ nsHtml5Highlighter::nsHtml5Highlighter(n
 }
 
 nsHtml5Highlighter::~nsHtml5Highlighter()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 void
-nsHtml5Highlighter::Start()
+nsHtml5Highlighter::Start(const nsAutoString& aTitle)
 {
   // Doctype
   mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
 
   mOpQueue.AppendElement()->Init(STANDARDS_MODE);
 
   nsIContent** root = CreateElement(nsHtml5Atoms::html, nsnull);
   mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
   mStack.AppendElement(root);
 
   Push(nsGkAtoms::head, nsnull);
 
   Push(nsGkAtoms::title, nsnull);
   // XUL will add the "Source of: " prefix.
-  AppendCharacters(mURL.get(), 0, mURL.Length());
+  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(
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -63,17 +63,17 @@ class nsHtml5Highlighter
     /**
      * The destructor.
      */
     ~nsHtml5Highlighter();
 
     /**
      * Starts the generated document.
      */
-    void Start();
+    void Start(const nsAutoString& aTitle);
 
     /**
      * Report a tokenizer state transition.
      *
      * @param aState the state being transitioned to
      * @param aReconsume whether this is a reconsuming transition
      * @param aPos the tokenizer's current position into the buffer
      */
@@ -340,21 +340,16 @@ class nsHtml5Highlighter
     bool mInCharacters;
 
     /**
      * The current buffer being tokenized.
      */
     nsHtml5UTF16Buffer* mBuffer;
 
     /**
-     * The URL of the document to be shown in the page title.
-     */
-    nsString mURL;
-
-    /**
      * Whether to highlight syntax visibly initially.
      */
     bool mSyntaxHighlight;
 
     /**
      * Whether to wrap long lines.
      */
     bool mWrapLongLines;
--- a/parser/html/nsHtml5Parser.cpp
+++ b/parser/html/nsHtml5Parser.cpp
@@ -213,30 +213,31 @@ nsHtml5Parser::IsParserEnabled()
 
 NS_IMETHODIMP_(bool)
 nsHtml5Parser::IsComplete()
 {
   return mExecutor->IsComplete();
 }
 
 NS_IMETHODIMP
-nsHtml5Parser::Parse(nsIURI* aURL, // legacy parameter; ignored
+nsHtml5Parser::Parse(nsIURI* aURL,
                      nsIRequestObserver* aObserver,
                      void* aKey,
                      nsDTDMode aMode) // legacy; ignored
 {
   /*
    * Do NOT cause WillBuildModel to be called synchronously from here!
    * The document won't be ready for it until OnStartRequest!
    */
   NS_PRECONDITION(!mExecutor->HasStarted(), 
                   "Tried to start parse without initializing the parser.");
   NS_PRECONDITION(mStreamParser, 
                   "Can't call this Parse() variant on script-created parser");
   mStreamParser->SetObserver(aObserver);
+  mStreamParser->SetViewSourceTitle(aURL); // In case we're viewing source
   mExecutor->SetStreamParser(mStreamParser);
   mExecutor->SetParser(this);
   mRootContextKey = aKey;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
--- a/parser/html/nsHtml5Parser.h
+++ b/parser/html/nsHtml5Parser.h
@@ -162,17 +162,17 @@ class nsHtml5Parser : public nsIParser,
     /**
      * Query whether the parser thinks it's done with parsing.
      */
     NS_IMETHOD_(bool) IsComplete();
 
     /**
      * Set up request observer.
      *
-     * @param   aURL ignored (for interface compat only)
+     * @param   aURL used for View Source title
      * @param   aListener a listener to forward notifications to
      * @param   aKey the root context key (used for document.write)
      * @param   aMode ignored (for interface compat only)
      */
     NS_IMETHOD Parse(nsIURI* aURL,
                      nsIRequestObserver* aListener = nsnull,
                      void* aKey = 0,
                      nsDTDMode aMode = eDTDMode_autodetect);
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -51,16 +51,17 @@
 #include "nsHtml5AtomTable.h"
 #include "nsHtml5Module.h"
 #include "nsHtml5RefPtr.h"
 #include "nsIScriptError.h"
 #include "mozilla/Preferences.h"
 #include "nsHtml5Highlighter.h"
 #include "expat_config.h"
 #include "expat.h"
+#include "nsINestedURI.h"
 
 using namespace mozilla;
 
 static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID);
 
 PRInt32 nsHtml5StreamParser::sTimerInitialDelay = 120;
 PRInt32 nsHtml5StreamParser::sTimerSubsequentDelay = 120;
 
@@ -286,16 +287,41 @@ nsHtml5StreamParser::Notify(const char* 
       mCharset.Assign(aCharset);
       mCharsetSource = kCharsetFromAutoDetection;
       mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
     }
   }
   return NS_OK;
 }
 
+void
+nsHtml5StreamParser::SetViewSourceTitle(nsIURI* aURL)
+{
+  if (aURL) {
+    nsCOMPtr<nsIURI> temp;
+    bool isViewSource;
+    aURL->SchemeIs("view-source", &isViewSource);
+    if (isViewSource) {
+      nsCOMPtr<nsINestedURI> nested = do_QueryInterface(aURL);
+      nested->GetInnerURI(getter_AddRefs(temp));
+    } else {
+      temp = aURL;
+    }
+    bool isData;
+    temp->SchemeIs("data", &isData);
+    if (isData) {
+      // Avoid showing potentially huge data: URLs. The three last bytes are
+      // UTF-8 for an ellipsis.
+      mViewSourceTitle.AssignLiteral("data:\xE2\x80\xA6");
+    } else {
+      temp->GetSpec(mViewSourceTitle);
+    }
+  }
+}
+
 nsresult
 nsHtml5StreamParser::SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const PRUint8* aFromSegment, // can be null
                                                                           PRUint32 aCount,
                                                                           PRUint32* aWriteCount)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
@@ -875,18 +901,19 @@ nsHtml5StreamParser::OnStartRequest(nsIR
   if (mObserver) {
     mObserver->OnStartRequest(aRequest, aContext);
   }
   mRequest = aRequest;
 
   mStreamState = STREAM_BEING_READ;
 
   if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
-    mTokenizer->StartViewSource();
+    mTokenizer->StartViewSource(NS_ConvertUTF8toUTF16(mViewSourceTitle));
   }
+
   // For View Source, the parser should run with scripts "enabled" if a normal
   // load would have scripts enabled.
   bool scriptingEnabled = mMode == LOAD_AS_DATA ?
                                    false : mExecutor->IsScriptEnabled();
   mOwner->StartTokenizer(scriptingEnabled);
   mTreeBuilder->setScriptingEnabled(scriptingEnabled);
   mTokenizer->start();
   mExecutor->Start();
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -215,16 +215,23 @@ class nsHtml5StreamParser : public nsISt
 
     /**
      * Sets mCharset and mCharsetSource appropriately for the XML View Source
      * case if aEncoding names a supported rough ASCII superset and sets
      * the mCharset and mCharsetSource to the UTF-8 default otherwise.
      */
     void SetEncodingFromExpat(const PRUnichar* aEncoding);
 
+    /**
+     * Sets the URL for View Source title in case this parser ends up being
+     * used for View Source. If aURL is a view-source: URL, takes the inner
+     * URL. data: URLs are shown with an ellipsis instead of the actual data.
+     */
+    void SetViewSourceTitle(nsIURI* aURL);
+
   private:
 
 #ifdef DEBUG
     bool IsParserThread() {
       bool ret;
       mThread->IsOnCurrentThread(&ret);
       return ret;
     }
@@ -381,16 +388,21 @@ class nsHtml5StreamParser : public nsISt
      * a flush runnable back on the main thread.
      */
     void TimerFlush();
 
     nsCOMPtr<nsIRequest>          mRequest;
     nsCOMPtr<nsIRequestObserver>  mObserver;
 
     /**
+     * The document title to use if this turns out to be a View Source parser.
+     */
+    nsCString                     mViewSourceTitle;
+
+    /**
      * The Unicode decoder
      */
     nsCOMPtr<nsIUnicodeDecoder>   mUnicodeDecoder;
 
     /**
      * The buffer for sniffing the character encoding
      */
     nsAutoArrayPtr<PRUint8>       mSniffingBuffer;
--- a/parser/html/nsHtml5TokenizerCppSupplement.h
+++ b/parser/html/nsHtml5TokenizerCppSupplement.h
@@ -49,19 +49,19 @@ nsHtml5Tokenizer::EnableViewSource(nsHtm
 
 bool
 nsHtml5Tokenizer::FlushViewSource()
 {
   return mViewSource->FlushOps();
 }
 
 void
-nsHtml5Tokenizer::StartViewSource()
+nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle)
 {
-  mViewSource->Start();
+  mViewSource->Start(aTitle);
 }
 
 void
 nsHtml5Tokenizer::EndViewSource()
 {
   mViewSource->End();
 }
 
--- a/parser/html/nsHtml5TokenizerHSupplement.h
+++ b/parser/html/nsHtml5TokenizerHSupplement.h
@@ -42,17 +42,17 @@ nsAutoPtr<nsHtml5Highlighter> mViewSourc
  * no corresponding EndPlainText() call.
  */
 void StartPlainText();
 
 void EnableViewSource(nsHtml5Highlighter* aHighlighter);
 
 bool FlushViewSource();
 
-void StartViewSource();
+void StartViewSource(const nsAutoString& aTitle);
 
 void EndViewSource();
 
 void errGarbageAfterLtSlash();
 
 void errLtSlashGt();
 
 void errWarnLtSlashInRcdata();
--- a/toolkit/components/viewsource/test/browser/browser_bug699356.js
+++ b/toolkit/components/viewsource/test/browser/browser_bug699356.js
@@ -4,13 +4,13 @@
 
 function test() {
   let source = "about:blank";
 
   waitForExplicitFinish();
   openViewSourceWindow(source, function(aWindow) {
     let gBrowser = aWindow.gBrowser;
 
-    todo(gBrowser.contentDocument.title == source, "Correct document title");
+    is(gBrowser.contentDocument.title, source, "Correct document title");
     todo(aWindow.document.documentElement.getAttribute("title") == "Source of: " + source, "Correct window title");
     closeViewSourceWindow(aWindow, finish);
   });
 }