Bug 1302551 - Add AnonymousContent::SetCutoutRectsForElement to allow a more efficient find bar highlighter implementation. r?smaug draft
authorMarkus Stange <mstange@themasta.com>
Thu, 15 Sep 2016 14:58:15 -0400
changeset 414154 e36c208247a36e42b42d0c8aa39c9b77f4ddd7fe
parent 414153 240c327fa164c68d6f7ae7e572034715fc97ad59
child 414155 24e7920b7faa862e6fe5bebc2b1f0b8dc701e63c
push id29604
push userbmo:mstange@themasta.com
push dateThu, 15 Sep 2016 19:37:10 +0000
reviewerssmaug
bugs1302551
milestone51.0a1
Bug 1302551 - Add AnonymousContent::SetCutoutRectsForElement to allow a more efficient find bar highlighter implementation. r?smaug This part just sets a cutoutregion property on the element node and schedules a paint. The next part will check for that property and create a display item for the element in question. MozReview-Commit-ID: EbPr8it5Lpw
dom/base/AnonymousContent.cpp
dom/base/AnonymousContent.h
dom/base/nsGkAtomList.h
dom/webidl/AnonymousContent.webidl
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AnonymousContent.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/AnonymousContentBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsIDOMHTMLCollection.h"
+#include "nsIFrame.h"
 #include "nsStyledElement.h"
 #include "HTMLCanvasElement.h"
 
 namespace mozilla {
 namespace dom {
 
 // Ref counting and cycle collection
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnonymousContent, AddRef)
@@ -149,16 +150,43 @@ AnonymousContent::SetAnimationForElement
   if (!element) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return nullptr;
   }
 
   return element->Animate(aContext, aKeyframes, aOptions, aRv);
 }
 
+void
+AnonymousContent::SetCutoutRectsForElement(const nsAString& aElementId,
+                                           const Sequence<OwningNonNull<DOMRect>>& aRects,
+                                           ErrorResult& aRv)
+{
+  Element* element = GetElementById(aElementId);
+
+  if (!element) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return;
+  }
+
+  nsRegion cutOutRegion;
+  for (const auto& r : aRects) {
+    CSSRect rect(r->X(), r->Y(), r->Width(), r->Height());
+    cutOutRegion.OrWith(CSSRect::ToAppUnits(rect));
+  }
+
+  element->SetProperty(nsGkAtoms::cutoutregion, new nsRegion(cutOutRegion),
+                       nsINode::DeleteProperty<nsRegion>);
+
+  nsIFrame* frame = element->GetPrimaryFrame();
+  if (frame) {
+    frame->SchedulePaint();
+  }
+}
+
 Element*
 AnonymousContent::GetElementById(const nsAString& aElementId)
 {
   // This can be made faster in the future if needed.
   nsCOMPtr<nsIAtom> elementId = NS_Atomize(aElementId);
   for (nsIContent* node = mContentNode; node;
        node = node->GetNextNode(mContentNode)) {
     if (!node->IsElement()) {
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -59,16 +59,20 @@ public:
                                                  ErrorResult& aRv);
 
   already_AddRefed<Animation> SetAnimationForElement(JSContext* aContext,
                                                      const nsAString& aElementId,
                                                      JS::Handle<JSObject*> aKeyframes,
                                                      const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
                                                      ErrorResult& aError);
 
+  void SetCutoutRectsForElement(const nsAString& aElementId,
+                                const Sequence<OwningNonNull<DOMRect>>& aRects,
+                                ErrorResult& aError);
+
 private:
   ~AnonymousContent();
   nsCOMPtr<Element> mContentNode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -259,16 +259,17 @@ GK_ATOM(controls, "controls")
 GK_ATOM(coords, "coords")
 GK_ATOM(copy, "copy")
 GK_ATOM(copyOf, "copy-of")
 GK_ATOM(count, "count")
 GK_ATOM(crop, "crop")
 GK_ATOM(crossorigin, "crossorigin")
 GK_ATOM(curpos, "curpos")
 GK_ATOM(current, "current")
+GK_ATOM(cutoutregion, "cutoutregion")
 GK_ATOM(cycler, "cycler")
 GK_ATOM(data, "data")
 GK_ATOM(datalist, "datalist")
 GK_ATOM(dataType, "data-type")
 GK_ATOM(dateTime, "date-time")
 GK_ATOM(datasources, "datasources")
 GK_ATOM(datetime, "datetime")
 GK_ATOM(dblclick, "dblclick")
--- a/dom/webidl/AnonymousContent.webidl
+++ b/dom/webidl/AnonymousContent.webidl
@@ -62,9 +62,19 @@ interface AnonymousContent {
   nsISupports? getCanvasContext(DOMString elementId,
                                 DOMString contextId);
 
   [Func="nsDocument::IsElementAnimateEnabled", Throws]
   Animation setAnimationForElement(DOMString elementId,
                                    object? keyframes,
                                    optional UnrestrictedDoubleOrKeyframeAnimationOptions
                                      options);
+
+  /**
+   * Accepts a list of (possibly overlapping) DOMRects which describe a shape
+   * in CSS pixels relative to the element's border box. This shape will be
+   * excluded from the element's background color rendering. The element will
+   * not render any background images once this method has been called.
+   */
+  [Throws]
+  void setCutoutRectsForElement(DOMString elementId,
+                                sequence<DOMRect> rects);
 };