Bug 1500768 - Implement SVGImageElement support for createImageBitmap, r=jwatt

This commit is contained in:
Andrea Marchesini 2018-10-25 14:55:06 +02:00
Родитель 887b24a77f
Коммит 25bff22bd6
7 изменённых файлов: 53 добавлений и 48 удалений

Просмотреть файл

@ -438,7 +438,7 @@ private:
};
static bool
CheckSecurityForHTMLElements(bool aIsWriteOnly, bool aCORSUsed, nsIPrincipal* aPrincipal)
CheckSecurityForElements(bool aIsWriteOnly, bool aCORSUsed, nsIPrincipal* aPrincipal)
{
if (aIsWriteOnly || !aPrincipal) {
return false;
@ -460,24 +460,24 @@ CheckSecurityForHTMLElements(bool aIsWriteOnly, bool aCORSUsed, nsIPrincipal* aP
}
static bool
CheckSecurityForHTMLElements(const nsLayoutUtils::SurfaceFromElementResult& aRes)
CheckSecurityForElements(const nsLayoutUtils::SurfaceFromElementResult& aRes)
{
return CheckSecurityForHTMLElements(aRes.mIsWriteOnly, aRes.mCORSUsed, aRes.mPrincipal);
return CheckSecurityForElements(aRes.mIsWriteOnly, aRes.mCORSUsed, aRes.mPrincipal);
}
/*
* A wrapper to the nsLayoutUtils::SurfaceFromElement() function followed by the
* security checking.
*/
template<class HTMLElementType>
template<class ElementType>
static already_AddRefed<SourceSurface>
GetSurfaceFromElement(nsIGlobalObject* aGlobal, HTMLElementType& aElement, ErrorResult& aRv)
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResult& aRv)
{
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE);
// check origin-clean
if (!CheckSecurityForHTMLElements(res)) {
if (!CheckSecurityForElements(res)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
@ -494,11 +494,12 @@ GetSurfaceFromElement(nsIGlobalObject* aGlobal, HTMLElementType& aElement, Error
/*
* The specification doesn't allow to create an ImegeBitmap from a vector image.
* This function is used to check if the given HTMLImageElement contains a
* This function is used to check if the given Image Element contains a
* raster image.
*/
template<class ElementType>
static bool
HasRasterImage(HTMLImageElement& aImageEl)
HasRasterImage(ElementType& aImageEl)
{
nsresult rv;
@ -892,6 +893,36 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
return ret.forget();
}
/* static */ already_AddRefed<ImageBitmap>
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
{
// Get the SourceSurface out from the image element and then do security
// checking.
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Create ImageBitmap.
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
if (NS_WARN_IF(!data)) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
// Set the picture rectangle.
if (ret && aCropRect.isSome()) {
ret->SetPictureRect(aCropRect.ref(), aRv);
}
return ret.forget();
}
/* static */ already_AddRefed<ImageBitmap>
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
@ -914,7 +945,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
// Check security.
nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal();
bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE;
if (!CheckSecurityForHTMLElements(false, CORSUsed, principal)) {
if (!CheckSecurityForElements(false, CORSUsed, principal)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
@ -1373,6 +1404,10 @@ ImageBitmap::Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc,
MOZ_ASSERT(NS_IsMainThread(),
"Creating ImageBitmap from HTMLImageElement off the main thread.");
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLImageElement(), aCropRect, aRv);
} else if (aSrc.IsSVGImageElement()) {
MOZ_ASSERT(NS_IsMainThread(),
"Creating ImageBitmap from SVGImageElement off the main thread.");
imageBitmap = CreateInternal(aGlobal, aSrc.GetAsSVGImageElement(), aCropRect, aRv);
} else if (aSrc.IsHTMLVideoElement()) {
MOZ_ASSERT(NS_IsMainThread(),
"Creating ImageBitmap from HTMLVideoElement off the main thread.");

Просмотреть файл

@ -48,12 +48,12 @@ class File;
class HTMLCanvasElement;
class HTMLImageElement;
class HTMLVideoElement;
enum class ImageBitmapFormat : uint8_t;
class ImageBitmapShutdownObserver;
class ImageData;
class ImageUtils;
class Promise;
class PostMessageEvent; // For StructuredClone between windows.
class ImageBitmapShutdownObserver;
class SVGImageElement;
struct ImageBitmapCloneData final
{
@ -184,6 +184,10 @@ protected:
CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
static already_AddRefed<ImageBitmap>
CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
static already_AddRefed<ImageBitmap>
CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);

Просмотреть файл

@ -11,8 +11,8 @@ namespace mozilla {
namespace dom {
// So we don't have to forward declare this elsewhere.
class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData;
typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource;
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData;
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource;
}
}

Просмотреть файл

@ -10,14 +10,7 @@
* http://w3c.github.io/mediacapture-worker/#imagebitmap-extensions
*/
// This is needed because we don't support SVG element as canvas image source.
// See bug 1500768.
typedef (HTMLImageElement or
HTMLCanvasElement or
HTMLVideoElement or
ImageBitmap) CanvasImageSourceExcludedSVG;
typedef (CanvasImageSourceExcludedSVG or
typedef (CanvasImageSource or
Blob or
CanvasRenderingContext2D or // This is out of spec.
ImageData) ImageBitmapSource;

Просмотреть файл

@ -14,12 +14,6 @@
[createImageBitmap from a vector HTMLImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a bitmap SVGImageElement, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a bitmap SVGImageElement with negative sw/sh, and drawImage on the created ImageBitmap]
expected: FAIL
[createImageBitmap from a vector SVGImageElement, and drawImage on the created ImageBitmap]
expected: FAIL

Просмотреть файл

@ -16,24 +16,6 @@
[createImageBitmap with an available but undecodable image source.]
expected: FAIL
[createImageBitmap with a bitmap SVGImageElement source and sw set to 0]
expected: FAIL
[createImageBitmap with a bitmap SVGImageElement source and sh set to 0]
expected: FAIL
[createImageBitmap with a vector SVGImageElement source and sw set to 0]
expected: FAIL
[createImageBitmap with a vector SVGImageElement source and sh set to 0]
expected: FAIL
[createImageBitmap with CanvasRenderingContext2D image source.]
expected: FAIL
[createImageBitmap with a bitmap SVGImageElement source and oversized (unallocatable) crop region]
expected: FAIL
[createImageBitmap with a vector SVGImageElement source and oversized (unallocatable) crop region]
expected: FAIL

Просмотреть файл

@ -2,9 +2,6 @@
[Transfer ImageBitmap created from a vector HTMLImageElement]
expected: FAIL
[Transfer ImageBitmap created from a bitmap SVGImageElement]
expected: FAIL
[Transfer ImageBitmap created from a vector SVGImageElement]
expected: FAIL