Bug 842201 - SVGUnitTypes interface object is not being instantiated r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Wed, 13 Mar 2013 14:07:49 -0400
changeset 124722 ba0ef31a1726be61921ffb4fe34b76093ab67743
parent 124721 f77559dc68c39576ef59f07859139f095f009b40
child 124723 738733ab166d0f48f15691191cdbd5536c3f659e
push id24433
push useremorley@mozilla.com
push dateThu, 14 Mar 2013 12:21:10 +0000
treeherdermozilla-central@96af92fa87fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs842201
milestone22.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 842201 - SVGUnitTypes interface object is not being instantiated r=bz
content/svg/content/src/SVGClipPathElement.cpp
content/svg/content/src/SVGClipPathElement.h
content/svg/content/src/SVGFilterElement.cpp
content/svg/content/src/SVGFilterElement.h
content/svg/content/src/SVGGradientElement.cpp
content/svg/content/src/SVGGradientElement.h
content/svg/content/src/SVGMaskElement.cpp
content/svg/content/src/SVGMaskElement.h
content/svg/content/src/SVGPatternElement.cpp
content/svg/content/src/SVGPatternElement.h
content/svg/content/test/Makefile.in
content/svg/content/test/test_SVGUnitTypes.html
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/test/TestCodeGen.webidl
dom/interfaces/svg/nsIDOMSVGUnitTypes.idl
--- a/content/svg/content/src/SVGClipPathElement.cpp
+++ b/content/svg/content/src/SVGClipPathElement.cpp
@@ -26,19 +26,19 @@ nsSVGElement::EnumInfo SVGClipPathElemen
     sSVGUnitTypesMap,
     SVG_UNIT_TYPE_USERSPACEONUSE
   }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ISUPPORTS_INHERITED3(SVGClipPathElement, SVGClipPathElementBase,
+NS_IMPL_ISUPPORTS_INHERITED4(SVGClipPathElement, SVGClipPathElementBase,
                              nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement)
+                             nsIDOMSVGElement, nsIDOMSVGUnitTypes)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGClipPathElement::SVGClipPathElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGClipPathElementBase(aNodeInfo)
 {
   SetIsDOMBinding();
--- a/content/svg/content/src/SVGClipPathElement.h
+++ b/content/svg/content/src/SVGClipPathElement.h
@@ -1,31 +1,33 @@
 /* -*- 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/. */
 
 #ifndef mozilla_dom_SVGClipPathElement_h
 #define mozilla_dom_SVGClipPathElement_h
 
+#include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEnum.h"
 #include "mozilla/dom/SVGTransformableElement.h"
 
 class nsSVGClipPathFrame;
 
 nsresult NS_NewSVGClipPathElement(nsIContent **aResult,
                                   already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 typedef SVGTransformableElement SVGClipPathElementBase;
 
 class SVGClipPathElement MOZ_FINAL : public SVGClipPathElementBase,
-                                     public nsIDOMSVGElement
+                                     public nsIDOMSVGElement,
+                                     public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGClipPathFrame;
 
 protected:
   friend nsresult (::NS_NewSVGClipPathElement(nsIContent **aResult,
                                               already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGClipPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope) MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGFilterElement.cpp
+++ b/content/svg/content/src/SVGFilterElement.cpp
@@ -50,19 +50,19 @@ nsSVGElement::EnumInfo SVGFilterElement:
 nsSVGElement::StringInfo SVGFilterElement::sStringInfo[1] =
 {
   { &nsGkAtoms::href, kNameSpaceID_XLink, true }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ISUPPORTS_INHERITED3(SVGFilterElement, SVGFilterElementBase,
+NS_IMPL_ISUPPORTS_INHERITED4(SVGFilterElement, SVGFilterElementBase,
                              nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement)
+                             nsIDOMSVGElement, nsIDOMSVGUnitTypes)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGFilterElement::SVGFilterElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGFilterElementBase(aNodeInfo)
 {
   SetIsDOMBinding();
--- a/content/svg/content/src/SVGFilterElement.h
+++ b/content/svg/content/src/SVGFilterElement.h
@@ -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/. */
 
 #ifndef mozilla_dom_SVGFilterElement_h
 #define mozilla_dom_SVGFilterElement_h
 
+#include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEnum.h"
 #include "nsSVGElement.h"
 #include "nsSVGIntegerPair.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 
 typedef nsSVGElement SVGFilterElementBase;
 
@@ -20,17 +21,18 @@ class nsAutoFilterInstance;
 nsresult NS_NewSVGFilterElement(nsIContent **aResult,
                                 already_AddRefed<nsINodeInfo> aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 class SVGAnimatedLength;
 
 class SVGFilterElement : public SVGFilterElementBase,
-                         public nsIDOMSVGElement
+                         public nsIDOMSVGElement,
+                         public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGFilterFrame;
   friend class ::nsAutoFilterInstance;
 
 protected:
   friend nsresult (::NS_NewSVGFilterElement(nsIContent **aResult,
                                             already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGFilterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
--- a/content/svg/content/src/SVGGradientElement.cpp
+++ b/content/svg/content/src/SVGGradientElement.cpp
@@ -48,16 +48,17 @@ nsSVGElement::StringInfo SVGGradientElem
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGGradientElement, SVGGradientElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGGradientElement, SVGGradientElementBase)
 
 NS_INTERFACE_MAP_BEGIN(SVGGradientElement)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMSVGUnitTypes)
 NS_INTERFACE_MAP_END_INHERITING(SVGGradientElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGGradientElement::SVGGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGGradientElementBase(aNodeInfo)
 {
--- a/content/svg/content/src/SVGGradientElement.h
+++ b/content/svg/content/src/SVGGradientElement.h
@@ -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/. */
 
 #ifndef __NS_SVGGRADIENTELEMENT_H__
 #define __NS_SVGGRADIENTELEMENT_H__
 
+#include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGElement.h"
 #include "nsSVGLength2.h"
 #include "nsSVGEnum.h"
 #include "nsSVGString.h"
 #include "SVGAnimatedTransformList.h"
 
 static const unsigned short SVG_SPREADMETHOD_UNKNOWN = 0;
 static const unsigned short SVG_SPREADMETHOD_PAD     = 1;
@@ -34,16 +35,17 @@ class DOMSVGAnimatedTransformList;
 
 namespace dom {
 
 //--------------------- Gradients------------------------
 
 typedef nsSVGElement SVGGradientElementBase;
 
 class SVGGradientElement : public SVGGradientElementBase
+                         , public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGGradientFrame;
 
 protected:
   SVGGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject*
   WrapNode(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE = 0;
 
--- a/content/svg/content/src/SVGMaskElement.cpp
+++ b/content/svg/content/src/SVGMaskElement.cpp
@@ -41,19 +41,19 @@ nsSVGElement::EnumInfo SVGMaskElement::s
     sSVGUnitTypesMap,
     SVG_UNIT_TYPE_USERSPACEONUSE
   }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ISUPPORTS_INHERITED3(SVGMaskElement, SVGMaskElementBase,
+NS_IMPL_ISUPPORTS_INHERITED4(SVGMaskElement, SVGMaskElementBase,
                              nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement)
+                             nsIDOMSVGElement, nsIDOMSVGUnitTypes)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGMaskElement::SVGMaskElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGMaskElementBase(aNodeInfo)
 {
   SetIsDOMBinding();
--- a/content/svg/content/src/SVGMaskElement.h
+++ b/content/svg/content/src/SVGMaskElement.h
@@ -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/. */
 
 #ifndef mozilla_dom_SVGMaskElement_h
 #define mozilla_dom_SVGMaskElement_h
 
+#include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGElement.h"
 
 class nsSVGMaskFrame;
 
 nsresult NS_NewSVGMaskElement(nsIContent **aResult,
                               already_AddRefed<nsINodeInfo> aNodeInfo);
@@ -18,17 +19,18 @@ nsresult NS_NewSVGMaskElement(nsIContent
 namespace mozilla {
 namespace dom {
 
 //--------------------- Masks ------------------------
 
 typedef nsSVGElement SVGMaskElementBase;
 
 class SVGMaskElement MOZ_FINAL : public SVGMaskElementBase,
-                                 public nsIDOMSVGElement
+                                 public nsIDOMSVGElement,
+                                 public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGMaskFrame;
 
 protected:
   friend nsresult (::NS_NewSVGMaskElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGMaskElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope) MOZ_OVERRIDE;
--- a/content/svg/content/src/SVGPatternElement.cpp
+++ b/content/svg/content/src/SVGPatternElement.cpp
@@ -47,19 +47,19 @@ nsSVGElement::EnumInfo SVGPatternElement
 nsSVGElement::StringInfo SVGPatternElement::sStringInfo[1] =
 {
   { &nsGkAtoms::href, kNameSpaceID_XLink, true }
 };
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ISUPPORTS_INHERITED3(SVGPatternElement, SVGPatternElementBase,
+NS_IMPL_ISUPPORTS_INHERITED4(SVGPatternElement, SVGPatternElementBase,
                              nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement)
+                             nsIDOMSVGElement, nsIDOMSVGUnitTypes)
 
 //----------------------------------------------------------------------
 // Implementation
 
 SVGPatternElement::SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : SVGPatternElementBase(aNodeInfo)
 {
   SetIsDOMBinding();
--- a/content/svg/content/src/SVGPatternElement.h
+++ b/content/svg/content/src/SVGPatternElement.h
@@ -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/. */
 
 #ifndef mozilla_dom_SVGPatternElement_h
 #define mozilla_dom_SVGPatternElement_h
 
+#include "nsIDOMSVGUnitTypes.h"
 #include "nsSVGEnum.h"
 #include "nsSVGLength2.h"
 #include "nsSVGString.h"
 #include "nsSVGElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "SVGAnimatedTransformList.h"
 
@@ -22,17 +23,18 @@ nsresult NS_NewSVGPatternElement(nsICont
 namespace mozilla {
 class DOMSVGAnimatedTransformList;
 
 namespace dom {
 
 typedef nsSVGElement SVGPatternElementBase;
 
 class SVGPatternElement MOZ_FINAL : public SVGPatternElementBase,
-                                    public nsIDOMSVGElement
+                                    public nsIDOMSVGElement,
+                                    public nsIDOMSVGUnitTypes
 {
   friend class ::nsSVGPatternFrame;
 
 protected:
   friend nsresult (::NS_NewSVGPatternElement(nsIContent **aResult,
                                              already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx, JSObject *scope) MOZ_OVERRIDE;
--- a/content/svg/content/test/Makefile.in
+++ b/content/svg/content/test/Makefile.in
@@ -63,16 +63,17 @@ MOCHITEST_FILES = \
 		test_SVGMatrix.xhtml \
 		test_SVGNumberList.xhtml \
 		test_SVGPathSegList.xhtml \
 		test_SVGPointList.xhtml \
 		test_SVGStyleElement.xhtml \
 		test_SVGStringList.xhtml \
 		test_SVGTransformList.xhtml \
 		test_SVGTransformListAddition.xhtml \
+		test_SVGUnitTypes.html \
 		test_SVGxxxList.xhtml \
 		test_SVGxxxListIndexing.xhtml \
 		test_switch.xhtml \
 		switch-helper.svg \
 		test_text.html \
 		test_text_2.html \
 		test_text_scaled.html \
 		test_text_selection.html \
new file mode 100644
--- /dev/null
+++ b/content/svg/content/test/test_SVGUnitTypes.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=366697
+-->
+<head>
+<title>Test for Bug 842201</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=842201">Mozilla Bug 842201</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+
+<pre id="test">
+<script class="testbody" type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function runTest()
+{
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "pattern")
+       instanceof SVGUnitTypes, "Pattern should implement SVGUnitTypes");
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "filter")
+       instanceof SVGUnitTypes, "Filter should implement SVGUnitTypes");
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "mask")
+       instanceof SVGUnitTypes, "Mask should implement SVGUnitTypes");
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "clipPath")
+       instanceof SVGUnitTypes, "ClipPath should implement SVGUnitTypes");
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "linearGradient")
+       instanceof SVGUnitTypes, "LinearGradient should implement SVGUnitTypes");
+  ok(document.createElementNS("http://www.w3.org/2000/svg", "radialGradient")
+       instanceof SVGUnitTypes, "radialGradient should implement SVGUnitTypes");
+  ok(!(document.createElementNS("http://www.w3.org/2000/svg", "svg")
+       instanceof SVGUnitTypes), "svg should not implement SVGUnitTypes");
+  SimpleTest.finish();
+}
+
+window.addEventListener("load", runTest, false);
+</script>
+</pre>
+</body>
+</html>
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -826,16 +826,20 @@ DOMInterfaces = {
     'headerFile': 'DOMSVGTransformList.h',
     'resultNotAddRefed': [ 'getItem' ]
 },
 
 'SVGSVGElement': {
     'resultNotAddRefed': [ 'getElementById' ]
 },
 
+'SVGUnitTypes' : {
+    'concrete': False,
+},
+
 'Text': {
     # Total hack to allow binding code to realize that nsTextNode can
     # in fact be cast to Text.
     'headerFile': 'nsTextNode.h',
 },
 
 'TextDecoder': [
 {
@@ -1078,16 +1082,57 @@ DOMInterfaces = {
         'concrete': False
         },
 
 'OnlyForUseInConstructor' : {
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
+'ImplementedInterface' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False,
+        },
+
+'ImplementedInterfaceParent' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
+
+'DiamondImplements' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
+
+'DiamondBranch1A' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
+
+'DiamondBranch1B' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
+
+'DiamondBranch2A' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
+
+'DiamondBranch2B' : {
+        'headerFile': 'TestBindingHeader.h',
+        'concrete': False,
+        'register': False
+        },
 
 'TestIndexedGetterInterface' : {
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestNamedGetterInterface' : {
         'headerFile': 'TestBindingHeader.h',
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -260,17 +260,16 @@ class CGInterfaceObjectJSClass(CGThing):
         # We're purely for internal consumption
         return ""
     def define(self):
         if self.descriptor.interface.ctor():
             ctorname = CONSTRUCT_HOOK_NAME
         else:
             ctorname = "ThrowingConstructor"
         if NeedsGeneratedHasInstance(self.descriptor):
-            assert self.descriptor.interface.hasInterfacePrototypeObject()
             hasinstance = HASINSTANCE_HOOK_NAME
         elif self.descriptor.interface.hasInterfacePrototypeObject():
             hasinstance = "InterfaceHasInstance"
         else:
             hasinstance = "nullptr"
         (prototypeID, depth) = PrototypeIDAndDepth(self.descriptor)
         return """
 static DOMIfaceAndProtoJSClass InterfaceObjectClass = {
@@ -492,21 +491,23 @@ class CGHeaders(CGWrapper):
         for iface in interfaceDeps:
             while iface.parent:
                 ancestors.append(iface.parent)
                 iface = iface.parent
         interfaceDeps.extend(ancestors)
         bindingIncludes = set(self.getDeclarationFilename(d) for d in interfaceDeps)
 
         # Grab all the implementation declaration files we need.
-        implementationIncludes = set(d.headerFile for d in descriptors)
+        implementationIncludes = set(d.headerFile for d in descriptors if d.needsHeaderInclude())
 
         # Grab the includes for the things that involve XPCOM interfaces
         hasInstanceIncludes = set("nsIDOM" + d.interface.identifier.name + ".h" for d
-                                  in descriptors if NeedsGeneratedHasInstance(d))
+                                  in descriptors if
+                                  NeedsGeneratedHasInstance(d) and
+                                  d.interface.hasInterfaceObject())
 
         # Now find all the things we'll need as arguments because we
         # need to wrap or unwrap them.
         bindingHeaders = set()
         def addHeadersForType(t, descriptor=None, dictionary=None):
             """
             Add the relevant headers for this type.  We use descriptor and
             dictionary, if passed, to decide what to do with interface types.
@@ -1047,34 +1048,41 @@ class CGClassHasInstanceHook(CGAbstractS
             return ""
         return CGAbstractStaticMethod.define(self)
 
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
         assert self.descriptor.nativeOwnership == 'nsisupports'
+        if self.descriptor.interface.hasInterfacePrototypeObject():
+            hasInstanceCode = """
+  bool ok = InterfaceHasInstance(cx, obj, instance, bp);
+  if (!ok || *bp) {
+    return ok;
+  }
+        """
+        else:
+            hasInstanceCode = ""
+
         return """  if (!vp.isObject()) {
     *bp = false;
     return true;
   }
 
   JSObject* instance = &vp.toObject();
-  bool ok = InterfaceHasInstance(cx, obj, instance, bp);
-  if (!ok || *bp) {
-    return ok;
-  }
+  %s
 
   // FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
   nsISupports* native =
     nsContentUtils::XPConnect()->GetNativeOfWrapper(cx,
                                                     js::UnwrapObject(instance));
   nsCOMPtr<nsIDOM%s> qiResult = do_QueryInterface(native);
   *bp = !!qiResult;
-  return true;""" % self.descriptor.interface.identifier.name
+  return true;""" % (hasInstanceCode, self.descriptor.interface.identifier.name)
 
 def isChromeOnly(m):
     return m.getExtendedAttribute("ChromeOnly")
 
 class MemberCondition:
     """
     An object representing the condition for a member to actually be
     exposed.  Either pref or func or both can be None.  If not None,
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -31,19 +31,19 @@ class Configuration:
             # isInterface()...
             if (not isinstance(thing, IDLInterface) and
                 not isinstance(thing, IDLExternalInterface)):
                 continue
             iface = thing
             self.interfaces[iface.identifier.name] = iface
             if iface.identifier.name not in config:
                 # Completely skip consequential interfaces with no descriptor
-                # because chances are we don't need to do anything interesting
-                # with them.
-                if iface.isConsequential():
+                # if they have no interface object because chances are we
+                # don't need to do anything interesting with them.
+                if iface.isConsequential() and not iface.hasInterfaceObject():
                     continue
                 entry = {}
             else:
                 entry = config[iface.identifier.name]
             if not isinstance(entry, list):
                 assert isinstance(entry, dict)
                 entry = [entry]
             elif len(entry) == 1 and entry[0].get("workers", False):
@@ -442,16 +442,25 @@ class Descriptor(DescriptorProvider):
 
     def supportsNamedProperties(self):
         return self.operations['NamedGetter'] is not None
 
     def needsConstructHookHolder(self):
         assert self.interface.hasInterfaceObject()
         return False
 
+    def needsHeaderInclude(self):
+        """
+        An interface doesn't need a header file if it is not concrete,
+        not pref-controlled, and has only consts.
+        """
+        return (self.interface.isExternal() or self.concrete or
+            self.interface.getExtendedAttribute("PrefControlled") or
+            not all(m.isConst() for m in self.interface.members))
+
 # Some utility methods
 def getTypesFromDescriptor(descriptor):
     """
     Get all argument and return types for all members of the descriptor
     """
     members = [m for m in descriptor.interface.members]
     if descriptor.interface.ctor():
         members.append(descriptor.interface.ctor())
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -517,16 +517,17 @@ interface TestParentInterface {
 };
 
 interface TestChildInterface : TestParentInterface {
 };
 
 interface TestNonWrapperCacheInterface {
 };
 
+[NoInterfaceObject]
 interface ImplementedInterfaceParent {
   void implementedParentMethod();
   attribute boolean implementedParentProperty;
 
   const long implementedParentConstant = 8;
 };
 
 ImplementedInterfaceParent implements IndirectlyImplementedInterface;
@@ -534,32 +535,38 @@ ImplementedInterfaceParent implements In
 [NoInterfaceObject]
 interface IndirectlyImplementedInterface {
   void indirectlyImplementedMethod();
   attribute boolean indirectlyImplementedProperty;
 
   const long indirectlyImplementedConstant = 9;
 };
 
+[NoInterfaceObject]
 interface ImplementedInterface : ImplementedInterfaceParent {
   void implementedMethod();
   attribute boolean implementedProperty;
 
   const long implementedConstant = 5;
 };
 
+[NoInterfaceObject]
 interface DiamondImplements {
   readonly attribute long diamondImplementedProperty;
 };
+[NoInterfaceObject]
 interface DiamondBranch1A {
 };
+[NoInterfaceObject]
 interface DiamondBranch1B {
 };
+[NoInterfaceObject]
 interface DiamondBranch2A : DiamondImplements {
 };
+[NoInterfaceObject]
 interface DiamondBranch2B : DiamondImplements {
 };
 TestInterface implements DiamondBranch1A;
 TestInterface implements DiamondBranch1B;
 TestInterface implements DiamondBranch2A;
 TestInterface implements DiamondBranch2B;
 DiamondBranch1A implements DiamondImplements;
 DiamondBranch1B implements DiamondImplements;
--- a/dom/interfaces/svg/nsIDOMSVGUnitTypes.idl
+++ b/dom/interfaces/svg/nsIDOMSVGUnitTypes.idl
@@ -11,13 +11,9 @@
  * For more information on this interface please see
  * http://www.w3.org/TR/SVG11/types.html
  *
  */
 
 [scriptable, uuid(154b572f-3d0b-49c0-8b5d-8864d05bd3d1)]
 interface nsIDOMSVGUnitTypes : nsISupports
 {
-  // Unit Types
-  const unsigned short SVG_UNIT_TYPE_UNKNOWN           = 0;
-  const unsigned short SVG_UNIT_TYPE_USERSPACEONUSE    = 1;
-  const unsigned short SVG_UNIT_TYPE_OBJECTBOUNDINGBOX = 2;
 };