Bug 1427512 - Part 24: Stop using XPCOM interfaces to access CSS property values in nsMenuItemIconX. r=mstange
MozReview-Commit-ID: HWsKlAQraO5
--- 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)
{