Bug 1427512 - Part 24: Stop using XPCOM interfaces to access CSS property values in nsMenuItemIconX. r=mstange
authorCameron McCormack <cam@mcc.id.au>
Thu, 11 Jan 2018 16:17:57 +0800
changeset 453078 7e658c088e7efe6055734f281aac3abe6f01b7b2
parent 453077 655a30bc61ef74395b8edf18030ddd45851fcaa1
child 453079 fc78bb882bacc3fc7175101de2e5f7905866982b
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1427512
milestone59.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 1427512 - Part 24: Stop using XPCOM interfaces to access CSS property values in nsMenuItemIconX. r=mstange MozReview-Commit-ID: HWsKlAQraO5
widget/cocoa/nsMenuItemIconX.mm
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -23,40 +23,35 @@
 
 #include "nsMenuItemIconX.h"
 #include "nsObjCExceptions.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsNameSpaceManager.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMElement.h"
-#include "nsICSSDeclaration.h"
-#include "nsIDOMCSSValue.h"
-#include "nsIDOMCSSPrimitiveValue.h"
-#include "nsIDOMRect.h"
 #include "nsThreadUtils.h"
 #include "nsToolkit.h"
 #include "nsNetUtil.h"
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
 #include "nsMenuItemX.h"
 #include "gfxPlatform.h"
 #include "imgIContainer.h"
 #include "nsCocoaUtils.h"
 #include "nsContentUtils.h"
 #include "nsIContentPolicy.h"
+#include "nsComputedDOMStyle.h"
 
 using mozilla::dom::Element;
 using mozilla::gfx::SourceSurface;
 
 static const uint32_t kIconWidth = 16;
 static const uint32_t kIconHeight = 16;
 
-typedef decltype(&nsIDOMRect::GetBottom) GetRectSideMethod;
-
 NS_IMPL_ISUPPORTS(nsMenuItemIconX, imgINotificationObserver)
 
 nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem,
                                  nsIContent*    aContent,
                                  NSMenuItem*    aNativeMenuItem)
 : mContent(aContent)
 , mTriggeringPrincipal(aContent->NodePrincipal())
 , mContentType(nsIContentPolicy::TYPE_INTERNAL_IMAGE)
@@ -115,38 +110,16 @@ nsMenuItemIconX::SetupIcon()
     // been set.  Clear it.
     [mNativeMenuItem setImage:nil];
   }
   return rv;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
-static int32_t
-GetDOMRectSide(nsIDOMRect* aRect, GetRectSideMethod aMethod)
-{
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> dimensionValue;
-  (aRect->*aMethod)(getter_AddRefs(dimensionValue));
-  if (!dimensionValue)
-    return -1;
-
-  uint16_t primitiveType;
-  nsresult rv = dimensionValue->GetPrimitiveType(&primitiveType);
-  if (NS_FAILED(rv) || primitiveType != nsIDOMCSSPrimitiveValue::CSS_PX)
-    return -1;
-
-  float dimension = 0;
-  rv = dimensionValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_PX,
-                                     &dimension);
-  if (NS_FAILED(rv))
-    return -1;
-
-  return NSToIntRound(dimension);
-}
-
 nsresult
 nsMenuItemIconX::GetIconURI(nsIURI** aIconURI)
 {
   if (!mMenuObject)
     return NS_ERROR_FAILURE;
 
   // Mac native menu items support having both a checkmark and an icon
   // simultaneously, but this is unheard of in the cross-platform toolkit,
@@ -167,113 +140,68 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIc
   nsAutoString imageURIString;
   bool hasImageAttr =
     mContent->IsElement() &&
     mContent->AsElement()->GetAttr(kNameSpaceID_None,
                                    nsGkAtoms::image,
                                    imageURIString);
 
   nsresult rv;
-  nsCOMPtr<nsIDOMCSSValue> cssValue;
-  nsCOMPtr<nsICSSDeclaration> cssStyleDecl;
-  nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue;
-  uint16_t primitiveType;
+  RefPtr<nsStyleContext> sc;
+  nsCOMPtr<nsIURI> iconURI;
   if (!hasImageAttr) {
     // If the content node has no "image" attribute, get the
     // "list-style-image" property from CSS.
     nsCOMPtr<nsIDocument> document = mContent->GetComposedDoc();
-    if (!document)
-      return NS_ERROR_FAILURE;
-
-    nsCOMPtr<nsPIDOMWindowInner> window = document->GetInnerWindow();
-    if (!window)
-      return NS_ERROR_FAILURE;
-
-    nsCOMPtr<Element> domElement = do_QueryInterface(mContent);
-    if (!domElement)
-      return NS_ERROR_FAILURE;
-
-    ErrorResult dummy;
-    cssStyleDecl = window->GetComputedStyle(*domElement, EmptyString(), dummy);
-    dummy.SuppressException();
-    if (!cssStyleDecl)
+    if (!document || !mContent->IsElement()) {
       return NS_ERROR_FAILURE;
-
-    NS_NAMED_LITERAL_STRING(listStyleImage, "list-style-image");
-    rv = cssStyleDecl->GetPropertyCSSValue(listStyleImage,
-                                           getter_AddRefs(cssValue));
-    if (NS_FAILED(rv)) return rv;
+    }
 
-    primitiveValue = do_QueryInterface(cssValue);
-    if (!primitiveValue) return NS_ERROR_FAILURE;
+    sc = nsComputedDOMStyle::GetStyleContext(mContent->AsElement(), nullptr,
+                                             document->GetShell());
+    if (!sc) {
+      return NS_ERROR_FAILURE;
+    }
 
-    rv = primitiveValue->GetPrimitiveType(&primitiveType);
-    if (NS_FAILED(rv)) return rv;
-    if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_URI)
+    iconURI = sc->StyleList()->GetListStyleImageURI();
+    if (!iconURI) {
       return NS_ERROR_FAILURE;
-
-    rv = primitiveValue->GetStringValue(imageURIString);
-    if (NS_FAILED(rv)) return rv;
+    }
   } else {
     uint64_t dummy = 0;
     nsContentUtils::GetContentPolicyTypeForUIImageLoading(mContent,
                                                           getter_AddRefs(mTriggeringPrincipal),
                                                           mContentType,
                                                           &dummy);
+
+    // If this menu item shouldn't have an icon, the string will be empty,
+    // and NS_NewURI will fail.
+    rv = NS_NewURI(getter_AddRefs(iconURI), imageURIString);
+    if (NS_FAILED(rv)) return rv;
   }
 
   // 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,
-  // and NS_NewURI will fail.
-  nsCOMPtr<nsIURI> iconURI;
-  rv = NS_NewURI(getter_AddRefs(iconURI), imageURIString);
-  if (NS_FAILED(rv)) return rv;
-
-  *aIconURI = iconURI;
-  NS_ADDREF(*aIconURI);
+  iconURI.forget(aIconURI);
 
   if (!hasImageAttr) {
     // Check if the icon has a specified image region so that it can be
     // cropped appropriately before being displayed.
-    NS_NAMED_LITERAL_STRING(imageRegion, "-moz-image-region");
-    rv = cssStyleDecl->GetPropertyCSSValue(imageRegion,
-                                           getter_AddRefs(cssValue));
-    // Just return NS_OK if there if there is a failure due to no
-    // moz-image region specified so the whole icon will be drawn anyway.
-    if (NS_FAILED(rv)) return NS_OK;
-
-    primitiveValue = do_QueryInterface(cssValue);
-    if (!primitiveValue) return NS_OK;
-
-    rv = primitiveValue->GetPrimitiveType(&primitiveType);
-    if (NS_FAILED(rv)) return NS_OK;
-    if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_RECT)
-      return NS_OK;
+    const nsRect& r = sc->StyleList()->mImageRegion;
 
-    nsCOMPtr<nsIDOMRect> imageRegionRect;
-    rv = primitiveValue->GetRectValue(getter_AddRefs(imageRegionRect));
-    if (NS_FAILED(rv)) return NS_OK;
+    // Return NS_ERROR_FAILURE if the image region is invalid so the image
+    // is not drawn, and behavior is similar to XUL menus.
+    if (r.X() < 0 || r.Y() < 0 || r.IsEmpty()) {
+      return NS_ERROR_FAILURE;
+    }
 
-    if (imageRegionRect) {
-      // Return NS_ERROR_FAILURE if the image region is invalid so the image
-      // is not drawn, and behavior is similar to XUL menus.
-      int32_t bottom = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetBottom);
-      int32_t right = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetRight);
-      int32_t top = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetTop);
-      int32_t left = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetLeft);
-
-      if (top < 0 || left < 0 || bottom <= top || right <= left)
-        return NS_ERROR_FAILURE;
-
-      mImageRegionRect.SetRect(left, top, right - left, bottom - top);
-    }
+    mImageRegionRect = r.ToNearestPixels(mozilla::AppUnitsPerCSSPixel());
   }
 
   return NS_OK;
 }
 
 nsresult
 nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
 {