Bug 1289340 - Expose Intl.DateTimeFormat.prototype.formatToParts. r=waldo
authorZibi Braniecki <gandalf@mozilla.com>
Tue, 13 Sep 2016 20:49:21 -0700
changeset 313773 3f47a92541c8e445757683d0e3e21e6df5d1a0d2
parent 313772 f7275e98b63bcf62ea38f38456c71ab28ed058f7
child 313774 908976ec552609d50bf14f5cace757808a51864f
push id81711
push userzbraniecki@mozilla.com
push dateWed, 14 Sep 2016 03:49:28 +0000
treeherdermozilla-inbound@3f47a92541c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1289340
milestone51.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 1289340 - Expose Intl.DateTimeFormat.prototype.formatToParts. r=waldo MozReview-Commit-ID: Ii7TqMDRzu4
js/src/builtin/Intl.cpp
js/src/jsapi.h
js/src/shell/js.cpp
js/src/tests/Intl/DateTimeFormat/formatToParts.js
js/src/vm/CommonPropertyNames.h
js/xpconnect/src/nsXPConnect.cpp
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -1669,16 +1669,17 @@ dateTimeFormat_toSource(JSContext* cx, u
 
 static const JSFunctionSpec dateTimeFormat_static_methods[] = {
     JS_SELF_HOSTED_FN("supportedLocalesOf", "Intl_DateTimeFormat_supportedLocalesOf", 1, 0),
     JS_FS_END
 };
 
 static const JSFunctionSpec dateTimeFormat_methods[] = {
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_DateTimeFormat_resolvedOptions", 0, 0),
+    JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 0, 0),
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0),
 #endif
     JS_FS_END
 };
 
 /**
  * DateTimeFormat constructor.
@@ -1806,33 +1807,16 @@ CreateDateTimeFormatPrototype(JSContext*
     }
     if (!DefineProperty(cx, proto, cx->names().format, UndefinedHandleValue,
                         JS_DATA_TO_FUNC_PTR(JSGetterOp, &getter.toObject()),
                         nullptr, JSPROP_GETTER | JSPROP_SHARED))
     {
         return nullptr;
     }
 
-    // If the still-experimental DateTimeFormat.prototype.formatToParts method
-    // is enabled, also add it.
-    if (cx->compartment()->creationOptions().experimentalDateTimeFormatFormatToPartsEnabled()) {
-        RootedValue ftp(cx);
-        HandlePropertyName name = cx->names().formatToParts;
-        if (!GlobalObject::getSelfHostedFunction(cx, cx->global(),
-                    cx->names().DateTimeFormatFormatToParts,
-                    name,
-                    0, &ftp))
-        {
-            return nullptr;
-        }
-
-        if (!DefineProperty(cx, proto, cx->names().formatToParts, ftp, nullptr, nullptr, 0))
-            return nullptr;
-    }
-
     RootedValue options(cx);
     if (!CreateDefaultOptions(cx, &options))
         return nullptr;
 
     // 12.2.1 and 12.3
     if (!IntlInitialize(cx, proto, cx->names().InitializeDateTimeFormat, UndefinedHandleValue,
                         options))
     {
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2140,17 +2140,16 @@ class JS_PUBLIC_API(CompartmentCreationO
   public:
     CompartmentCreationOptions()
       : addonId_(nullptr),
         traceGlobal_(nullptr),
         invisibleToDebugger_(false),
         mergeable_(false),
         preserveJitCode_(false),
         cloneSingletons_(false),
-        experimentalDateTimeFormatFormatToPartsEnabled_(false),
         sharedMemoryAndAtomics_(false),
         secureContext_(false)
     {
         zone_.spec = JS::FreshZone;
     }
 
     // A null add-on ID means that the compartment is not associated with an
     // add-on.
@@ -2205,33 +2204,16 @@ class JS_PUBLIC_API(CompartmentCreationO
     }
 
     bool cloneSingletons() const { return cloneSingletons_; }
     CompartmentCreationOptions& setCloneSingletons(bool flag) {
         cloneSingletons_ = flag;
         return *this;
     }
 
-    // ECMA-402 is considering adding a "formatToParts" DateTimeFormat method,
-    // that exposes not just a formatted string but its ordered subcomponents.
-    // The method, its semantics, and its name are all well short of being
-    // finalized, so for now it's exposed *only* if requested.
-    //
-    // Until "formatToParts" is included in a final specification edition, it's
-    // subject to change or removal at any time.  Do *not* rely on it in
-    // mission-critical code that can't be changed if ECMA-402 decides not to
-    // accept the method in its current form.
-    bool experimentalDateTimeFormatFormatToPartsEnabled() const {
-        return experimentalDateTimeFormatFormatToPartsEnabled_;
-    }
-    CompartmentCreationOptions& setExperimentalDateTimeFormatFormatToPartsEnabled(bool flag) {
-        experimentalDateTimeFormatFormatToPartsEnabled_ = flag;
-        return *this;
-    }
-
     bool getSharedMemoryAndAtomicsEnabled() const;
     CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
 
     // This flag doesn't affect JS engine behavior.  It is used by Gecko to
     // mark whether content windows and workers are "Secure Context"s. See
     // https://w3c.github.io/webappsec-secure-contexts/
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
     bool secureContext() const { return secureContext_; }
@@ -2246,17 +2228,16 @@ class JS_PUBLIC_API(CompartmentCreationO
     union {
         ZoneSpecifier spec;
         void* pointer; // js::Zone* is not exposed in the API.
     } zone_;
     bool invisibleToDebugger_;
     bool mergeable_;
     bool preserveJitCode_;
     bool cloneSingletons_;
-    bool experimentalDateTimeFormatFormatToPartsEnabled_;
     bool sharedMemoryAndAtomics_;
     bool secureContext_;
 };
 
 /**
  * CompartmentBehaviors specifies behaviors of a compartment that can be
  * changed after the compartment's been created.
  */
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4455,21 +4455,16 @@ NewGlobal(JSContext* cx, unsigned argc, 
         if (v.isBoolean())
             creationOptions.setInvisibleToDebugger(v.toBoolean());
 
         if (!JS_GetProperty(cx, opts, "cloneSingletons", &v))
             return false;
         if (v.isBoolean())
             creationOptions.setCloneSingletons(v.toBoolean());
 
-        if (!JS_GetProperty(cx, opts, "experimentalDateTimeFormatFormatToPartsEnabled", &v))
-            return false;
-        if (v.isBoolean())
-            creationOptions.setExperimentalDateTimeFormatFormatToPartsEnabled(v.toBoolean());
-
         if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
             return false;
         if (v.isObject())
             creationOptions.setSameZoneAs(UncheckedUnwrap(&v.toObject()));
 
         if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v))
             return false;
         if (v.isBoolean())
--- a/js/src/tests/Intl/DateTimeFormat/formatToParts.js
+++ b/js/src/tests/Intl/DateTimeFormat/formatToParts.js
@@ -1,9 +1,9 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.newGlobal||!newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat().formatToParts)
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
 // Any copyright is dedicated to the Public Domain.
 // http://creativecommons.org/licenses/publicdomain/
 
 // Tests the format function with a diverse set of locales and options.
 // Always use UTC to avoid dependencies on test environment.
 
 /*
  * Return true if A is equal to B, where equality on arrays and objects
@@ -42,65 +42,59 @@ function deepEqual(a, b) {
 function composeDate(parts) {
   return parts.map(({value}) => value)
               .reduce((string, part) => string + part);
 }
 
 var format;
 var date = Date.UTC(2012, 11, 17, 3, 0, 42);
 
-// The experimental formatToParts method is only exposed if specifically
-// requested.  Perform all tests using DateTimeFormat instances from a global
-// object with this method enabled.
-var DateTimeFormat =
-  newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat;
-
 // Locale en-US; default options.
-format = new DateTimeFormat("en-us", {timeZone: "UTC"});
+format = new Intl.DateTimeFormat("en-us", {timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'month', value: '12' },
   { type: 'literal', value: '/' },
   { type: 'day', value: '17' },
   { type: 'literal', value: '/' },
   { type: 'year', value: '2012' }
 ]), true);
 
 // Just date
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   year: 'numeric',
   month: 'numeric',
   day: 'numeric',
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'month', value: '12' },
   { type: 'literal', value: '/' },
   { type: 'day', value: '17' },
   { type: 'literal', value: '/' },
   { type: 'year', value: '2012' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Just time in hour24
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   hour: 'numeric',
   minute: 'numeric',
   second: 'numeric',
   hour12: false,
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'hour', value: '03' },
   { type: 'literal', value: ':' },
   { type: 'minute', value: '00' },
   { type: 'literal', value: ':' },
   { type: 'second', value: '42' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Just time in hour12
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   hour: 'numeric',
   minute: 'numeric',
   second: 'numeric',
   hour12: true,
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'hour', value: '3' },
   { type: 'literal', value: ':' },
@@ -108,47 +102,47 @@ assertEq(deepEqual(format.formatToParts(
   { type: 'literal', value: ':' },
   { type: 'second', value: '42' },
   { type: 'literal', value: ' ' },
   { type: 'dayPeriod', value: 'AM' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Just month.
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   month: "narrow",
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'month', value: 'D' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Just weekday.
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   weekday: "narrow",
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'weekday', value: 'M' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Year and era.
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   year: "numeric",
   era: "short",
   timeZone: "UTC"});
 assertEq(deepEqual(format.formatToParts(date), [
   { type: 'year', value: '2012' },
   { type: 'literal', value: ' ' },
   { type: 'era', value: 'AD' }
 ]), true);
 assertEq(composeDate(format.formatToParts(date)), format.format(date));
 
 // Time and date
-format = new DateTimeFormat("en-us", {
+format = new Intl.DateTimeFormat("en-us", {
   weekday: 'long',
   year: 'numeric',
   month: 'numeric',
   day: 'numeric',
   hour: 'numeric',
   minute: 'numeric',
   second: 'numeric',
   hour12: true,
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -110,17 +110,16 @@
     macro(flags, flags, "flags") \
     macro(float32, float32, "float32") \
     macro(Float32x4, Float32x4, "Float32x4") \
     macro(float64, float64, "float64") \
     macro(Float64x2, Float64x2, "Float64x2") \
     macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
     macro(forEach, forEach, "forEach") \
     macro(format, format, "format") \
-    macro(formatToParts, formatToParts, "formatToParts") \
     macro(frame, frame, "frame") \
     macro(from, from, "from") \
     macro(fulfilled, fulfilled, "fulfilled") \
     macro(fulfillHandler, fulfillHandler, "fulfillHandler") \
     macro(futexNotEqual, futexNotEqual, "not-equal") \
     macro(futexOK, futexOK, "ok") \
     macro(futexTimedOut, futexTimedOut, "timed-out") \
     macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -434,22 +434,16 @@ InitGlobalObjectOptions(JS::CompartmentO
     bool shouldDiscardSystemSource = ShouldDiscardSystemSource();
     bool extraWarningsForSystemJS = ExtraWarningsForSystemJS();
 
     bool isSystem = nsContentUtils::IsSystemPrincipal(aPrincipal);
 
     if (isSystem) {
         // Make sure [SecureContext] APIs are visible:
         aOptions.creationOptions().setSecureContext(true);
-
-#if 0 // TODO: Reenable in Bug 1288653
-        // Enable the ECMA-402 experimental formatToParts in any chrome page
-        aOptions.creationOptions()
-                .setExperimentalDateTimeFormatFormatToPartsEnabled(true);
-#endif
     }
 
     if (shouldDiscardSystemSource) {
         bool discardSource = isSystem;
 
         aOptions.behaviors().setDiscardSource(discardSource);
     }