OLD | NEW |
| (Empty) |
1 // Copyright 2013 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 // limitations under the License. | |
28 | |
29 // ECMAScript 402 API implementation is broken into separate files for | |
30 // each service. The build system combines them together into one | |
31 // Intl namespace. | |
32 | |
33 | |
34 // Save references to Intl objects and methods we use, for added security. | |
35 var savedObjects = { | |
36 'collator': Intl.Collator, | |
37 'numberformat': Intl.NumberFormat, | |
38 'dateformatall': Intl.DateTimeFormat, | |
39 'dateformatdate': Intl.DateTimeFormat, | |
40 'dateformattime': Intl.DateTimeFormat | |
41 }; | |
42 | |
43 | |
44 // Default (created with undefined locales and options parameters) collator, | |
45 // number and date format instances. They'll be created as needed. | |
46 var defaultObjects = { | |
47 'collator': undefined, | |
48 'numberformat': undefined, | |
49 'dateformatall': undefined, | |
50 'dateformatdate': undefined, | |
51 'dateformattime': undefined, | |
52 }; | |
53 | |
54 | |
55 /** | |
56 * Returns cached or newly created instance of a given service. | |
57 * We cache only default instances (where no locales or options are provided). | |
58 */ | |
59 function cachedOrNewService(service, locales, options, defaults) { | |
60 var useOptions = (defaults === undefined) ? options : defaults; | |
61 if (locales === undefined && options === undefined) { | |
62 if (defaultObjects[service] === undefined) { | |
63 defaultObjects[service] = new savedObjects[service](locales, useOptions); | |
64 } | |
65 return defaultObjects[service]; | |
66 } | |
67 return new savedObjects[service](locales, useOptions); | |
68 } | |
69 | |
70 | |
71 /** | |
72 * Compares this and that, and returns less than 0, 0 or greater than 0 value. | |
73 * Overrides the built-in method. | |
74 */ | |
75 Object.defineProperty(String.prototype, 'localeCompare', { | |
76 value: function(that) { | |
77 if (%_IsConstructCall()) { | |
78 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); | |
79 } | |
80 | |
81 if (this === undefined || this === null) { | |
82 throw new TypeError('Method invoked on undefined or null value.'); | |
83 } | |
84 | |
85 var locales = arguments[1]; | |
86 var options = arguments[2]; | |
87 var collator = cachedOrNewService('collator', locales, options); | |
88 return compare(collator, this, that); | |
89 }, | |
90 writable: true, | |
91 configurable: true, | |
92 enumerable: false | |
93 }); | |
94 %FunctionSetName(String.prototype.localeCompare, 'localeCompare'); | |
95 %FunctionRemovePrototype(String.prototype.localeCompare); | |
96 %SetNativeFlag(String.prototype.localeCompare); | |
97 | |
98 | |
99 /** | |
100 * Formats a Number object (this) using locale and options values. | |
101 * If locale or options are omitted, defaults are used. | |
102 */ | |
103 Object.defineProperty(Number.prototype, 'toLocaleString', { | |
104 value: function() { | |
105 if (%_IsConstructCall()) { | |
106 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); | |
107 } | |
108 | |
109 if (!(this instanceof Number) && typeof(this) !== 'number') { | |
110 throw new TypeError('Method invoked on an object that is not Number.'); | |
111 } | |
112 | |
113 var locales = arguments[0]; | |
114 var options = arguments[1]; | |
115 var numberFormat = cachedOrNewService('numberformat', locales, options); | |
116 return formatNumber(numberFormat, this); | |
117 }, | |
118 writable: true, | |
119 configurable: true, | |
120 enumerable: false | |
121 }); | |
122 %FunctionSetName(Number.prototype.toLocaleString, 'toLocaleString'); | |
123 %FunctionRemovePrototype(Number.prototype.toLocaleString); | |
124 %SetNativeFlag(Number.prototype.toLocaleString); | |
125 | |
126 | |
127 /** | |
128 * Returns actual formatted date or fails if date parameter is invalid. | |
129 */ | |
130 function toLocaleDateTime(date, locales, options, required, defaults, service) { | |
131 if (!(date instanceof Date)) { | |
132 throw new TypeError('Method invoked on an object that is not Date.'); | |
133 } | |
134 | |
135 if (isNaN(date)) { | |
136 return 'Invalid Date'; | |
137 } | |
138 | |
139 var internalOptions = toDateTimeOptions(options, required, defaults); | |
140 | |
141 var dateFormat = | |
142 cachedOrNewService(service, locales, options, internalOptions); | |
143 | |
144 return formatDate(dateFormat, date); | |
145 } | |
146 | |
147 | |
148 /** | |
149 * Formats a Date object (this) using locale and options values. | |
150 * If locale or options are omitted, defaults are used - both date and time are | |
151 * present in the output. | |
152 */ | |
153 Object.defineProperty(Date.prototype, 'toLocaleString', { | |
154 value: function() { | |
155 if (%_IsConstructCall()) { | |
156 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); | |
157 } | |
158 | |
159 var locales = arguments[0]; | |
160 var options = arguments[1]; | |
161 return toLocaleDateTime( | |
162 this, locales, options, 'any', 'all', 'dateformatall'); | |
163 }, | |
164 writable: true, | |
165 configurable: true, | |
166 enumerable: false | |
167 }); | |
168 %FunctionSetName(Date.prototype.toLocaleString, 'toLocaleString'); | |
169 %FunctionRemovePrototype(Date.prototype.toLocaleString); | |
170 %SetNativeFlag(Date.prototype.toLocaleString); | |
171 | |
172 | |
173 /** | |
174 * Formats a Date object (this) using locale and options values. | |
175 * If locale or options are omitted, defaults are used - only date is present | |
176 * in the output. | |
177 */ | |
178 Object.defineProperty(Date.prototype, 'toLocaleDateString', { | |
179 value: function() { | |
180 if (%_IsConstructCall()) { | |
181 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); | |
182 } | |
183 | |
184 var locales = arguments[0]; | |
185 var options = arguments[1]; | |
186 return toLocaleDateTime( | |
187 this, locales, options, 'date', 'date', 'dateformatdate'); | |
188 }, | |
189 writable: true, | |
190 configurable: true, | |
191 enumerable: false | |
192 }); | |
193 %FunctionSetName(Date.prototype.toLocaleDateString, 'toLocaleDateString'); | |
194 %FunctionRemovePrototype(Date.prototype.toLocaleDateString); | |
195 %SetNativeFlag(Date.prototype.toLocaleDateString); | |
196 | |
197 | |
198 /** | |
199 * Formats a Date object (this) using locale and options values. | |
200 * If locale or options are omitted, defaults are used - only time is present | |
201 * in the output. | |
202 */ | |
203 Object.defineProperty(Date.prototype, 'toLocaleTimeString', { | |
204 value: function() { | |
205 if (%_IsConstructCall()) { | |
206 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); | |
207 } | |
208 | |
209 var locales = arguments[0]; | |
210 var options = arguments[1]; | |
211 return toLocaleDateTime( | |
212 this, locales, options, 'time', 'time', 'dateformattime'); | |
213 }, | |
214 writable: true, | |
215 configurable: true, | |
216 enumerable: false | |
217 }); | |
218 %FunctionSetName(Date.prototype.toLocaleTimeString, 'toLocaleTimeString'); | |
219 %FunctionRemovePrototype(Date.prototype.toLocaleTimeString); | |
220 %SetNativeFlag(Date.prototype.toLocaleTimeString); | |
OLD | NEW |