Bug 466626 - Make nsStyleLinkElement::ParseLinkTypes return a bitmask; r=roc
authorAndrew <andrew.quartey@gmail.com>
Sun, 20 Nov 2011 11:13:40 +0000
changeset 80516 a751a20c3e8c0eae96c864caaa40fa9d3bf53314
parent 80515 bb4b4b65beed86ed86411a7a215566a87a63394e
child 80520 9a1341595afb31b424375b59436c58983d13079e
push id3481
push userbmo@edmorley.co.uk
push dateSun, 20 Nov 2011 11:14:25 +0000
treeherdermozilla-inbound@a751a20c3e8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs466626
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 466626 - Make nsStyleLinkElement::ParseLinkTypes return a bitmask; r=roc
content/base/src/nsContentSink.cpp
content/base/src/nsStyleLinkElement.cpp
content/base/src/nsStyleLinkElement.h
content/html/content/src/nsHTMLLinkElement.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -814,44 +814,42 @@ nsContentSink::ProcessLinkHeader(nsICont
 
 
 nsresult
 nsContentSink::ProcessLink(nsIContent* aElement,
                            const nsSubstring& aAnchor, const nsSubstring& aHref,
                            const nsSubstring& aRel, const nsSubstring& aTitle,
                            const nsSubstring& aType, const nsSubstring& aMedia)
 {
-  // XXX seems overkill to generate this string array
-  nsTArray<nsString> linkTypes;
-  nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
+  PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aRel);
 
   // The link relation may apply to a different resource, specified
   // in the anchor parameter. For the link relations supported so far,
   // we simply abort if the link applies to a resource different to the
   // one we've loaded
   if (!LinkContextIsOurDocument(aAnchor)) {
     return NS_OK;
   }
   
-  bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
+  bool hasPrefetch = linkTypes & PREFETCH;
   // prefetch href if relation is "next" or "prefetch"
-  if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
+  if (hasPrefetch || (linkTypes & NEXT)) {
     PrefetchHref(aHref, aElement, hasPrefetch);
   }
 
-  if ((!aHref.IsEmpty()) && linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
+  if (!aHref.IsEmpty() && (linkTypes & DNS_PREFETCH)) {
     PrefetchDNS(aHref);
   }
 
   // is it a stylesheet link?
-  if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
+  if (!(linkTypes & STYLESHEET)) {
     return NS_OK;
   }
 
-  bool isAlternate = linkTypes.Contains(NS_LITERAL_STRING("alternate"));
+  bool isAlternate = linkTypes & ALTERNATE;
   return ProcessStyleLink(aElement, aHref, isAlternate, aTitle, aType,
                           aMedia);
 }
 
 nsresult
 nsContentSink::ProcessStyleLink(nsIContent* aElement,
                                 const nsSubstring& aHref,
                                 bool aAlternate,
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -148,49 +148,66 @@ nsStyleLinkElement::OverrideBaseURI(nsIU
 }
 
 /* virtual */ void
 nsStyleLinkElement::SetLineNumber(PRUint32 aLineNumber)
 {
   mLineNumber = aLineNumber;
 }
 
-void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
-                                        nsTArray<nsString>& aResult)
+PRUint32 ToLinkMask(const nsAString& aLink)
+{ 
+  if (aLink.EqualsLiteral("prefetch"))
+     return PREFETCH;
+  else if (aLink.EqualsLiteral("dns-prefetch"))
+     return DNS_PREFETCH;
+  else if (aLink.EqualsLiteral("stylesheet"))
+    return STYLESHEET;
+  else if (aLink.EqualsLiteral("next"))
+    return NEXT;
+  else if (aLink.EqualsLiteral("alternate"))
+    return ALTERNATE;
+  else 
+    return 0;
+}
+
+PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
 {
+  PRUint32 linkMask = 0;
   nsAString::const_iterator start, done;
   aTypes.BeginReading(start);
   aTypes.EndReading(done);
   if (start == done)
-    return;
+    return linkMask;
 
   nsAString::const_iterator current(start);
   bool inString = !nsCRT::IsAsciiSpace(*current);
   nsAutoString subString;
-
+  
   while (current != done) {
     if (nsCRT::IsAsciiSpace(*current)) {
       if (inString) {
         ToLowerCase(Substring(start, current), subString);
-        aResult.AppendElement(subString);
+        linkMask |= ToLinkMask(subString);
         inString = false;
       }
     }
     else {
       if (!inString) {
         start = current;
         inString = true;
       }
     }
     ++current;
   }
   if (inString) {
     ToLowerCase(Substring(start, current), subString);
-    aResult.AppendElement(subString);
+     linkMask |= ToLinkMask(subString);
   }
+  return linkMask;
 }
 
 NS_IMETHODIMP
 nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
                                      bool* aWillNotify,
                                      bool* aIsAlternate)
 {
   return DoUpdateStyleSheet(nsnull, aObserver, aWillNotify, aIsAlternate,
--- a/content/base/src/nsStyleLinkElement.h
+++ b/content/base/src/nsStyleLinkElement.h
@@ -48,16 +48,22 @@
 
 #include "nsCOMPtr.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIStyleSheet.h"
 #include "nsIURI.h"
 #include "nsTArray.h"
 
+#define PREFETCH      0x00000001
+#define DNS_PREFETCH  0x00000002
+#define STYLESHEET    0x00000004
+#define NEXT          0x00000008
+#define ALTERNATE     0x00000010
+
 class nsIDocument;
 
 class nsStyleLinkElement : public nsIDOMLinkStyle,
                            public nsIStyleSheetLinkingElement
 {
 public:
   nsStyleLinkElement();
   virtual ~nsStyleLinkElement();
@@ -75,18 +81,18 @@ public:
                               bool* aWillNotify,
                               bool* aIsAlternate);
   NS_IMETHOD SetEnableUpdates(bool aEnableUpdates);
   NS_IMETHOD GetCharset(nsAString& aCharset);
 
   virtual void OverrideBaseURI(nsIURI* aNewBaseURI);
   virtual void SetLineNumber(PRUint32 aLineNumber);
 
-  static void ParseLinkTypes(const nsAString& aTypes, nsTArray<nsString>& aResult);
-
+  static PRUint32 ParseLinkTypes(const nsAString& aTypes);
+  
   void UpdateStyleSheetInternal() { UpdateStyleSheetInternal(nsnull); }
 protected:
   /**
    * @param aOldDocument should be non-null only if we're updating because we
    *                     removed the node from the document.
    * @param aForceUpdate true will force the update even if the URI has not
    *                     changed.  This should be used in cases when something
    *                     about the content that affects the resulting sheet
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -302,19 +302,18 @@ nsHTMLLinkElement::SetAttr(PRInt32 aName
   if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
     Link::ResetLinkState(!!aNotify);
   }
 
   if (NS_SUCCEEDED(rv)) {
     bool dropSheet = false;
     if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel &&
         GetStyleSheet()) {
-      nsAutoTArray<nsString, 4> linkTypes;
-      nsStyleLinkElement::ParseLinkTypes(aValue, linkTypes);
-      dropSheet = !linkTypes.Contains(NS_LITERAL_STRING("stylesheet"));
+      PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aValue);
+      dropSheet = !(linkTypes & STYLESHEET);          
     }
     
     UpdateStyleSheetInternal(nsnull,
                              dropSheet ||
                              (aNameSpaceID == kNameSpaceID_None &&
                               (aName == nsGkAtoms::title ||
                                aName == nsGkAtoms::media ||
                                aName == nsGkAtoms::type)));
@@ -408,31 +407,30 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsA
                                      bool* aIsAlternate)
 {
   aTitle.Truncate();
   aType.Truncate();
   aMedia.Truncate();
   *aIsAlternate = false;
 
   nsAutoString rel;
-  nsAutoTArray<nsString, 4> linkTypes;
   GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
-  nsStyleLinkElement::ParseLinkTypes(rel, linkTypes);
+  PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
   // Is it a stylesheet link?
-  if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
+  if (!(linkTypes & STYLESHEET)) {
     return;
   }
 
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
   aTitle.Assign(title);
 
   // If alternate, does it have title?
-  if (linkTypes.Contains(NS_LITERAL_STRING("alternate"))) {
+  if (linkTypes & ALTERNATE) {
     if (aTitle.IsEmpty()) { // alternates must have title
       return;
     } else {
       *aIsAlternate = true;
     }
   }
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -2639,28 +2639,26 @@ HTMLContentSink::ProcessLINKTag(const ns
         ++mPendingSheetCount;
         mScriptLoader->AddExecuteBlocker();
       }
 
       // look for <link rel="next" href="url">
       nsAutoString relVal;
       element->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
       if (!relVal.IsEmpty()) {
-        // XXX seems overkill to generate this string array
-        nsAutoTArray<nsString, 4> linkTypes;
-        nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
-        bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
-        if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
+        PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
+        bool hasPrefetch = linkTypes & PREFETCH;
+        if (hasPrefetch || (linkTypes & NEXT)) {
           nsAutoString hrefVal;
           element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
           if (!hrefVal.IsEmpty()) {
             PrefetchHref(hrefVal, element, hasPrefetch);
           }
         }
-        if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
+        if (linkTypes & DNS_PREFETCH) {
           nsAutoString hrefVal;
           element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
           if (!hrefVal.IsEmpty()) {
             PrefetchDNS(hrefVal);
           }
         }
       }
     }
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -641,28 +641,26 @@ nsXMLContentSink::CloseElement(nsIConten
       }
     }
     // Look for <link rel="dns-prefetch" href="hostname">
     // and look for <link rel="next" href="hostname"> like in HTML sink
     if (nodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
       nsAutoString relVal;
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
       if (!relVal.IsEmpty()) {
-        // XXX seems overkill to generate this string array
-        nsAutoTArray<nsString, 4> linkTypes;
-        nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
-        bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
-        if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
+        PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
+        bool hasPrefetch = linkTypes & PREFETCH;
+        if (hasPrefetch || (linkTypes & NEXT)) {
           nsAutoString hrefVal;
           aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
           if (!hrefVal.IsEmpty()) {
             PrefetchHref(hrefVal, aContent, hasPrefetch);
           }
         }
-        if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
+        if (linkTypes & DNS_PREFETCH) {
           nsAutoString hrefVal;
           aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
           if (!hrefVal.IsEmpty()) {
             PrefetchDNS(hrefVal);
           }
         }
       }
     }
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -340,28 +340,26 @@ nsHtml5TreeOpExecutor::UpdateStyleSheet(
     mScriptLoader->AddExecuteBlocker();
   }
 
   if (aElement->IsHTML(nsGkAtoms::link)) {
     // look for <link rel="next" href="url">
     nsAutoString relVal;
     aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
     if (!relVal.IsEmpty()) {
-      // XXX seems overkill to generate this string array
-      nsAutoTArray<nsString, 4> linkTypes;
-      nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
-      bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
-      if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
+      PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
+      bool hasPrefetch = linkTypes & PREFETCH;
+      if (hasPrefetch || (linkTypes & NEXT)) {
         nsAutoString hrefVal;
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
         if (!hrefVal.IsEmpty()) {
           PrefetchHref(hrefVal, aElement, hasPrefetch);
         }
       }
-      if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
+      if (linkTypes & DNS_PREFETCH) {
         nsAutoString hrefVal;
         aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
         if (!hrefVal.IsEmpty()) {
           PrefetchDNS(hrefVal);
         }
       }
     }
   }