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 %FunctionRemovePrototype(String.prototype.localeCompare); |
| 95 |
| 96 |
| 97 /** |
| 98 * Formats a Number object (this) using locale and options values. |
| 99 * If locale or options are omitted, defaults are used. |
| 100 */ |
| 101 Object.defineProperty(Number.prototype, 'toLocaleString', { |
| 102 value: function() { |
| 103 if (%_IsConstructCall()) { |
| 104 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); |
| 105 } |
| 106 |
| 107 if (!(this instanceof Number) && typeof(this) !== 'number') { |
| 108 throw new TypeError('Method invoked on an object that is not Number.'); |
| 109 } |
| 110 |
| 111 var locales = arguments[0]; |
| 112 var options = arguments[1]; |
| 113 var numberFormat = cachedOrNewService('numberformat', locales, options); |
| 114 return formatNumber(numberFormat, this); |
| 115 }, |
| 116 writable: true, |
| 117 configurable: true, |
| 118 enumerable: false |
| 119 }); |
| 120 %FunctionRemovePrototype(Number.prototype.toLocaleString); |
| 121 |
| 122 |
| 123 /** |
| 124 * Returns actual formatted date or fails if date parameter is invalid. |
| 125 */ |
| 126 function toLocaleDateTime(date, locales, options, required, defaults, service) { |
| 127 if (!(date instanceof Date)) { |
| 128 throw new TypeError('Method invoked on an object that is not Date.'); |
| 129 } |
| 130 |
| 131 if (isNaN(date)) { |
| 132 return 'Invalid Date'; |
| 133 } |
| 134 |
| 135 var internalOptions = toDateTimeOptions(options, required, defaults); |
| 136 |
| 137 var dateFormat = |
| 138 cachedOrNewService(service, locales, options, internalOptions); |
| 139 |
| 140 return formatDate(dateFormat, date); |
| 141 } |
| 142 |
| 143 |
| 144 /** |
| 145 * Formats a Date object (this) using locale and options values. |
| 146 * If locale or options are omitted, defaults are used - both date and time are |
| 147 * present in the output. |
| 148 */ |
| 149 Object.defineProperty(Date.prototype, 'toLocaleString', { |
| 150 value: function() { |
| 151 if (%_IsConstructCall()) { |
| 152 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); |
| 153 } |
| 154 |
| 155 var locales = arguments[0]; |
| 156 var options = arguments[1]; |
| 157 return toLocaleDateTime( |
| 158 this, locales, options, 'any', 'all', 'dateformatall'); |
| 159 }, |
| 160 writable: true, |
| 161 configurable: true, |
| 162 enumerable: false |
| 163 }); |
| 164 %FunctionRemovePrototype(Date.prototype.toLocaleString); |
| 165 |
| 166 |
| 167 /** |
| 168 * Formats a Date object (this) using locale and options values. |
| 169 * If locale or options are omitted, defaults are used - only date is present |
| 170 * in the output. |
| 171 */ |
| 172 Object.defineProperty(Date.prototype, 'toLocaleDateString', { |
| 173 value: function() { |
| 174 if (%_IsConstructCall()) { |
| 175 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); |
| 176 } |
| 177 |
| 178 var locales = arguments[0]; |
| 179 var options = arguments[1]; |
| 180 return toLocaleDateTime( |
| 181 this, locales, options, 'date', 'date', 'dateformatdate'); |
| 182 }, |
| 183 writable: true, |
| 184 configurable: true, |
| 185 enumerable: false |
| 186 }); |
| 187 %FunctionRemovePrototype(Date.prototype.toLocaleDateString); |
| 188 |
| 189 |
| 190 /** |
| 191 * Formats a Date object (this) using locale and options values. |
| 192 * If locale or options are omitted, defaults are used - only time is present |
| 193 * in the output. |
| 194 */ |
| 195 Object.defineProperty(Date.prototype, 'toLocaleTimeString', { |
| 196 value: function() { |
| 197 if (%_IsConstructCall()) { |
| 198 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); |
| 199 } |
| 200 |
| 201 var locales = arguments[0]; |
| 202 var options = arguments[1]; |
| 203 return toLocaleDateTime( |
| 204 this, locales, options, 'time', 'time', 'dateformattime'); |
| 205 }, |
| 206 writable: true, |
| 207 configurable: true, |
| 208 enumerable: false |
| 209 }); |
| 210 %FunctionRemovePrototype(Date.prototype.toLocaleTimeString); |
OLD | NEW |