Bug 1319908 - Load the menu icons for the bookmarks menu with the correct content type and principal on OSX; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 14 Dec 2016 15:52:57 -0500
changeset 330371 5021d272e95361f4f3a2900e8b5827158d306fe1
parent 330370 f5773f7823898e84a05a6900f0fddead497f696d
child 330372 46225906354e6a74c04c15cce5243d82daf2f092
push id31238
push userphilringnalda@gmail.com
push dateSat, 21 Jan 2017 03:00:22 +0000
treeherdermozilla-central@487a4e43eb9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1319908, 1277803
milestone53.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 1319908 - Load the menu icons for the bookmarks menu with the correct content type and principal on OSX; r=baku This patch makes nsMenuItemIconX also participate in the setup introduced in bug 1277803.
browser/base/content/browser-places.js
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
layout/xul/nsImageBoxFrame.cpp
widget/cocoa/nsMenuItemIconX.h
widget/cocoa/nsMenuItemIconX.mm
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -1476,16 +1476,20 @@ var BookmarkingUI = {
 
     let options = PlacesUtils.history.getNewQueryOptions();
     options.excludeQueries = true;
     options.queryType = options.QUERY_TYPE_BOOKMARKS;
     options.sortingMode = options.SORT_BY_DATEADDED_DESCENDING;
     options.maxResults = kMaxResults;
     let query = PlacesUtils.history.getNewQuery();
 
+    let sh = Cc["@mozilla.org/network/serialization-helper;1"]
+               .getService(Ci.nsISerializationHelper);
+    let loadingPrincipal = sh.serializeToString(document.nodePrincipal);
+
     let fragment = document.createDocumentFragment();
     let root = PlacesUtils.history.executeQuery(query, options).root;
     root.containerOpen = true;
     for (let i = 0; i < root.childCount; i++) {
       let node = root.getChild(i);
       let uri = node.uri;
       let title = node.title;
       let icon = node.icon;
@@ -1495,16 +1499,17 @@ var BookmarkingUI = {
                                  "menuitem");
       item.setAttribute("label", title || uri);
       item.setAttribute("targetURI", uri);
       item.setAttribute("simulated-places-node", true);
       item.setAttribute("class", "menuitem-iconic menuitem-with-favicon bookmark-item " +
                                  aExtraCSSClass);
       if (icon) {
         item.setAttribute("image", icon);
+        item.setAttribute("loadingprincipal", loadingPrincipal);
       }
       item._placesNode = node;
       fragment.appendChild(item);
     }
     root.containerOpen = false;
     aHeaderItem.parentNode.insertBefore(fragment, aHeaderItem.nextSibling);
   },
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -184,16 +184,17 @@
 #include "nsParserCIID.h"
 #include "nsParserConstants.h"
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 #include "nsPrintfCString.h"
 #include "nsReferencedElement.h"
 #include "nsSandboxFlags.h"
 #include "nsScriptSecurityManager.h"
+#include "nsSerializationHelper.h"
 #include "nsStreamUtils.h"
 #include "nsTextEditorState.h"
 #include "nsTextFragment.h"
 #include "nsTextNode.h"
 #include "nsThreadUtils.h"
 #include "nsUnicharUtilCIID.h"
 #include "nsUnicodeProperties.h"
 #include "nsViewManager.h"
@@ -9774,8 +9775,38 @@ nsContentUtils::AppendDocumentLevelNativ
     if (nsIFrame* scrollFrame = presShell->GetRootScrollFrame()) {
       nsIAnonymousContentCreator* creator = do_QueryFrame(scrollFrame);
       MOZ_ASSERT(creator,
                  "scroll frame should always implement nsIAnonymousContentCreator");
       creator->AppendAnonymousContentTo(aElements, 0);
     }
   }
 }
+
+/* static */ void
+nsContentUtils::GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
+                                                      nsIPrincipal** aLoadingPrincipal,
+                                                      nsContentPolicyType& aContentPolicyType)
+{
+  // Use the serialized loadingPrincipal from the image element. Fall back
+  // to mContent's principal (SystemPrincipal) if not available.
+  aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
+  nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingNode->NodePrincipal();
+  nsAutoString imageLoadingPrincipal;
+  aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
+                        imageLoadingPrincipal);
+  if (!imageLoadingPrincipal.IsEmpty()) {
+    nsCOMPtr<nsISupports> serializedPrincipal;
+    NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
+                         getter_AddRefs(serializedPrincipal));
+    loadingPrincipal = do_QueryInterface(serializedPrincipal);
+
+    if (loadingPrincipal) {
+      // Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
+      // indicating it's a favicon loading.
+      aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
+    } else {
+      // Fallback if the deserialization is failed.
+      loadingPrincipal = aLoadingNode->NodePrincipal();
+    }
+  }
+  loadingPrincipal.forget(aLoadingPrincipal);
+}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2738,16 +2738,26 @@ public:
    * aDocument to aElements.  Document level NAC subtrees are those created
    * by ancestor frames of the document element's primary frame, such as
    * the scrollbar elements created by the root scroll frame.
    */
   static void AppendDocumentLevelNativeAnonymousContentTo(
       nsIDocument* aDocument,
       nsTArray<nsIContent*>& aElements);
 
+  /**
+   * Returns the content policy type that should be used for loading images
+   * for displaying in the UI.  The sources of such images can be <xul:image>,
+   * <xul:menuitem> on OSX where we load the image through nsMenuItemIconX, etc.
+   */
+  static void
+  GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
+                                        nsIPrincipal** aLoadingPrincipal,
+                                        nsContentPolicyType& aContentPolicyType);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -43,17 +43,16 @@
 #include "nsIURI.h"
 #include "nsThreadUtils.h"
 #include "nsDisplayList.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
 #include "nsIContent.h"
 
 #include "nsContentUtils.h"
-#include "nsSerializationHelper.h"
 
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Maybe.h"
 
 #define ONLOAD_CALLED_TOO_EARLY 1
 
 using namespace mozilla;
@@ -222,38 +221,21 @@ nsImageBoxFrame::UpdateImage()
 
   // get the new image src
   nsAutoString src;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
   mUseSrcAttr = !src.IsEmpty();
   if (mUseSrcAttr) {
     nsIDocument* doc = mContent->GetComposedDoc();
     if (doc) {
-      // Use the serialized loadingPrincipal from the image element. Fall back
-      // to mContent's principal (SystemPrincipal) if not available.
-      nsContentPolicyType contentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
-      nsCOMPtr<nsIPrincipal> loadingPrincipal = mContent->NodePrincipal();
-      nsAutoString imageLoadingPrincipal;
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
-                        imageLoadingPrincipal);
-      if (!imageLoadingPrincipal.IsEmpty()) {
-        nsCOMPtr<nsISupports> serializedPrincipal;
-        NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
-                             getter_AddRefs(serializedPrincipal));
-        loadingPrincipal = do_QueryInterface(serializedPrincipal);
-
-        if (loadingPrincipal) {
-          // Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
-          // indicating it's a favicon loading.
-          contentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
-        } else {
-          // Fallback if the deserialization is failed.
-          loadingPrincipal = mContent->NodePrincipal();
-        }
-      }
+      nsContentPolicyType contentPolicyType;
+      nsCOMPtr<nsIPrincipal> loadingPrincipal;
+      nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,
+                                                            getter_AddRefs(loadingPrincipal),
+                                                            contentPolicyType);
 
       nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
       nsCOMPtr<nsIURI> uri;
       nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                                 src,
                                                 doc,
                                                 baseURI);
       if (uri) {
--- a/widget/cocoa/nsMenuItemIconX.h
+++ b/widget/cocoa/nsMenuItemIconX.h
@@ -8,16 +8,17 @@
  */
 
 #ifndef nsMenuItemIconX_h_
 #define nsMenuItemIconX_h_
 
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "imgINotificationObserver.h"
+#include "nsIContentPolicy.h"
 
 class nsIURI;
 class nsIContent;
 class imgRequestProxy;
 class nsMenuObjectX;
 
 #import <Cocoa/Cocoa.h>
 
@@ -50,16 +51,18 @@ public:
   // Destroy() should be called from mMenuObject's destructor to prevent
   // this from happening.  See bug 499600.
   void Destroy();
 
 protected:
   nsresult OnFrameComplete(imgIRequest* aRequest);
 
   nsCOMPtr<nsIContent>      mContent;
+  nsCOMPtr<nsIPrincipal>    mLoadingPrincipal;
+  nsContentPolicyType       mContentType;
   RefPtr<imgRequestProxy> mIconRequest;
   nsMenuObjectX*            mMenuObject; // [weak]
   nsIntRect                 mImageRegionRect;
   bool                      mLoadedIcon;
   bool                      mSetIcon;
   NSMenuItem*               mNativeMenuItem; // [weak]
 };
 
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -54,16 +54,18 @@ typedef NS_STDCALL_FUNCPROTO(nsresult, G
                              GetBottom, (nsIDOMCSSPrimitiveValue**));
 
 NS_IMPL_ISUPPORTS(nsMenuItemIconX, imgINotificationObserver)
 
 nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem,
                                  nsIContent*    aContent,
                                  NSMenuItem*    aNativeMenuItem)
 : mContent(aContent)
+, mLoadingPrincipal(aContent->NodePrincipal())
+, mContentType(nsIContentPolicy::TYPE_INTERNAL_IMAGE)
 , mMenuObject(aMenuItem)
 , mLoadedIcon(false)
 , mSetIcon(false)
 , mNativeMenuItem(aNativeMenuItem)
 {
   //  printf("Creating icon for menu item %d, menu %d, native item is %d\n", aMenuItem, aMenu, aNativeMenuItem);
 }
 
@@ -204,16 +206,20 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIc
 
     rv = primitiveValue->GetPrimitiveType(&primitiveType);
     if (NS_FAILED(rv)) return rv;
     if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_URI)
       return NS_ERROR_FAILURE;
 
     rv = primitiveValue->GetStringValue(imageURIString);
     if (NS_FAILED(rv)) return rv;
+  } else {
+    nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,
+                                                          getter_AddRefs(mLoadingPrincipal),
+                                                          mContentType);
   }
 
   // Empty the mImageRegionRect initially as the image region CSS could
   // have been changed and now have an error or have been removed since the
   // last GetIconURI call.
   mImageRegionRect.SetEmpty();
 
   // If this menu item shouldn't have an icon, the string will be empty,
@@ -306,19 +312,19 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconU
     if (!sPlaceholderIconImage) return NS_ERROR_FAILURE;
 
     if (mNativeMenuItem)
       [mNativeMenuItem setImage:sPlaceholderIconImage];
   }
 
   nsresult rv = loader->LoadImage(aIconURI, nullptr, nullptr,
                                   mozilla::net::RP_Unset,
-                                  nullptr, loadGroup, this,
-                                  nullptr, nullptr, nsIRequest::LOAD_NORMAL, nullptr,
-                                  nsIContentPolicy::TYPE_INTERNAL_IMAGE, EmptyString(),
+                                  mLoadingPrincipal, loadGroup, this,
+                                  mContent, document, nsIRequest::LOAD_NORMAL, nullptr,
+                                  mContentType, EmptyString(),
                                   getter_AddRefs(mIconRequest));
   if (NS_FAILED(rv)) return rv;
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }