Bug 1333045. Update Location object properties to current spec. r=qdot
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 15 Feb 2017 00:01:48 -0500
changeset 389610 5061e0dedf2f7afd0ff203d93b9122d7eaaf0007
parent 389609 01dd2928a1b7b37f3ca69ea3fe70b4499f065659
child 389611 ebb182ab1da2d3eb7c00662f23818b46dd940611
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1333045
milestone54.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 1333045. Update Location object properties to current spec. r=qdot Specifically, three changes: 1) valueOf should be non-enumerable. 2) valueOf should be === to Object.prototype.valueOf. 3) There should be no toJSON. The tests come directly from https://github.com/w3c/web-platform-tests/pull/4623 so not much need to review them.
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
js/xpconnect/tests/chrome/test_bug1041626.xul
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html
testing/web-platform/tests/html/browsers/history/the-location-interface/location-symbol-toprimitive.html
testing/web-platform/tests/html/browsers/history/the-location-interface/location-tojson.html
testing/web-platform/tests/html/browsers/history/the-location-interface/location-valueof.html
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1207,24 +1207,16 @@ GetInterfaceImpl(JSContext* aCx, nsIInte
   }
 
   if (!WrapObject(aCx, result, iid, aRetval)) {
     aError.Throw(NS_ERROR_FAILURE);
   }
 }
 
 bool
-UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp)
-{
-  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-  args.rval().set(args.thisv());
-  return true;
-}
-
-bool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
 {
   return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
 }
 
 bool
 ThrowConstructorWithoutNew(JSContext* cx, const char* name)
 {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1824,19 +1824,16 @@ template<class T>
 void
 GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
              JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
 {
   GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
 }
 
 bool
-UnforgeableValueOf(JSContext* cx, unsigned argc, JS::Value* vp);
-
-bool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
 
 bool
 ThrowConstructorWithoutNew(JSContext* cx, const char* name);
 
 bool
 GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
                        JS::Handle<JS::Value> receiver, JS::Handle<jsid> id,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2483,21 +2483,20 @@ class MethodDefiner(PropertyDefiner):
                     self.chrome.append(toJSONDesc)
                 else:
                     self.regular.append(toJSONDesc)
             if (unforgeable and
                 descriptor.interface.getExtendedAttribute("Unforgeable")):
                 # Synthesize our valueOf method
                 self.regular.append({
                     "name": 'valueOf',
-                    "nativeName": "UnforgeableValueOf",
+                    "selfHostedName": "Object_valueOf",
                     "methodInfo": False,
                     "length": 0,
-                    "flags": "JSPROP_ENUMERATE",  # readonly/permanent added
-                                                  # automatically.
+                    "flags": "0",  # readonly/permanent added automatically.
                     "condition": MemberCondition()
                 })
 
         if descriptor.interface.isJSImplemented():
             if static:
                 if descriptor.interface.hasInterfaceObject():
                     self.chrome.append({
                         "name": '_create',
@@ -3558,29 +3557,25 @@ def InitUnforgeablePropertiesOnHolder(de
         if array.hasNonChromeOnly():
             unforgeables.append(CGGeneric(template % array.variableName(False)))
         if array.hasChromeOnly():
             unforgeables.append(
                 CGIfWrapper(CGGeneric(template % array.variableName(True)),
                             "nsContentUtils::ThreadsafeIsSystemCaller(aCx)"))
 
     if descriptor.interface.getExtendedAttribute("Unforgeable"):
-        # We do our undefined toJSON and toPrimitive here, not as a regular
-        # property because we don't have a concept of value props anywhere in
-        # IDL.
+        # We do our undefined toPrimitive here, not as a regular property
+        # because we don't have a concept of value props anywhere in IDL.
         unforgeables.append(CGGeneric(fill(
             """
             JS::RootedId toPrimitive(aCx,
               SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::toPrimitive)));
             if (!JS_DefinePropertyById(aCx, ${holderName}, toPrimitive,
                                        JS::UndefinedHandleValue,
-                                       JSPROP_READONLY | JSPROP_PERMANENT) ||
-                !JS_DefineProperty(aCx, ${holderName}, "toJSON",
-                                   JS::UndefinedHandleValue,
-                                   JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
+                                       JSPROP_READONLY | JSPROP_PERMANENT)) {
               $*{failureCode}
             }
             """,
             failureCode=failureCode,
             holderName=holderName)))
 
     return CGWrapper(CGList(unforgeables), pre="\n")
 
--- a/js/xpconnect/tests/chrome/test_bug1041626.xul
+++ b/js/xpconnect/tests/chrome/test_bug1041626.xul
@@ -23,19 +23,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   function go() {
 
     //
     // Location
     //
 
     ok(Cu.isXrayWrapper(window[0].location), "Location is Xrayed");
     let xrayOwnProperties = Object.getOwnPropertyNames(window[0].location);
-    todo(xrayOwnProperties.indexOf('toJSON') != -1,
-         "dummy toJSON on Location should show up in Xrayable properties");
-    xrayOwnProperties.push('toJSON');
 
     let realOwnProperties = Object.getOwnPropertyNames(window[0].wrappedJSObject.location);
     ok(realOwnProperties.length > 2);
 
     is(xrayOwnProperties.sort().toSource(), realOwnProperties.sort().toSource(),
        "Xray enumerates location properties properly");
 
     //
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -88211,16 +88211,34 @@
     ]
    ],
    "html/browsers/history/the-location-interface/location-stringifier.html": [
     [
      "/html/browsers/history/the-location-interface/location-stringifier.html",
      {}
     ]
    ],
+   "html/browsers/history/the-location-interface/location-symbol-toprimitive.html": [
+    [
+     "/html/browsers/history/the-location-interface/location-symbol-toprimitive.html",
+     {}
+    ]
+   ],
+   "html/browsers/history/the-location-interface/location-tojson.html": [
+    [
+     "/html/browsers/history/the-location-interface/location-tojson.html",
+     {}
+    ]
+   ],
+   "html/browsers/history/the-location-interface/location-valueof.html": [
+    [
+     "/html/browsers/history/the-location-interface/location-valueof.html",
+     {}
+    ]
+   ],
    "html/browsers/history/the-location-interface/location_assign.html": [
     [
      "/html/browsers/history/the-location-interface/location_assign.html",
      {}
     ]
    ],
    "html/browsers/history/the-location-interface/location_assign_about_blank.html": [
     [
@@ -164999,17 +165017,29 @@
    "70f3c81ddfe58e8751543513fbd8ea44a6b122a1",
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location-prototype-setting.html": [
    "47a284185d6abb33d601a3b066a72bf480b515e7",
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location-stringifier.html": [
-   "d7cea275e734051c77e820488ae04742dc073c26",
+   "25cf5b1fabfc32bdfed8803a07f4498aa764d148",
+   "testharness"
+  ],
+  "html/browsers/history/the-location-interface/location-symbol-toprimitive.html": [
+   "f1216c7e9375e855e4e57d5396eee58c1eac0950",
+   "testharness"
+  ],
+  "html/browsers/history/the-location-interface/location-tojson.html": [
+   "caeb36aec042ae39289becc4250f941822973fdb",
+   "testharness"
+  ],
+  "html/browsers/history/the-location-interface/location-valueof.html": [
+   "f192bc7f3ab76ba77002a00086a62088e46ad777",
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location_assign.html": [
    "25cf2537db65db3f85705810f588992236a38fbd",
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location_assign_about_blank-1.html": [
    "2921019f87a4cb4e189500e746bb7720ea006e55",
--- a/testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-stringifier.html
@@ -3,9 +3,22 @@
 <link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
 <link rel="help" href="https://heycam.github.io/webidl/#es-stringifier">
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script src=/common/stringifiers.js></script>
 <div id=log></div>
 <script>
 test_stringifier_attribute(location, "href", true);
+
+test(function() {
+  const prop1 = Object.getOwnPropertyDescriptor(location, "toString"),
+        prop2 = Object.getOwnPropertyDescriptor(location, "href")
+
+  assert_true(prop1.enumerable)
+  assert_false(prop1.writable)
+  assert_false(prop1.configurable)
+
+  assert_true(prop2.enumerable)
+  assert_false(prop2.configurable)
+  assert_equals(typeof prop2.get, "function")
+})
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-symbol-toprimitive.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Location Symbol.toPrimitive</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(() => {
+  assert_equals(location[Symbol.toPrimitive], undefined)
+  const prop = Object.getOwnPropertyDescriptor(location, Symbol.toPrimitive)
+  assert_false(prop.enumerable)
+  assert_false(prop.writable)
+  assert_false(prop.configurable)
+})
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-tojson.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>Location has no toJSON</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(() => {
+  assert_equals(location.toJSON, undefined)
+  assert_equals(Object.getOwnPropertyDescriptor(location, "toJSON"), undefined)
+  assert_false(location.hasOwnProperty("toJSON"))
+})
+</script>
+<!-- See https://github.com/whatwg/html/pull/2294 for context. (And the HTML Standard of course.) -->
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/history/the-location-interface/location-valueof.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Location valueOf</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(() => {
+  assert_equals(location.valueOf, Object.prototype.valueOf)
+  assert_equals(typeof location.valueOf.call(5), "object")
+  const prop = Object.getOwnPropertyDescriptor(location, "valueOf")
+  assert_false(prop.enumerable)
+  assert_false(prop.writable)
+  assert_false(prop.configurable)
+})
+</script>