[JSC] Drop direct references to Intl constructors by rewriting Intl JS builtins in C++
[WebKit-https.git] / Source / JavaScriptCore / builtins / DatePrototype.js
1 /*
2  * Copyright (C) 2015 Andy VanWagoner <andy@vanwagoner.family>.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 // @conditional=ENABLE(INTL)
27
28 function toLocaleString(/* locales, options */)
29 {
30     "use strict";
31
32     function toDateTimeOptionsAnyAll(opts)
33     {
34         // ToDateTimeOptions(options, "any", "all")
35         // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
36
37         var options;
38         if (opts === @undefined)
39             options = null;
40         else if (opts === null)
41             @throwTypeError("null is not an object");
42         else
43             options = @toObject(opts);
44
45         // Check original instead of descendant to reduce lookups up the prototype chain.
46         var needsDefaults = !options || (
47             options.weekday === @undefined &&
48             options.year === @undefined &&
49             options.month === @undefined &&
50             options.day === @undefined &&
51             options.hour === @undefined &&
52             options.minute === @undefined &&
53             options.second === @undefined
54         );
55
56         // Only create descendant if it will have own properties.
57         if (needsDefaults) {
58             options = @Object.@create(options);
59             options.year = "numeric";
60             options.month = "numeric";
61             options.day = "numeric";
62             options.hour = "numeric";
63             options.minute = "numeric";
64             options.second = "numeric";
65         }
66
67         // 9. Return options.
68         return options;
69     }
70
71     // 13.3.1 Date.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0)
72     // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleString
73
74     var value = @thisTimeValue.@call(this);
75     if (@isNaN(value))
76         return "Invalid Date";
77
78     var options = toDateTimeOptionsAnyAll(@argument(1));
79     var locales = @argument(0);
80     return @dateTimeFormat(locales, options, value);
81 }
82
83 function toLocaleDateString(/* locales, options */)
84 {
85     "use strict";
86
87     function toDateTimeOptionsDateDate(opts)
88     {
89         // ToDateTimeOptions(options, "date", "date")
90         // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
91
92         var options;
93         if (opts === @undefined)
94             options = null;
95         else if (opts === null)
96             @throwTypeError("null is not an object");
97         else
98             options = @toObject(opts);
99
100         // Check original instead of descendant to reduce lookups up the prototype chain.
101         var needsDefaults = !options || (
102             options.weekday === @undefined &&
103             options.year === @undefined &&
104             options.month === @undefined &&
105             options.day === @undefined
106         );
107
108         // Only create descendant if it will have own properties.
109         if (needsDefaults) {
110             options = @Object.@create(options);
111             options.year = "numeric";
112             options.month = "numeric";
113             options.day = "numeric";
114         }
115
116         return options;
117     }
118
119     // 13.3.2 Date.prototype.toLocaleDateString ([locales [, options ]]) (ECMA-402 2.0)
120     // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleDateString
121
122     var value = @thisTimeValue.@call(this);
123     if (@isNaN(value))
124         return "Invalid Date";
125
126     var options = toDateTimeOptionsDateDate(@argument(1));
127     var locales = @argument(0);
128     return @dateTimeFormat(locales, options, value);
129 }
130
131 function toLocaleTimeString(/* locales, options */)
132 {
133     "use strict";
134
135     function toDateTimeOptionsTimeTime(opts)
136     {
137         // ToDateTimeOptions(options, "time", "time")
138         // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
139
140         var options;
141         if (opts === @undefined)
142             options = null;
143         else if (opts === null)
144             @throwTypeError("null is not an object");
145         else
146             options = @toObject(opts);
147
148         // Check original instead of descendant to reduce lookups up the prototype chain.
149         var needsDefaults = !options || (
150             options.hour === @undefined &&
151             options.minute === @undefined &&
152             options.second === @undefined
153         );
154
155         // Only create descendant if it will have own properties.
156         if (needsDefaults) {
157             options = @Object.@create(options);
158             options.hour = "numeric";
159             options.minute = "numeric";
160             options.second = "numeric";
161         }
162
163         return options;
164     }
165
166     // 13.3.3 Date.prototype.toLocaleTimeString ([locales [, options ]]) (ECMA-402 2.0)
167     // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleTimeString
168
169     var value = @thisTimeValue.@call(this);
170     if (@isNaN(value))
171         return "Invalid Date";
172
173     var options = toDateTimeOptionsTimeTime(@argument(1));
174     var locales = @argument(0);
175     return @dateTimeFormat(locales, options, value);
176 }