From 2f2740d6144ec484574899e0e81868a1b9c82714 Mon Sep 17 00:00:00 2001 From: Rik Cabanier Date: Fri, 21 Feb 2014 08:35:36 -0500 Subject: [PATCH] Bug 966591 - Part 2: Validate input to AddHitRegion. Provide partial implementation. r=roc --- .../canvas/src/CanvasRenderingContext2D.cpp | 32 ++++++++++++++++--- content/canvas/src/CanvasRenderingContext2D.h | 22 ++++++++++++- dom/webidl/CanvasRenderingContext2D.webidl | 2 +- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 36c98cf66fc..9aeb494a477 100755 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -2355,12 +2355,36 @@ CanvasRenderingContext2D::MeasureText(const nsAString& rawText, return new TextMetrics(width); } -void CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& ) -{} +void +CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& options, ErrorResult& error) +{ + // remove old hit region first + RemoveHitRegion(options.mId); -void CanvasRenderingContext2D::RemoveHitRegion(const nsAString&) -{} + // for now, we require a fallback element + if (options.mControl == NULL) { + error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } + // check if the control is a descendant of our canvas + HTMLCanvasElement* canvas = GetCanvas(); + if (!canvas || !nsContentUtils::ContentIsDescendantOf(options.mControl, canvas)) { + error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } + + // finally, add the region to the list if it has an ID + if (options.mId.Length() != 0) { + mHitRegionsOptions.PutEntry(options.mId)->mElement = options.mControl; + } +} + +void +CanvasRenderingContext2D::RemoveHitRegion(const nsAString& id) +{ + mHitRegionsOptions.RemoveEntry(id); +} /** * Used for nsBidiPresUtils::ProcessText diff --git a/content/canvas/src/CanvasRenderingContext2D.h b/content/canvas/src/CanvasRenderingContext2D.h index 263058bba7b..314ab5e2be1 100644 --- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -186,7 +186,7 @@ public: TextMetrics* MeasureText(const nsAString& rawText, mozilla::ErrorResult& error); - void AddHitRegion(const HitRegionOptions& options); + void AddHitRegion(const HitRegionOptions& options, mozilla::ErrorResult& error); void RemoveHitRegion(const nsAString& id); void DrawImage(const HTMLImageOrCanvasOrVideoElement& image, @@ -684,6 +684,26 @@ protected: uint32_t mInvalidateCount; static const uint32_t kCanvasMaxInvalidateCount = 100; + /** + * State information for hit regions + */ + + struct RegionInfo : public nsStringHashKey + { + RegionInfo(const nsAString& aKey) : + nsStringHashKey(&aKey) + { + } + RegionInfo(const nsAString *aKey) : + nsStringHashKey(aKey) + { + } + + nsRefPtr mElement; + }; + + nsTHashtable mHitRegionsOptions; + /** * Returns true if a shadow should be drawn along with a * drawing operation. diff --git a/dom/webidl/CanvasRenderingContext2D.webidl b/dom/webidl/CanvasRenderingContext2D.webidl index 565f34477a7..18598cee182 100644 --- a/dom/webidl/CanvasRenderingContext2D.webidl +++ b/dom/webidl/CanvasRenderingContext2D.webidl @@ -116,7 +116,7 @@ interface CanvasRenderingContext2D { void drawImage((HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh); // hit regions - [Pref="canvas.hitregions.enabled"] void addHitRegion(optional HitRegionOptions options); + [Pref="canvas.hitregions.enabled", Throws] void addHitRegion(optional HitRegionOptions options); [Pref="canvas.hitregions.enabled"] void removeHitRegion(DOMString id); // pixel manipulation