Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, annotate Window as having named properties. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Fri, 05 Sep 2014 22:36:32 +0200
changeset 207652 024db535ce4d
parent 207651 591364ca5f0a
child 207653 7f2d0c477f64
push id27564
push userryanvm@gmail.com
push dateMon, 29 Sep 2014 18:57:04 +0000
treeherdermozilla-central@ce9a0b34225e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs787070
milestone35.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 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, annotate Window as having named properties. r=bz.
dom/bindings/Configuration.py
dom/webidl/Window.webidl
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -298,35 +298,35 @@ class Descriptor(DescriptorProvider):
 
         self.hasXPConnectImpls = desc.get('hasXPConnectImpls', False)
 
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         self.concrete = (not self.interface.isExternal() and
                          not self.interface.isCallback() and
                          desc.get('concrete', True))
-        operations = {
+        self.operations = {
             'IndexedGetter': None,
             'IndexedSetter': None,
             'IndexedCreator': None,
             'IndexedDeleter': None,
             'NamedGetter': None,
             'NamedSetter': None,
             'NamedCreator': None,
             'NamedDeleter': None,
             'Stringifier': None,
             'LegacyCaller': None,
             'Jsonifier': None
             }
         if self.concrete:
             self.proxy = False
             iface = self.interface
             def addOperation(operation, m):
-                if not operations[operation]:
-                    operations[operation] = m
+                if not self.operations[operation]:
+                    self.operations[operation] = m
             # Since stringifiers go on the prototype, we only need to worry
             # about our own stringifier, not those of our ancestor interfaces.
             for m in iface.members:
                 if m.isMethod() and m.isStringifier():
                     addOperation('Stringifier', m)
                 if m.isMethod() and m.isJsonifier():
                     addOperation('Jsonifier', m)
                 # Don't worry about inheriting legacycallers either: in
@@ -340,17 +340,16 @@ class Descriptor(DescriptorProvider):
                                         "legacycaller.\n%s" % m.location)
                     addOperation('LegacyCaller', m)
             while iface:
                 for m in iface.members:
                     if not m.isMethod():
                         continue
 
                     def addIndexedOrNamedOperation(operation, m):
-                        self.proxy = True
                         if m.isIndexed():
                             operation = 'Indexed' + operation
                         else:
                             assert m.isNamed()
                             operation = 'Named' + operation
                         addOperation(operation, m)
 
                     if m.isGetter():
@@ -364,36 +363,39 @@ class Descriptor(DescriptorProvider):
                     if m.isLegacycaller() and iface != self.interface:
                         raise TypeError("We don't support legacycaller on "
                                         "non-leaf interface %s.\n%s" %
                                         (iface, iface.location))
 
                 iface.setUserData('hasConcreteDescendant', True)
                 iface = iface.parent
 
+            self.proxy = (self.supportsIndexedProperties() or
+                          (self.supportsNamedProperties() and
+                           not self.hasNamedPropertiesObject))
+
             if self.proxy:
-                if (not operations['IndexedGetter'] and
-                    (operations['IndexedSetter'] or
-                     operations['IndexedDeleter'] or
-                     operations['IndexedCreator'])):
+                if (not self.operations['IndexedGetter'] and
+                    (self.operations['IndexedSetter'] or
+                     self.operations['IndexedDeleter'] or
+                     self.operations['IndexedCreator'])):
                     raise SyntaxError("%s supports indexed properties but does "
                                       "not have an indexed getter.\n%s" %
                                       (self.interface, self.interface.location))
-                if (not operations['NamedGetter'] and
-                    (operations['NamedSetter'] or
-                     operations['NamedDeleter'] or
-                     operations['NamedCreator'])):
+                if (not self.operations['NamedGetter'] and
+                    (self.operations['NamedSetter'] or
+                     self.operations['NamedDeleter'] or
+                     self.operations['NamedCreator'])):
                     raise SyntaxError("%s supports named properties but does "
                                       "not have a named getter.\n%s" %
                                       (self.interface, self.interface.location))
                 iface = self.interface
                 while iface:
                     iface.setUserData('hasProxyDescendant', True)
                     iface = iface.parent
-        self.operations = operations
 
         self.nativeOwnership = desc.get('nativeOwnership', 'refcounted')
         if not self.nativeOwnership in ('owned', 'refcounted'):
             raise TypeError("Descriptor for %s has unrecognized value (%s) "
                             "for nativeOwnership" %
                             (self.interface.identifier.name, self.nativeOwnership))
         if desc.get('wantsQI', None) != None:
             self._wantsQI = desc.get('wantsQI', None)
@@ -516,16 +518,23 @@ class Descriptor(DescriptorProvider):
         # Forward-declared interfaces don't need either interface object or
         # interface prototype object as they're going to use QI (on main thread)
         # or be passed as a JSObject (on worker threads).
         if self.interface.isExternal():
             return False
 
         return self.interface.hasInterfaceObject() or self.interface.hasInterfacePrototypeObject()
 
+    @property
+    def hasNamedPropertiesObject(self):
+        if self.interface.isExternal():
+            return False
+
+        return self.isGlobal() and self.supportsNamedProperties()
+
     def getExtendedAttributes(self, member, getter=False, setter=False):
         def ensureValidThrowsExtendedAttribute(attr):
             assert(attr is None or attr is True or len(attr) == 1)
             if (attr is not None and attr is not True and
                 'Workers' not in attr and 'MainThread' not in attr):
                 raise TypeError("Unknown value for 'Throws': " + attr[0])
 
         def maybeAppendInfallibleToAttrs(attrs, throws):
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -58,17 +58,17 @@ typedef any Transferable;
   //[Throws] readonly attribute WindowProxy parent;
   [Replaceable, Throws, CrossOriginReadable] readonly attribute WindowProxy? parent;
   [Throws] readonly attribute Element? frameElement;
   //[Throws] WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", [TreatNullAs=EmptyString] optional DOMString features = "", optional boolean replace = false);
   [Throws] WindowProxy? open(optional DOMString url = "", optional DOMString target = "", [TreatNullAs=EmptyString] optional DOMString features = "");
   // We think the indexed getter is a bug in the spec, it actually needs to live
   // on the WindowProxy
   //getter WindowProxy (unsigned long index);
-  //getter object (DOMString name);
+  getter object (DOMString name);
 
   // the user agent
   [Throws] readonly attribute Navigator navigator; 
 #ifdef HAVE_SIDEBAR
   [Replaceable, Throws] readonly attribute External external;
 #endif
   [Throws] readonly attribute ApplicationCache applicationCache;