diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 36c98cf66fc8..9aeb494a477a 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 263058bba7be..314ab5e2be13 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 565f34477a73..18598cee1828 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