Bug 570898 - Defer isindex prompt reading until after startup. r=jonas.
authorHenri Sivonen <hsivonen@iki.fi>
Fri, 11 Jun 2010 18:08:13 +0300
changeset 44175 075fe10df9c3ec6ac6752912502ad72a7ee52043
parent 44174 30e7132bba2850a8e4eb9adb085cff7d2ec0a3e9
child 44176 35f1e03ce92849ff187e4f4134f6009eb0daf6a8
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonas
bugs570898
milestone1.9.3a6pre
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 570898 - Defer isindex prompt reading until after startup. r=jonas.
parser/html/javasrc/Portability.java
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5Portability.cpp
parser/html/nsHtml5Portability.h
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeOperation.cpp
parser/html/nsHtml5TreeOperation.h
--- a/parser/html/javasrc/Portability.java
+++ b/parser/html/javasrc/Portability.java
@@ -162,20 +162,16 @@ public final class Portability {
         }
         return true;
     }
     
     public static boolean literalEqualsString(@Literal String literal, String string) {
         return literal.equals(string);
     }
 
-    public static char[] isIndexPrompt() {
-        return "This is a searchable index. Enter search keywords: ".toCharArray();
-    }
-
     public static void delete(Object o) {
         
     }
 
     public static void deleteArray(Object o) {
         
     }
 }
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -261,18 +261,16 @@ public abstract class TreeBuilder<T> imp
     private static final int CHARSET_SINGLE_QUOTED = 9;
 
     private static final int CHARSET_DOUBLE_QUOTED = 10;
 
     private static final int CHARSET_UNQUOTED = 11;
 
     // end pseudo enums
 
-    private final static char[] ISINDEX_PROMPT = Portability.isIndexPrompt();
-
     // [NOCPP[
 
     private final static String[] HTML4_PUBLIC_IDS = {
             "-//W3C//DTD HTML 4.0 Frameset//EN",
             "-//W3C//DTD HTML 4.0 Transitional//EN",
             "-//W3C//DTD HTML 4.0//EN", "-//W3C//DTD HTML 4.01 Frameset//EN",
             "-//W3C//DTD HTML 4.01 Transitional//EN",
             "-//W3C//DTD HTML 4.01//EN" };
@@ -2050,20 +2048,17 @@ public abstract class TreeBuilder<T> imp
                                         HtmlAttributes.EMPTY_ATTRIBUTES);
                                 int promptIndex = attributes.getIndex(AttributeName.PROMPT);
                                 if (promptIndex > -1) {
                                     char[] prompt = Portability.newCharArrayFromString(attributes.getValue(promptIndex));
                                     appendCharacters(stack[currentPtr].node,
                                             prompt, 0, prompt.length);
                                     Portability.releaseArray(prompt);
                                 } else {
-                                    // XXX localization
-                                    appendCharacters(stack[currentPtr].node,
-                                            TreeBuilder.ISINDEX_PROMPT, 0,
-                                            TreeBuilder.ISINDEX_PROMPT.length);
+                                    appendIsindexPrompt(stack[currentPtr].node);
                                 }
                                 HtmlAttributes inputAttributes = new HtmlAttributes(
                                         0);
                                 inputAttributes.addAttribute(
                                         AttributeName.NAME,
                                         Portability.newStringFromLiteral("isindex")
                                         // [NOCPP[
                                         , XmlViolationPolicy.ALLOW
@@ -2084,17 +2079,16 @@ public abstract class TreeBuilder<T> imp
 
                                         );
                                     }
                                 }
                                 attributes.clearWithoutReleasingContents();
                                 appendVoidElementToCurrentMayFoster(
                                         "http://www.w3.org/1999/xhtml",
                                         "input", inputAttributes, formPointer);
-                                // XXX localization
                                 pop(); // label
                                 appendVoidElementToCurrentMayFoster(
                                         "http://www.w3.org/1999/xhtml",
                                         ElementName.HR,
                                         HtmlAttributes.EMPTY_ATTRIBUTES);
                                 pop(); // form
                                 selfClosing = false;
                                 // Portability.delete(formAttrs);
@@ -5144,16 +5138,18 @@ public abstract class TreeBuilder<T> imp
 
     protected abstract void insertFosterParentedCharacters(
             @NoLength char[] buf, int start, int length, T table, T stackParent)
             throws SAXException;
 
     protected abstract void appendCharacters(T parent, @NoLength char[] buf,
             int start, int length) throws SAXException;
 
+    protected abstract void appendIsindexPrompt(T parent) throws SAXException;
+    
     protected abstract void appendComment(T parent, @NoLength char[] buf,
             int start, int length) throws SAXException;
 
     protected abstract void appendCommentToDocument(@NoLength char[] buf,
             int start, int length) throws SAXException;
 
     protected abstract void addAttributesToElement(T element,
             HtmlAttributes attributes) throws SAXException;
--- a/parser/html/nsHtml5Portability.cpp
+++ b/parser/html/nsHtml5Portability.cpp
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "prtypes.h"
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "jArray.h"
 #include "nsHtml5Portability.h"
-#include "nsContentUtils.h"
 
 nsIAtom*
 nsHtml5Portability::newLocalNameFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner)
 {
   NS_ASSERTION(!offset, "The offset should always be zero here.");
   NS_ASSERTION(interner, "Didn't get an atom service.");
   return interner->GetAtom(nsDependentSubstring(buf, buf + length));
 }
@@ -175,39 +174,16 @@ PRBool
 nsHtml5Portability::literalEqualsString(const char* literal, nsString* string)
 {
   if (!string) {
     return PR_FALSE;
   }
   return string->EqualsASCII(literal);
 }
 
-jArray<PRUnichar,PRInt32>
-nsHtml5Portability::isIndexPrompt()
-{
-  nsXPIDLString prompt;
-  nsresult rv =
-      nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
-                                         "IsIndexPromptWithSpace", prompt);
-  PRUint32 len = prompt.Length();
-  if (NS_FAILED(rv) || !len) {
-    // jArray doesn't support dynamically-allocated zero-length arrays
-    // and this method has no way to signal an error. Let's return
-    // the REPLACEMENT CHARACTER to avoid crashing on null pointer.
-    jArray<PRUnichar,PRInt32> arr = jArray<PRUnichar,PRInt32>(1);
-    arr[0] = 0xFFFD;
-    return arr;
-  }
-  jArray<PRUnichar,PRInt32> arr = jArray<PRUnichar,PRInt32>(len);
-  PRUnichar* arrAsPtr = arr;
-  const PRUnichar* strAsPtr = prompt.BeginReading();
-  memcpy(arrAsPtr, strAsPtr, len * sizeof(PRUnichar));
-  return arr;
-}
-
 void
 nsHtml5Portability::initializeStatics()
 {
 }
 
 void
 nsHtml5Portability::releaseStatics()
 {
--- a/parser/html/nsHtml5Portability.h
+++ b/parser/html/nsHtml5Portability.h
@@ -71,17 +71,16 @@ class nsHtml5Portability
     static nsIAtom* newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner);
     static void releaseString(nsString* str);
     static void retainLocal(nsIAtom* local);
     static void releaseLocal(nsIAtom* local);
     static PRBool localEqualsBuffer(nsIAtom* local, PRUnichar* buf, PRInt32 offset, PRInt32 length);
     static PRBool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
     static PRBool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
     static PRBool literalEqualsString(const char* literal, nsString* string);
-    static jArray<PRUnichar,PRInt32> isIndexPrompt();
     static void initializeStatics();
     static void releaseStatics();
 };
 
 #ifdef nsHtml5Portability_cpp__
 #endif
 
 
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -1104,17 +1104,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
               appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
               appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
               PRInt32 promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT);
               if (promptIndex > -1) {
                 jArray<PRUnichar,PRInt32> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValue(promptIndex));
                 appendCharacters(stack[currentPtr]->node, prompt, 0, prompt.length);
                 prompt.release();
               } else {
-                appendCharacters(stack[currentPtr]->node, nsHtml5TreeBuilder::ISINDEX_PROMPT, 0, nsHtml5TreeBuilder::ISINDEX_PROMPT.length);
+                appendIsindexPrompt(stack[currentPtr]->node);
               }
               nsHtml5HtmlAttributes* inputAttributes = new nsHtml5HtmlAttributes(0);
               inputAttributes->addAttribute(nsHtml5AttributeName::ATTR_NAME, nsHtml5Portability::newStringFromLiteral("isindex"));
               for (PRInt32 i = 0; i < attributes->getLength(); i++) {
                 nsHtml5AttributeName* attributeQName = attributes->getAttributeName(i);
                 if (nsHtml5AttributeName::ATTR_NAME == attributeQName || nsHtml5AttributeName::ATTR_PROMPT == attributeQName) {
                   attributes->releaseValue(i);
                 } else if (nsHtml5AttributeName::ATTR_ACTION != attributeQName) {
@@ -3986,17 +3986,16 @@ PRInt32
 nsHtml5TreeBuilder::getStackLength()
 {
   return currentPtr + 1;
 }
 
 void
 nsHtml5TreeBuilder::initializeStatics()
 {
-  ISINDEX_PROMPT = nsHtml5Portability::isIndexPrompt();
   QUIRKY_PUBLIC_IDS = jArray<const char*,PRInt32>(55);
   QUIRKY_PUBLIC_IDS[0] = "+//silmaril//dtd html pro v0r11 19970101//";
   QUIRKY_PUBLIC_IDS[1] = "-//advasoft ltd//dtd html 3.0 aswedit + extensions//";
   QUIRKY_PUBLIC_IDS[2] = "-//as//dtd html 3.0 aswedit + extensions//";
   QUIRKY_PUBLIC_IDS[3] = "-//ietf//dtd html 2.0 level 1//";
   QUIRKY_PUBLIC_IDS[4] = "-//ietf//dtd html 2.0 level 2//";
   QUIRKY_PUBLIC_IDS[5] = "-//ietf//dtd html 2.0 strict level 1//";
   QUIRKY_PUBLIC_IDS[6] = "-//ietf//dtd html 2.0 strict level 2//";
@@ -4048,15 +4047,14 @@ nsHtml5TreeBuilder::initializeStatics()
   QUIRKY_PUBLIC_IDS[52] = "-//w3o//dtd w3 html 3.0//";
   QUIRKY_PUBLIC_IDS[53] = "-//webtechs//dtd mozilla html 2.0//";
   QUIRKY_PUBLIC_IDS[54] = "-//webtechs//dtd mozilla html//";
 }
 
 void
 nsHtml5TreeBuilder::releaseStatics()
 {
-  ISINDEX_PROMPT.release();
   QUIRKY_PUBLIC_IDS.release();
 }
 
 
 #include "nsHtml5TreeBuilderCppSupplement.h"
 
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -65,17 +65,16 @@ class nsHtml5HtmlAttributes;
 class nsHtml5UTF16Buffer;
 class nsHtml5StateSnapshot;
 class nsHtml5Portability;
 
 
 class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
 {
   private:
-    static jArray<PRUnichar,PRInt32> ISINDEX_PROMPT;
     static jArray<const char*,PRInt32> QUIRKY_PUBLIC_IDS;
     PRInt32 mode;
     PRInt32 originalMode;
     PRBool framesetOk;
     PRBool inForeign;
   protected:
     nsHtml5Tokenizer* tokenizer;
   private:
@@ -189,16 +188,17 @@ class nsHtml5TreeBuilder : public nsAHtm
     nsIContent** createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
     void detachFromParent(nsIContent** element);
     PRBool hasChildren(nsIContent** element);
     void appendElement(nsIContent** child, nsIContent** newParent);
     void appendChildrenToNewParent(nsIContent** oldParent, nsIContent** newParent);
     void insertFosterParentedChild(nsIContent** child, nsIContent** table, nsIContent** stackParent);
     void insertFosterParentedCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length, nsIContent** table, nsIContent** stackParent);
     void appendCharacters(nsIContent** parent, PRUnichar* buf, PRInt32 start, PRInt32 length);
+    void appendIsindexPrompt(nsIContent** parent);
     void appendComment(nsIContent** parent, PRUnichar* buf, PRInt32 start, PRInt32 length);
     void appendCommentToDocument(PRUnichar* buf, PRInt32 start, PRInt32 length);
     void addAttributesToElement(nsIContent** element, nsHtml5HtmlAttributes* attributes);
     void markMalformedIfScript(nsIContent** elt);
     void start(PRBool fragmentMode);
     void end();
     void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
     void elementPushed(PRInt32 ns, nsIAtom* name, nsIContent** node);
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -45,18 +45,16 @@
 #include "nsEventDispatcher.h"
 #include "nsContentUtils.h"
 #include "nsNodeUtils.h"
 
 #define NS_HTML5_TREE_DEPTH_LIMIT 200
 
 class nsPresContext;
 
-// this really should be autogenerated...
-jArray<PRUnichar,PRInt32> nsHtml5TreeBuilder::ISINDEX_PROMPT = jArray<PRUnichar,PRInt32>();
 nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
                                        nsHtml5TreeOpStage* aStage)
   : scriptingEnabled(PR_FALSE)
   , fragment(PR_FALSE)
   , contextNode(nsnull)
   , formPointer(nsnull)
   , headPointer(nsnull)
   , mOpSink(aOpSink)
@@ -308,16 +306,26 @@ nsHtml5TreeBuilder::appendCharacters(nsI
   
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
       mDeepTreeSurrogateParent ? mDeepTreeSurrogateParent : aParent);
 }
 
 void
+nsHtml5TreeBuilder::appendIsindexPrompt(nsIContent** aParent)
+{
+  NS_PRECONDITION(aParent, "Null parent");
+
+  nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+  NS_ASSERTION(treeOp, "Tree op allocation failed.");
+  treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
+}
+
+void
 nsHtml5TreeBuilder::appendComment(nsIContent** aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
 {
   NS_PRECONDITION(aBuffer, "Null buffer");
   NS_PRECONDITION(aParent, "Null parent");
   if (mDeepTreeSurrogateParent) {
     return;
   }
 
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -128,17 +128,17 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
       nsMemory::Free(mOne.unicharPtr);
       break;
     default: // keep the compiler happy
       break;
   }
 }
 
 nsresult
-nsHtml5TreeOperation::AppendTextToTextNode(PRUnichar* aBuffer,
+nsHtml5TreeOperation::AppendTextToTextNode(const PRUnichar* aBuffer,
                                            PRInt32 aLength,
                                            nsIContent* aTextNode,
                                            nsHtml5TreeOpExecutor* aBuilder)
 {
   NS_PRECONDITION(aTextNode, "Got null text node.");
 
   if (aBuilder->HaveNotified(aTextNode)) {
     // This text node has already been notified on, so it's necessary to
@@ -160,17 +160,17 @@ nsHtml5TreeOperation::AppendTextToTextNo
     return rv;
   }
 
   return aTextNode->AppendText(aBuffer, aLength, PR_FALSE);
 }
 
 
 nsresult
-nsHtml5TreeOperation::AppendText(PRUnichar* aBuffer,
+nsHtml5TreeOperation::AppendText(const PRUnichar* aBuffer,
                                  PRInt32 aLength,
                                  nsIContent* aParent,
                                  nsHtml5TreeOpExecutor* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* lastChild = aParent->GetLastChild();
   if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
     nsHtml5OtherDocUpdate update(aParent->GetOwnerDoc(),
@@ -474,16 +474,32 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       return rv;
     }
     case eTreeOpAppendText: {
       nsIContent* parent = *mOne.node;
       PRUnichar* buffer = mTwo.unicharPtr;
       PRInt32 length = mInt;
       return AppendText(buffer, length, parent, aBuilder);
     }
+    case eTreeOpAppendIsindexPrompt: {
+      nsIContent* parent = *mOne.node;
+      nsXPIDLString prompt;
+      nsresult rv =
+          nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+                                             "IsIndexPromptWithSpace", prompt);
+      PRUint32 len = prompt.Length();
+      if (NS_FAILED(rv)) {
+        return rv;
+      }
+      if (!len) {
+        // Don't bother appending a zero-length text node.
+        return NS_OK;
+      }
+      return AppendText(prompt.BeginReading(), len, parent, aBuilder);
+    }
     case eTreeOpFosterParentText: {
       nsIContent* stackParent = *mOne.node;
       PRUnichar* buffer = mTwo.unicharPtr;
       PRInt32 length = mInt;
       nsIContent* table = *mThree.node;
       
       nsIContent* foster = table->GetParent();
 
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -57,16 +57,17 @@ enum eHtml5TreeOperation {
   eTreeOpFosterParent,
   eTreeOpAppendToDocument,
   eTreeOpAddAttributes,
   eTreeOpDocumentMode,
   eTreeOpCreateElementNetwork,
   eTreeOpCreateElementNotNetwork,
   eTreeOpSetFormElement,
   eTreeOpAppendText,
+  eTreeOpAppendIsindexPrompt,
   eTreeOpFosterParentText,
   eTreeOpAppendComment,
   eTreeOpAppendCommentToDocument,
   eTreeOpAppendDoctypeToDocument,
   // Gecko-specific on-pop ops
   eTreeOpRunScript,
   eTreeOpRunScriptAsyncDefer,
   eTreeOpDoneAddingChildren,
@@ -314,22 +315,22 @@ class nsHtml5TreeOperation {
       }
       nsAutoString str;
       aAtom->ToString(str);
       return do_GetAtom(str);
     }
 
   private:
 
-    nsresult AppendTextToTextNode(PRUnichar* aBuffer,
+    nsresult AppendTextToTextNode(const PRUnichar* aBuffer,
                                   PRInt32 aLength,
                                   nsIContent* aTextNode,
                                   nsHtml5TreeOpExecutor* aBuilder);
 
-    nsresult AppendText(PRUnichar* aBuffer,
+    nsresult AppendText(const PRUnichar* aBuffer,
                         PRInt32 aLength,
                         nsIContent* aParent,
                         nsHtml5TreeOpExecutor* aBuilder);
 
     nsresult Append(nsIContent* aNode,
                     nsIContent* aParent,
                     nsHtml5TreeOpExecutor* aBuilder);