| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| var GlobalizationError = require('./GlobalizationError'); |
| var moment = require('cordova-plugin-globalization.moment'); |
| |
| function getCrossPlatformLocale() { |
| // userLanguage is for IE, which corresponds to selected regional format |
| return navigator.userLanguage || navigator.language; |
| } |
| |
| function stdTimezoneOffset(date) { |
| var jan = new Date(date.getFullYear(), 0, 20); |
| var jul = new Date(date.getFullYear(), 6, 20); |
| return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); |
| } |
| |
| function dst(date) { |
| return date.getTimezoneOffset() < stdTimezoneOffset(date); |
| } |
| |
| function dstOffsetAbs(date) { |
| var janOffset = new Date(date.getFullYear(), 0, 20).getTimezoneOffset(); |
| var julOffset = new Date(date.getFullYear(), 6, 20).getTimezoneOffset(); |
| if (janOffset < 0) { janOffset = -janOffset; } |
| if (julOffset < 0) { julOffset = -julOffset; } |
| var offset = janOffset - julOffset; |
| if (offset < 0) { offset = -offset; } |
| return offset; |
| } |
| |
| function getWeekDayNames(locale, options) { |
| var result = [], date; |
| for (var i = 0; i < 7; i++) { |
| date = new Date(2014, 5, i + 1, 0, 0, 0, 0); |
| result[i] = date.toLocaleDateString(locale, options); |
| } |
| return result; |
| } |
| |
| function convertToIntlNumberFormatOptions(options) { |
| switch (options.type) { |
| case 'decimal': |
| return { style: 'decimal' }; |
| case 'currency': |
| throw '\'currency\' number type is not supported'; |
| case 'percent': |
| return { style: 'percent' }; |
| default: |
| throw 'The options.type can be \'decimal\', \'percent\' or \'currency\''; |
| } |
| } |
| |
| function convertToMomentLocalizedFormat(options) { |
| var selectorError = 'The options.selector can be \'date\', \'time\' or \'date and time\''; |
| var formatLengthError = 'The options.formatLength can be \'short\', \'medium\', \'long\', or \'full\''; |
| |
| switch (options.formatLength) { |
| case 'short': |
| switch(options.selector) { |
| case 'date and time': return 'lll'; |
| case 'date': return 'l'; |
| case 'time': return 'LT'; |
| default: |
| throw selectorError; |
| } |
| break; |
| case 'medium': |
| switch(options.selector) { |
| case 'date and time': return 'LLL'; |
| case 'date': return 'L'; |
| case 'time': |
| throw '\'time\' selector does not support \'medium\' formatLength'; |
| default: |
| throw selectorError; |
| } |
| break; |
| case 'long': |
| switch(options.selector) { |
| case 'date and time': return 'llll'; |
| case 'date': return 'll'; |
| case 'time': |
| throw '\'time\' selector does not support \'long\' formatLength'; |
| default: |
| throw selectorError; |
| } |
| break; |
| case 'full': |
| switch(options.selector) { |
| case 'date and time': return 'LLLL'; |
| case 'date': return 'LL'; |
| case 'time': return 'LTS'; |
| default: |
| throw selectorError; |
| } |
| break; |
| default: |
| throw formatLengthError; |
| } |
| } |
| |
| function prepareAndGetDateOptions(options) { |
| options = options || {formatLength:'short', selector:'date and time'}; |
| options.formatLength = options.formatLength || 'short'; |
| options.selector = options.selector || 'date and time'; |
| |
| return convertToMomentLocalizedFormat(options); |
| } |
| |
| var globalization = { |
| getLocaleName: function(win, fail) { |
| try { |
| win( { value: getCrossPlatformLocale() }); |
| } catch (e) { |
| fail({ code: 0, message: e.hasOwnProperty('message')? e.message : e }); |
| } |
| }, |
| |
| numberToString: function(win, fail, args) { |
| try { |
| var options = args[0].options || { type : 'decimal' }; |
| options.type = options.type || 'decimal'; |
| |
| options = convertToIntlNumberFormatOptions(options); |
| |
| var formatter = new Intl.NumberFormat(getCrossPlatformLocale(), options); |
| win( { value: formatter.format(args[0].number) }); |
| } catch (e) { |
| fail(new GlobalizationError(GlobalizationError.FORMATTING_ERROR, |
| e.hasOwnProperty('message')? e.message : e)); |
| } |
| }, |
| |
| isDayLightSavingsTime: function(win, fail, args) { |
| try { |
| var date = new Date(args[0].date); |
| win({ dst: dst(date) }); |
| } catch (e) { |
| fail({ code: 0, message: e.hasOwnProperty('message')? e.message : e }); |
| } |
| }, |
| |
| getFirstDayOfWeek: function(win, fail) { |
| try { |
| var locale = getCrossPlatformLocale(); |
| moment.locale(locale); |
| // Converting ISO format (Monday = 1, Sunday = 7) to what Cordova expects (Sunday = 1, Monday = 2, Saturday = 7) |
| var shiftDay = moment().weekday(0).isoWeekday() + 1; |
| win({ value: shiftDay % 8 + Math.floor(shiftDay / 8) }); |
| } catch (e) { |
| fail({ code: 0, message: e.hasOwnProperty('message')? e.message : e }); |
| } |
| }, |
| |
| getDateNames: function (win, fail, args) { |
| try { |
| var options = args[0].options || { type: 'wide', item: 'months' }; |
| var type = options.type || 'wide'; |
| var item = options.item || 'item'; |
| |
| var locale = getCrossPlatformLocale(); |
| |
| if (item === 'months' && type === 'wide') { |
| options = { month: 'long' }; |
| } else if (item === 'months' && type === 'narrow') { |
| options = { month: 'short'}; |
| } else if (item === 'days' && type === 'wide') { |
| options = { weekday: 'long'}; |
| } else if (item === 'days' && type === 'narrow') { |
| options = { weekday: 'short'}; |
| } else { |
| throw 'Incorrect type or item'; |
| } |
| |
| var result = []; |
| if (item === 'months') { |
| for (var i = 0; i < 12; i++) { |
| var date = new Date(2014, i, 20, 0, 0, 0, 0); |
| result[i] = date.toLocaleDateString(locale, options); |
| } |
| } else { |
| result = getWeekDayNames(locale, options); |
| } |
| |
| win({ value: result }); |
| } catch (e) { |
| fail({ code: 0, message: e.hasOwnProperty('message')? e.message : e }); |
| } |
| }, |
| |
| getDatePattern: function(win, fail) { |
| try { |
| var formatter = new Intl.DateTimeFormat(getCrossPlatformLocale()); |
| var timezone = formatter.hasOwnProperty('resolved') ? formatter.resolved.timeZone : ''; |
| var dstOffset = dstOffsetAbs(new Date()); |
| |
| win( { |
| utc_offset: new Date().getTimezoneOffset() * (-60), |
| dst_offset: dstOffset * 60, |
| timezone: timezone, |
| pattern: '', |
| }); |
| } catch (e) { |
| fail(new GlobalizationError(GlobalizationError.PATTERN_ERROR, |
| e.hasOwnProperty('message')? e.message : e)); |
| } |
| }, |
| |
| getNumberPattern: function(win, fail, args) { |
| try { |
| var options = args[0].options || { type : 'decimal'}; |
| options.type = options.type || 'decimal'; |
| |
| options = convertToIntlNumberFormatOptions(options); |
| |
| var formatter = new Intl.NumberFormat(getCrossPlatformLocale(), options); |
| |
| if (!formatter.hasOwnProperty('resolved')) { |
| fail('Not supported'); |
| return; |
| } |
| var pattern = formatter.resolved.pattern; |
| win( { |
| pattern: pattern, |
| symbol: '', |
| fraction: 0, |
| rounding: 0, |
| positive: '', |
| negative: '', |
| decimal: '', |
| grouping: '', |
| }); |
| } catch (e) { |
| fail(new GlobalizationError(GlobalizationError.PATTERN_ERROR, |
| e.hasOwnProperty('message')? e.message : e)); |
| } |
| }, |
| |
| getPreferredLanguage: function(win, fail, args) { |
| // Falling back on locale |
| globalization.getLocaleName(win, fail); |
| }, |
| |
| getCurrencyPattern: function(win, fail, args) { |
| fail('Not supported'); |
| }, |
| |
| stringToDate: function(win, fail, args) { |
| try { |
| var options = prepareAndGetDateOptions(args[0].options); |
| moment.locale(getCrossPlatformLocale()); |
| |
| var date = moment(args[0].dateString, options).toDate(); |
| |
| win({ |
| year: date.getFullYear(), |
| month: date.getMonth(), |
| day: date.getDate(), |
| hour: date.getHours(), |
| minute: date.getMinutes(), |
| second: date.getSeconds(), |
| millisecond: date.getMilliseconds() |
| }); |
| } catch (e) { |
| fail(new GlobalizationError(GlobalizationError.PARSING_ERROR, |
| e.hasOwnProperty('message')? e.message : e)); |
| } |
| }, |
| |
| stringToNumber: function(win, fail, args) { |
| fail('Not supported'); |
| }, |
| |
| dateToString: function(win, fail, args) { |
| try { |
| var date = new Date(args[0].date); |
| var options = prepareAndGetDateOptions(args[0].options); |
| moment.locale(getCrossPlatformLocale()); |
| |
| win({ value : moment(date).format(options)}); |
| } catch (e) { |
| fail(new GlobalizationError(GlobalizationError.FORMATTING_ERROR, |
| e.hasOwnProperty('message')? e.message : e)); |
| } |
| } |
| }; |
| |
| module.exports = globalization; |
| |
| require('cordova/exec/proxy').add('Globalization', module.exports); |