Bug 825527 - Part 3: Move HTMLImageElement to WebIDL bindings; r=bzbarsky
authorEhsan Akhgari <ehsan@mozilla.com>
Mon, 31 Dec 2012 13:48:55 -0500
changeset 126539 df5bcdcadfba2f6ac5b91277077da03a24695211
parent 126538 e3a0ca11961e35b4805ee195ade676032d8ca65a
child 126540 4e9da4e344529bad782cf3484fe5fac575c98ebb
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs825527
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 825527 - Part 3: Move HTMLImageElement to WebIDL bindings; r=bzbarsky
content/canvas/src/WebGLContext.h
content/html/content/src/HTMLImageElement.cpp
content/html/content/src/HTMLImageElement.h
content/html/content/src/nsGenericHTMLElement.h
content/html/content/test/reflect.js
dom/webidl/HTMLImageElement.webidl
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -545,17 +545,17 @@ public:
     void TexImage2D(WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
                     dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexImage2D
     template<class ElementType>
     void TexImage2D(WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
-                    ElementType* elt, ErrorResult& rv) {
+                    const ElementType& elt, ErrorResult& rv) {
         if (!IsContextStable())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
                                                     &srcFormat);
         if (rv.Failed())
@@ -582,17 +582,17 @@ public:
     void TexSubImage2D(WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
                        WebGLenum type, dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexSubImage2D
     template<class ElementType>
     void TexSubImage2D(WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
-                       WebGLenum type, ElementType* elt, ErrorResult& rv) {
+                       WebGLenum type, const ElementType& elt, ErrorResult& rv) {
         if (!IsContextStable())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
                                                     &srcFormat);
         if (rv.Failed())
@@ -981,16 +981,20 @@ protected:
             nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
 
         if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
             flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
         if (!mPixelStorePremultiplyAlpha)
             flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
         return nsLayoutUtils::SurfaceFromElement(aElement, flags);
     }
+    template<class ElementType>
+    nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(const dom::NonNull<ElementType>& aElement) {
+      return SurfaceFromElement(aElement.get());
+    }
 
     nsresult SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
                                                     gfxImageSurface **imageOut,
                                                     WebGLTexelFormat *format);
 
     void CopyTexSubImage2D_base(WebGLenum target,
                                 WebGLint level,
                                 WebGLenum internalformat,
--- a/content/html/content/src/HTMLImageElement.cpp
+++ b/content/html/content/src/HTMLImageElement.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
 #include "mozilla/dom/HTMLImageElement.h"
+#include "mozilla/dom/HTMLImageElementBinding.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsMappedAttributes.h"
 #include "nsSize.h"
 #include "nsIDocument.h"
 #include "nsIScriptContext.h"
@@ -134,31 +135,36 @@ NS_IMPL_STRING_ATTR(HTMLImageElement, Cr
 bool
 HTMLImageElement::Draggable() const
 {
   // images may be dragged unless the draggable attribute is false
   return !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
                       nsGkAtoms::_false, eIgnoreCase);
 }
 
+bool
+HTMLImageElement::Complete()
+{
+  if (!mCurrentRequest) {
+    return true;
+  }
+
+  uint32_t status;
+  mCurrentRequest->GetImageStatus(&status);
+  return
+    (status &
+     (imgIRequest::STATUS_LOAD_COMPLETE | imgIRequest::STATUS_ERROR)) != 0;
+}
+
 NS_IMETHODIMP
 HTMLImageElement::GetComplete(bool* aComplete)
 {
   NS_PRECONDITION(aComplete, "Null out param!");
-  *aComplete = true;
 
-  if (!mCurrentRequest) {
-    return NS_OK;
-  }
-
-  uint32_t status;
-  mCurrentRequest->GetImageStatus(&status);
-  *aComplete =
-    (status &
-     (imgIRequest::STATUS_LOAD_COMPLETE | imgIRequest::STATUS_ERROR)) != 0;
+  *aComplete = Complete();
 
   return NS_OK;
 }
 
 nsIntPoint
 HTMLImageElement::GetXY()
 {
   nsIntPoint point(0, 0);
@@ -192,31 +198,31 @@ HTMLImageElement::GetY(int32_t* aY)
   *aY = GetXY().y;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLImageElement::GetHeight(uint32_t* aHeight)
 {
-  *aHeight = GetWidthHeightForImage(mCurrentRequest).height;
+  *aHeight = Height();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLImageElement::SetHeight(uint32_t aHeight)
 {
   return nsGenericHTMLElement::SetUnsignedIntAttr(nsGkAtoms::height, aHeight);
 }
 
 NS_IMETHODIMP
 HTMLImageElement::GetWidth(uint32_t* aWidth)
 {
-  *aWidth = GetWidthHeightForImage(mCurrentRequest).width;
+  *aWidth = Width();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLImageElement::SetWidth(uint32_t aWidth)
 {
   return nsGenericHTMLElement::SetUnsignedIntAttr(nsGkAtoms::width, aWidth);
@@ -477,61 +483,73 @@ HTMLImageElement::Initialize(nsISupports
     NS_ENSURE_TRUE(ret, NS_ERROR_INVALID_ARG);
 
     rv = SetIntAttr(nsGkAtoms::height, static_cast<int32_t>(height));
   }
 
   return rv;
 }
 
+uint32_t
+HTMLImageElement::NaturalHeight()
+{
+  if (!mCurrentRequest) {
+    return 0;
+  }
+
+  nsCOMPtr<imgIContainer> image;
+  mCurrentRequest->GetImage(getter_AddRefs(image));
+  if (!image) {
+    return 0;
+  }
+
+  int32_t height;
+  if (NS_SUCCEEDED(image->GetHeight(&height))) {
+    return height;
+  }
+  return 0;
+}
+
 NS_IMETHODIMP
 HTMLImageElement::GetNaturalHeight(uint32_t* aNaturalHeight)
 {
   NS_ENSURE_ARG_POINTER(aNaturalHeight);
 
-  *aNaturalHeight = 0;
+  *aNaturalHeight = NaturalHeight();
 
+  return NS_OK;
+}
+
+uint32_t
+HTMLImageElement::NaturalWidth()
+{
   if (!mCurrentRequest) {
-    return NS_OK;
+    return 0;
   }
-  
+
   nsCOMPtr<imgIContainer> image;
   mCurrentRequest->GetImage(getter_AddRefs(image));
   if (!image) {
-    return NS_OK;
+    return 0;
   }
 
-  int32_t height;
-  if (NS_SUCCEEDED(image->GetHeight(&height))) {
-    *aNaturalHeight = height;
+  int32_t width;
+  if (NS_SUCCEEDED(image->GetWidth(&width))) {
+    return width;
   }
-  return NS_OK;
+  return 0;
 }
 
 NS_IMETHODIMP
 HTMLImageElement::GetNaturalWidth(uint32_t* aNaturalWidth)
 {
   NS_ENSURE_ARG_POINTER(aNaturalWidth);
 
-  *aNaturalWidth = 0;
+  *aNaturalWidth = NaturalWidth();
 
-  if (!mCurrentRequest) {
-    return NS_OK;
-  }
-  
-  nsCOMPtr<imgIContainer> image;
-  mCurrentRequest->GetImage(getter_AddRefs(image));
-  if (!image) {
-    return NS_OK;
-  }
-
-  int32_t width;
-  if (NS_SUCCEEDED(image->GetWidth(&width))) {
-    *aNaturalWidth = width;
-  }
   return NS_OK;
 }
 
 nsresult
 HTMLImageElement::CopyInnerTo(Element* aDest)
 {
   if (aDest->OwnerDoc()->IsStaticDocument()) {
     CreateStaticImageClone(static_cast<HTMLImageElement*>(aDest));
@@ -540,10 +558,17 @@ HTMLImageElement::CopyInnerTo(Element* a
 }
 
 CORSMode
 HTMLImageElement::GetCORSMode()
 {
   return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 }
 
+JSObject*
+HTMLImageElement::WrapNode(JSContext* aCx, JSObject* aScope,
+                           bool* aTriedToWrap)
+{
+  return HTMLImageElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLImageElement.h
+++ b/content/html/content/src/HTMLImageElement.h
@@ -5,16 +5,17 @@
 
 #ifndef mozilla_dom_HTMLImageElement_h
 #define mozilla_dom_HTMLImageElement_h
 
 #include "nsGenericHTMLElement.h"
 #include "nsImageLoadingContent.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIJSNativeInitializer.h"
+#include "imgRequestProxy.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLImageElement MOZ_FINAL : public nsGenericHTMLElement,
                                    public nsImageLoadingContent,
                                    public nsIDOMHTMLImageElement,
                                    public nsIJSNativeInitializer
@@ -82,18 +83,99 @@ public:
   virtual nsEventStates IntrinsicState() const;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   nsresult CopyInnerTo(Element* aDest);
 
   void MaybeLoadImage();
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  bool IsMap()
+  {
+    return GetBoolAttr(nsGkAtoms::ismap);
+  }
+  void SetIsMap(bool aIsMap, ErrorResult& aError)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::ismap, aIsMap, aError);
+  }
+  uint32_t Width()
+  {
+    return GetWidthHeightForImage(mCurrentRequest).width;
+  }
+  void SetWidth(uint32_t aWidth, ErrorResult& aError)
+  {
+    SetHTMLUnsignedIntAttr(nsGkAtoms::width, aWidth, aError);
+  }
+  uint32_t Height()
+  {
+    return GetWidthHeightForImage(mCurrentRequest).height;
+  }
+  void SetHeight(uint32_t aHeight, ErrorResult& aError)
+  {
+    SetHTMLUnsignedIntAttr(nsGkAtoms::height, aHeight, aError);
+  }
+  uint32_t NaturalWidth();
+  uint32_t NaturalHeight();
+  bool Complete();
+  int32_t Hspace()
+  {
+    return GetIntAttr(nsGkAtoms::hspace, 0);
+  }
+  void SetHspace(int32_t aHspace, ErrorResult& aError)
+  {
+    SetHTMLIntAttr(nsGkAtoms::hspace, aHspace, aError);
+  }
+  int32_t Vspace()
+  {
+    return GetIntAttr(nsGkAtoms::vspace, 0);
+  }
+  void SetVspace(int32_t aVspace, ErrorResult& aError)
+  {
+    SetHTMLIntAttr(nsGkAtoms::vspace, aVspace, aError);
+  }
+
+  // The XPCOM versions of the following getters work for Web IDL bindings as well
+  void SetAlt(const nsAString& aAlt, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::alt, aAlt, aError);
+  }
+  void SetSrc(const nsAString& aSrc, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
+  }
+  void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
+  }
+  void SetUseMap(const nsAString& aUseMap, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::usemap, aUseMap, aError);
+  }
+  void SetName(const nsAString& aName, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::name, aName, aError);
+  }
+  void SetAlign(const nsAString& aAlign, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
+  }
+  void SetLongDesc(const nsAString& aLongDesc, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::longdesc, aLongDesc, aError);
+  }
+  void SetBorder(const nsAString& aBorder, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::border, aBorder, aError);
+  }
+
 protected:
   nsIntPoint GetXY();
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_HTMLImageElement_h */
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -824,16 +824,23 @@ protected:
   }
   void SetHTMLIntAttr(nsIAtom* aName, int32_t aValue, mozilla::ErrorResult& aError)
   {
     nsAutoString value;
     value.AppendInt(aValue);
 
     SetHTMLAttr(aName, value, aError);
   }
+  void SetHTMLUnsignedIntAttr(nsIAtom* aName, uint32_t aValue, mozilla::ErrorResult& aError)
+  {
+    nsAutoString value;
+    value.AppendInt(aValue);
+
+    SetHTMLAttr(aName, value, aError);
+  }
 
   /**
    * Helper method for NS_IMPL_STRING_ATTR macro.
    * Sets the value of an attribute, returns specified default value if the
    * attribute isn't set. Only works for attributes in null namespace.
    *
    * @param aAttr    name of attribute.
    * @param aDefault default-value to return if attribute isn't set.
--- a/content/html/content/test/reflect.js
+++ b/content/html/content/test/reflect.js
@@ -51,17 +51,35 @@ function reflectString(aParameters)
   is(element.getAttribute(contentAttr), "null",
      "null should have been stringified to 'null'");
   is(element[idlAttr], "null",
      "null should have been stringified to 'null'");
   element.removeAttribute(contentAttr);
 
   element[idlAttr] = null;
   // TODO: remove this ugly hack when null stringification will work as expected.
-  if (element.localName == "textarea" && idlAttr == "wrap") {
+  var todoAttrs = {
+    col: [ "align", "vAlign", "ch" ],
+    colgroup: [ "align", "vAlign", "ch" ],
+    form: [ "acceptCharset", "name", "target" ],
+    img: [ "align" ],
+    input: [ "accept", "alt", "formTarget", "max", "min", "name", "pattern", "placeholder", "step", "defaultValue" ],
+    link: [ "crossOrigin" ],
+    script: [ "crossOrigin" ],
+    source: [ "media" ],
+    table: [ "border", "width" ],
+    tbody: [ "align", "vAlign", "ch" ],
+    td: [ "align", "vAlign", "ch" ],
+    textarea: [ "name", "placeholder" ],
+    tfoot: [ "align", "vAlign", "ch" ],
+    th: [ "align", "vAlign", "ch" ],
+    thead: [ "align", "vAlign", "ch" ],
+    tr: [ "align", "vAlign", "ch" ],
+  };
+  if (!(element.localName in todoAttrs) || todoAttrs[element.localName].indexOf(idlAttr) == -1) {
     is(element.getAttribute(contentAttr), "null",
        "null should have been stringified to 'null'");
     is(element[idlAttr], "null", "null should have been stringified to 'null'");
     element.removeAttribute(contentAttr);
   } else {
     todo_is(element.getAttribute(contentAttr), "null",
        "null should have been stringified to 'null'");
     todo_is(element[idlAttr], "null",
new file mode 100644
--- /dev/null
+++ b/dom/webidl/HTMLImageElement.webidl
@@ -0,0 +1,53 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/specs/web-apps/current-work/#htmlimageelement
+ * http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce
+ * and create derivative works of this document.
+ */
+
+[NamedConstructor=Image(),
+ NamedConstructor=Image(unsigned long width),
+ NamedConstructor=Image(unsigned long width, unsigned long height)]
+interface HTMLImageElement : HTMLElement {
+           [SetterThrows]
+           attribute DOMString alt;
+           [SetterThrows]
+           attribute DOMString src;
+//           attribute DOMString srcset;
+           [SetterThrows]
+           attribute DOMString crossOrigin;
+           [SetterThrows]
+           attribute DOMString useMap;
+           [SetterThrows]
+           attribute boolean isMap;
+           [SetterThrows]
+           attribute unsigned long width;
+           [SetterThrows]
+           attribute unsigned long height;
+  readonly attribute unsigned long naturalWidth;
+  readonly attribute unsigned long naturalHeight;
+  readonly attribute boolean complete;
+/*};
+
+// http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis
+partial interface HTMLImageElement {
+*/
+           [SetterThrows]
+           attribute DOMString name;
+           [SetterThrows]
+           attribute DOMString align;
+           [SetterThrows]
+           attribute unsigned long hspace;
+           [SetterThrows]
+           attribute unsigned long vspace;
+           [SetterThrows]
+           attribute DOMString longDesc;
+
+  [TreatNullAs=EmptyString,SetterThrows] attribute DOMString border;
+};