Bug 1427512 - Part 24: Stop using XPCOM interfaces to access CSS property values in nsMenuItemIconX. r=mstange draft
authorCameron McCormack <cam@mcc.id.au>
Tue, 02 Jan 2018 19:48:29 +1100
changeset 717725 1d6e33efe9fb3efe6c34aedf735f033d4bdef5b0
parent 717724 576601ef0861b2f6f8bf2cdda992ae0b9768f527
child 717726 0bafa141fecb81fd922f77900d83b78dedb5d4da
push id94746
push userbmo:cam@mcc.id.au
push dateTue, 09 Jan 2018 10:21:54 +0000
reviewersmstange
bugs1427512
milestone59.0a1
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)
 {