From b8a42b9e4710bd57dae542a84d790a7d946ed57f Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Thu, 22 Oct 2015 11:39:55 +0200 Subject: [PATCH] [Cordova] Globalization implementation JS part added [Verification] Tests results are 46 specs, 11 failures. Change-Id: Icab3fd00fe97c2df2020c87a110dbadb9c4d1e63 Signed-off-by: Piotr Kosko --- src/cordova-api.gyp | 1 + src/globalization/cordova_globalization.gyp | 25 ++ src/globalization/cordova_globalization_api.js | 263 +++++++++++++++++++++ .../cordova_globalization_extension.cc | 39 +++ .../cordova_globalization_extension.h | 36 +++ 5 files changed, 364 insertions(+) create mode 100644 src/globalization/cordova_globalization.gyp create mode 100755 src/globalization/cordova_globalization_api.js create mode 100755 src/globalization/cordova_globalization_extension.cc create mode 100755 src/globalization/cordova_globalization_extension.h diff --git a/src/cordova-api.gyp b/src/cordova-api.gyp index 3f3140e..1f637da 100644 --- a/src/cordova-api.gyp +++ b/src/cordova-api.gyp @@ -12,6 +12,7 @@ 'device/cordova_device.gyp:*', 'dialog/cordova_dialog.gyp:*', 'file/cordova_file.gyp:*', + 'globalization/cordova_globalization.gyp:*', 'networkinformation/cordova_networkinformation.gyp:*', 'filetransfer/cordova_filetransfer.gyp:*', ], diff --git a/src/globalization/cordova_globalization.gyp b/src/globalization/cordova_globalization.gyp new file mode 100644 index 0000000..9c44927 --- /dev/null +++ b/src/globalization/cordova_globalization.gyp @@ -0,0 +1,25 @@ +{ + 'includes':[ + '/usr/include/webapi-plugins/src/common/common.gypi', + ], + 'targets': [ + { + 'target_name': 'tizen_cordova_globalization', + 'type': 'loadable_module', + 'sources': [ + 'cordova_globalization_api.js', + 'cordova_globalization_extension.cc', + 'cordova_globalization_extension.h', + ], + 'include_dirs': [ + '../', + '<(SHARED_INTERMEDIATE_DIR)', + ], + 'variables': { + 'packages': [ + 'webapi-plugins', + ], + }, + }, + ], +} \ No newline at end of file diff --git a/src/globalization/cordova_globalization_api.js b/src/globalization/cordova_globalization_api.js new file mode 100755 index 0000000..e857ba9 --- /dev/null +++ b/src/globalization/cordova_globalization_api.js @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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 _navigator = navigator || {}; +var _global = window || global || {}; + +///// GlobalizationError ////// +var GlobalizationError = function(code, message) { + this.code = code; + this.name = 'GlobalizationError'; + this.message = message || 'Default Message'; + this.stack = (new Error()).stack; +}; + +GlobalizationError.prototype = Object.create(Error.prototype); +GlobalizationError.prototype.constructor = GlobalizationError; + +GlobalizationError.UNKNOWN_ERROR = 0; +GlobalizationError.FORMATTING_ERROR = 1; +GlobalizationError.PARSING_ERROR = 2; +GlobalizationError.PATTERN_ERROR = 3; + +_global.GlobalizationError = GlobalizationError; + + +///// Globalization ////// +var selectorDateStr = 'date'; +var selectorTimeStr = 'time'; +var selectorDateAndTimeStr = selectorDateStr + ' and ' + selectorTimeStr; + +//TODO how to support all those lenghts?? +var formatShortStr = 'short'; +var formatMediumStr = 'medium'; +var formatLongStr = 'long'; +var formatFullStr = 'full'; + +var oneHourSeconds = 60*60; + +var Globalization = {}; + +Globalization.getPreferredLanguage = function(successCb, errorCb) { + // TODO add validation of parameters + // TODO Indicates the current language setting in the (LANGUAGE)_(REGION) syntax. + // The language setting is in the ISO 630-2 format and the region setting is in the ISO 3166-1 format. + tizen.systeminfo.getPropertyValue ('LOCALE', + function (locale) { + // replacing '_' with '-' to satisfy cordova language and region separator + var result = locale.language.replace('_', '-'); + successCb( {'value': result} ); + }, + function(error) { + console.log('Cordova, getLocaleName, An error occurred ' + error.message); + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , + 'cannot retrieve language name')); + } + ); +} + +Globalization.getLocaleName = function(successCb, errorCb) { + Globalization.getPreferredLanguage(successCb, errorCb); +} + +//TODO dateToString would support only full length (one format is supprted), +// but selector for getting only needed values is fully supported +Globalization.dateToString = function(date, successCb, errorCb, options) { + // TODO add validation of parameters + var result = null; + var formatLength = formatFullStr; + var selector = selectorDateAndTimeStr; + console.log("options " + JSON.stringify(options)); + if (options) { + formatLength = options.formatLength || formatFullStr; + selector = options.selector || selectorDateAndTimeStr; + } + console.log("len: " + formatLength + " selector: " + selector); + + var tzdate = new tizen.TZDate(date); + if (tzdate) { + // TODO only one format length is supprted + // "Wednesday, January 7, 2015, 12:33:15 PM" + if (selectorDateStr === selector) { + result = tzdate.toLocaleDateString(); + } else if (selectorTimeStr === selector) { + result = tzdate.toLocaleTimeString(); + } else { + result = tzdate.toLocaleString(); + } + } + + if (result) { + setTimeout( function() { + successCb ({'value': result}); + }, 0); + } else { + setTimeout( function() { + errorCb(new GlobalizationError( + GlobalizationError.FORMATTING_ERROR , 'cannot format date string')); + }, 0); + } +} + +//TODO implementation would try to convert string to Date using javascript Date object +// constructor, options are basically ignored +Globalization.stringToDate = function(dateString, successCb, errorCb, options) { + // TODO add validation of parameters + var d = new Date(dateString); + if (!d.getTime()) { + setTimeout( function() { + errorCb(new GlobalizationError( + GlobalizationError.PARSING_ERROR , 'cannot parse date from string')); + }, 0); + } else { + var result = { + year : d.getYear() + 1900, + month : d.getMonth(), + day : d.getDate(), + hour : d.getHours(), + minute : d.getMinutes(), + second : d.getSeconds(), + millisecond : d.getMilliseconds() + }; + setTimeout( function() { + successCb (result); + }, 0); + } +} + +// TODO getDatePattern would support only short and full length, +// but selector for getting only needed values is fully supported +Globalization.getDatePattern = function(successCb, errorCb, options) { + // TODO add validation of parameters + var selector = selectorDateAndTimeStr; + var isShortFormat = false; + if (options) { + selector = options.selector || selectorDateAndTimeStr; + isShortFormat = (options.formatLength === formatShortStr); + } + var pattern = null; + if (selectorTimeStr === selector) { + pattern = tizen.time.getTimeFormat(); + } else if (selectorDateStr === selector) { + pattern = tizen.time.getDateFormat(isShortFormat); + } else { + // TODO in tizen there is no unified date and time format getter + // (for now implementation separates date and time formats with colon ',' + pattern = tizen.time.getDateFormat(isShortFormat) + ", " + tizen.time.getTimeFormat(); + } + + var currentDateTime = tizen.time.getCurrentDateTime(); + if (pattern && currentDateTime) { + // TODO currently value as "GMT+09:00" will be returned, + // to get value "Asia/Seoul" use .getTimezone() instead + var timezoneAbbreviation = currentDateTime.getTimezoneAbbreviation(); + + // TODO method secondsFromUTC returns inverted offset: if time zone is GMT+8, it will return -32,400. + // TODO currently utcOffset will include DST additional hour if it is present, value will be + // timezoneOffset = timezoneOffsetWithoutDST + DSTAdditionalOffset + // if other behaviour is correct, just need to substract dstOffset from utcOffset + var utcOffset = currentDateTime.secondsFromUTC() * (-1); + var dstOffset = currentDateTime.isDST() ? oneHourSeconds : 0; + + var result = { + "pattern": pattern, + "timezone": timezoneAbbreviation, + "utc_offset": utcOffset, + "dst_offset": dstOffset + }; + setTimeout( function() { + successCb (result); + }, 0); + } else { + errorCb(new GlobalizationError(GlobalizationError.PATTERN_ERROR , "cannot get pattern")); + } +} + +// TODO implement this as native method +Globalization.getDateNames = function(successCb, errorCb, options) { + // TODO add validation of parameters + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported")) + }, 0); +} + +Globalization.isDayLightSavingsTime = function(date, successCb, errorCb) { + // TODO add validation of parameters + var tzdate = new tizen.TZDate(date); //creates tzdate with local default timezone + if (tzdate) { + var result = tzdate.isDST(); + setTimeout( function() { + successCb ( {'dst' : result} ); + }, 0); + } else { + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot get information")) + }, 0); + } +} + +//TODO implement this as native method +Globalization.getFirstDayOfWeek = function(successCb, errorCb) { + // TODO add validation of parameters + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported")) + }, 0); +} + +//TODO how to implement this?? +Globalization.numberToString = function(number, successCb, errorCb, options) { + // TODO add validation of parameters + var result = number.toLocaleString(); + setTimeout( function() { + successCb ( {'value' : result} ); + }, 0); +} + +//TODO how should look this implementation about options?? +Globalization.stringToNumber = function(numberStr, successCb, errorCb, options) { + // TODO add validation of parameters + var result = Number(numberStr); + if ('NaN' != result.toString()) { + setTimeout( function() { + successCb ( {'value' : result} ); + }, 0); + } else { + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.PARSING_ERROR , + "cannot convert string to number")) + }, 0); + } +} + +//TODO how to implement this?? +Globalization.getNumberPattern = function(successCb, errorCb, options) { + // TODO add validation of parameters + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported")) + }, 0); +} + +//TODO how to implement this?? +Globalization.getCurrencyPattern = function(currencyCode, successCb, errorCb) { + // TODO add validation of parameters + setTimeout( function() { + errorCb(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported")) + }, 0); +} + +_navigator.globalization = Globalization; + +console.log('Loaded cordova.globalization API'); diff --git a/src/globalization/cordova_globalization_extension.cc b/src/globalization/cordova_globalization_extension.cc new file mode 100755 index 0000000..7bb780d --- /dev/null +++ b/src/globalization/cordova_globalization_extension.cc @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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. + */ + +#include "globalization/cordova_globalization_extension.h" + +// This will be generated from cordova_globalization_api.js +extern const char kSource_cordova_globalization_api[]; + +common::Extension* CreateExtension() { + return new extension::cordova::globalization::CordovaGlobalizationExtension(); +} + +namespace extension { +namespace cordova { +namespace globalization { + +CordovaGlobalizationExtension::CordovaGlobalizationExtension() { + SetExtensionName("tizen.cordova.globalization"); + SetJavaScriptAPI(kSource_cordova_globalization_api); +} + +CordovaGlobalizationExtension::~CordovaGlobalizationExtension() {} + +} // globalization +} // cordova +} // extension diff --git a/src/globalization/cordova_globalization_extension.h b/src/globalization/cordova_globalization_extension.h new file mode 100755 index 0000000..91a37ec --- /dev/null +++ b/src/globalization/cordova_globalization_extension.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed 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. + */ + +#ifndef GLOBALIZATION_CORDOVA_GLOBALIZATION_EXTENSION_H_ +#define GLOBALIZATION_CORDOVA_GLOBALIZATION_EXTENSION_H_ + +#include "common/extension.h" + +namespace extension { +namespace cordova { +namespace globalization { + +class CordovaGlobalizationExtension : public common::Extension { + public: + CordovaGlobalizationExtension(); + virtual ~CordovaGlobalizationExtension(); +}; + +} // globalization +} // cordova +} // extension + +#endif // GLOBALIZATION_CORDOVA_GLOBALIZATION_EXTENSION_H_ -- 2.7.4