summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorYongkook Kim <yk22.kim@samsung.com>2015-12-09 15:52:14 +0900
committerYongkook Kim <yk22.kim@samsung.com>2015-12-09 15:52:53 +0900
commite1d475bac2aea0dbe037607cf7445eb145d85019 (patch)
treed13e3fc4ce54403eab52e8fb518cdce47fc4bbd1 /js
parent721ac8120af82d883e00ab499158d8b95a35bcf4 (diff)
downloadaltimeter-master.tar.gz
altimeter-master.tar.bz2
altimeter-master.zip
[Altimeter] Project InitHEADmaster
Signed-off-by: Yongkook Kim <yk22.kim@samsung.com> Change-Id: I2873b2234e00d678d387dcec1b3127d90e1aa8f4
Diffstat (limited to 'js')
-rw-r--r--js/app.js47
-rw-r--r--js/core/.gitignore2
-rw-r--r--js/core/.jscsrc44
-rw-r--r--js/core/.jshintignore2
-rw-r--r--js/core/.jshintrc25
-rw-r--r--js/core/README.md53
-rw-r--r--js/core/core.js672
-rw-r--r--js/core/core/application.js221
-rw-r--r--js/core/core/event.js323
-rw-r--r--js/core/core/storage/idb.js320
-rw-r--r--js/core/core/systeminfo.js120
-rw-r--r--js/core/core/tizen.js44
-rw-r--r--js/core/core/window.js43
-rw-r--r--js/helpers/dom.js53
-rw-r--r--js/models/pressure.js223
-rw-r--r--js/models/settings.js153
-rw-r--r--js/tau-config.js24
-rw-r--r--js/views/init.js102
-rw-r--r--js/views/main.js355
19 files changed, 2826 insertions, 0 deletions
diff --git a/js/app.js b/js/app.js
new file mode 100644
index 0000000..c9b0e4c
--- /dev/null
+++ b/js/app.js
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global require, define, console, $*/
+
+/**
+ * App module.
+ * @requires {@link Altimeter/views/init}
+ * @namespace Altimeter/app
+ * @memberof Altimeter
+ */
+
+define({
+ name: 'app',
+ requires: [
+ 'views/init'
+ ],
+ def: function appInit() {
+ 'use strict';
+
+ /**
+ * Initializes the app.
+ * @memberof Altimeter/app
+ */
+ function init() {
+ console.log('APP: init()');
+ }
+
+ return {
+ init: init
+ };
+ }
+});
+
diff --git a/js/core/.gitignore b/js/core/.gitignore
new file mode 100644
index 0000000..af95e6b
--- /dev/null
+++ b/js/core/.gitignore
@@ -0,0 +1,2 @@
+/tests/_build
+/tests/node_modules \ No newline at end of file
diff --git a/js/core/.jscsrc b/js/core/.jscsrc
new file mode 100644
index 0000000..c51de4b
--- /dev/null
+++ b/js/core/.jscsrc
@@ -0,0 +1,44 @@
+{
+ "excludeFiles": [
+ "*/node_modules/*",
+ "*/libs/*",
+ "*/lib/*"
+ ],
+
+ "validateJSDoc": {
+ "checkParamNames": true,
+ "checkRedundantParams": true,
+ "requireParamTypes": true
+ },
+
+ "maximumLineLength": 80,
+
+
+ "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
+ "requireMultipleVarDecl": true,
+ "requireBlocksOnNewline": true,
+ "requireLineFeedAtFileEnd": true,
+ "requireDotNotation": true,
+ "requireBlocksOnNewline": 1,
+ "requireSpaceAfterLineComment": true,
+ "requireSpaceBeforeBlockStatements": true,
+ "requireSpacesInConditionalExpression": true,
+ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
+ "requireSpacesInFunctionExpression": {
+ "beforeOpeningCurlyBrace": true
+ },
+ "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
+ "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
+
+ "disallowAnonymousFunctions": true,
+ "disallowKeywords": ["with"],
+ "disallowEmptyBlocks": true,
+
+ "disallowNewlineBeforeBlockStatements": true,
+ "disallowSpaceAfterObjectKeys": true,
+ "disallowSpacesInsideArrayBrackets": true,
+ "disallowSpacesInsideParentheses": true,
+ "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+ "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
+ "disallowSpaceBeforeBinaryOperators": [","]
+}
diff --git a/js/core/.jshintignore b/js/core/.jshintignore
new file mode 100644
index 0000000..039e6b2
--- /dev/null
+++ b/js/core/.jshintignore
@@ -0,0 +1,2 @@
+*/node_modules/*
+*/libs/*
diff --git a/js/core/.jshintrc b/js/core/.jshintrc
new file mode 100644
index 0000000..115de8b
--- /dev/null
+++ b/js/core/.jshintrc
@@ -0,0 +1,25 @@
+{
+ "browser": false,
+ "curly": true,
+ "devel": false,
+ "globals": {},
+ "immed": true,
+ "indent": 4,
+ "latedef": true,
+ "maxcomplexity": 7,
+ "maxdepth": 3,
+ "maxlen": 80,
+ "maxparams": 5,
+ "maxstatements": 30,
+ "noempty": true,
+ "nomen": true,
+ "nonew": true,
+ "onevar": true,
+ "plusplus": true,
+ "quotmark": "single",
+ "strict": true,
+ "trailing": true,
+ "undef": true,
+ "unused": "strict",
+ "white": true
+}
diff --git a/js/core/README.md b/js/core/README.md
new file mode 100644
index 0000000..faef037
--- /dev/null
+++ b/js/core/README.md
@@ -0,0 +1,53 @@
+
+# Overview #
+
+Reference Web Applications Core uses a simple MVP (Model View Presenter) architecture.
+
+There are a core part which determines the architecture and an app part which determines the application behavior.
+
+
+# Overview of core.js #
+
+`core.js` implements simple AMD (Asynchronous Module Definition) and specifies module defining.
+
+Modules definition organizes code into simple units (modules).
+Module can refer to other modules – dependency references.
+
+
+## Loading ##
+
+`core.js` loads files with a different approach than &lt;script&gt; tags in HTML file.
+
+`core.js` loads each file as a script tag, using _document.createElement_ and _head.appendChild_ and then waits for all dependencies to load, figures the right order to call definitions of module.
+
+## Usage ##
+
+Adding `core.js` to index.html:
+```
+{@lang xml}<script src="./js/libs/core/core.js" data-main="./js/app.js"></script>
+```
+
+
+Where `app.js` is the main application module.
+
+```
+{@lang javascript}define({
+ name: 'app',
+ def: function def() {}
+});
+```
+
+### Defining a module ###
+A module is a file with simple code unit, different from a traditional script file. Module avoids impact on global namespace like _window_.
+Any valid return from a module is allowed, module can return objects, functions or nothing. If module definition return object with
+_init_ method then module will be automatically initialized.
+There should only be __one__ module definition per file.
+
+[See examples how to define a module](global.html#define)
+
+
+# Contributors #
+
+* [Sergiusz Struminski](mailto:s.struminski@samsung.com)
+* [Pawel Sierszen](mailto:p.sierszen@samsung.com)
+* [Kamil Stepczuk](mailto:k.stepczuk@samsung.com)
diff --git a/js/core/core.js b/js/core/core.js
new file mode 100644
index 0000000..9a25ede
--- /dev/null
+++ b/js/core/core.js
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+
+/**
+ * @namespace core
+ * @author Sergiusz Struminski <s.struminski@samsung.com>
+ * @author Pawel Sierszen <p.sierszen@samsung.com>
+ */
+(function core(global) {
+ 'use strict';
+
+ /**
+ * Public object.
+ * @type {object}
+ */
+ var publicAPI = {},
+
+ /**
+ * Document element.
+ * @type {object}
+ */
+ document = global.document,
+
+ /**
+ * Head element.
+ * @type {HTMLHeadElement}
+ */
+ head = document.getElementsByTagName('head')[0],
+
+ /**
+ * Internal object cache
+ * @type {object}
+ */
+ modules = {},
+
+ /**
+ * Internal config
+ * @type {object}
+ */
+ cfg = {
+
+ /**
+ * Default path to modules.
+ * @type {string}
+ */
+ defaultPath: './js/',
+
+ /**
+ * Path to core modules.
+ * @type {string}
+ */
+ basePath: null,
+
+ /**
+ * Path to application modules.
+ * @type {string}
+ */
+ modulePath: null
+ };
+
+ /**
+ * Generic Module class.
+ * @private
+ */
+ function Module(name) {
+ // Module name.
+ this.name = name;
+ return;
+ }
+
+ /**
+ * Returns correct path for modules.
+ * @private
+ * @param {string} data Current path.
+ * @return {string} New path.
+ */
+ function getPath(data) {
+ var index = data.lastIndexOf('/'),
+ path = data.substr(0, index + 1);
+
+ return path || './';
+ }
+
+ /**
+ * Have all requires been sorted already?
+ * @private
+ * @param {string[]} requires Requires.
+ * @param {string[]} sorted Sorted requires.
+ * @return {boolean} result.
+ */
+ function areSorted(requires, sorted) {
+ var i = 0,
+ depsLen = requires.length,
+ result = true;
+ for (i = 0; i < depsLen; i += 1) {
+ // Has mod been sorted already?
+ result = result && (sorted.indexOf(requires[i]) !== -1);
+ }
+ return result;
+ }
+
+ /**
+ * Sort modules by requires (dependents last),
+ * returning sorted list of module names.
+ * @private
+ * @param {object} modules Modules.
+ */
+ function sort(modules) {
+
+ var name = null,
+ // Modules to be sorted.
+ pending = [],
+ // Modules already sorted.
+ sorted = [],
+ // Remember length of pending list for each module.
+ visited = {},
+ currModule = null;
+
+ for (name in modules) {
+ if (modules.hasOwnProperty(name)) {
+ if (modules[name].instance) {
+ // Already linked.
+ sorted.push(name);
+ } else {
+ // Sort for linking.
+ pending.push(name);
+ }
+ }
+ }
+
+ // Repeat while there are modules pending.
+ while (pending.length > 0) {
+
+ // Consider the next pending module
+ currModule = pending.shift();
+
+ // If we've been here and have not made any progress, we are looping
+ // (no support for cyclic module requires).
+ if (visited[currModule] && visited[currModule] <= pending.length) {
+ throw new Error('No support for circular module dependency.');
+ }
+ visited[currModule] = pending.length;
+
+ // Consider the current module's import requires.
+ if (areSorted(modules[currModule].requires, sorted)) {
+ // Requires done, module done.
+ sorted.push(currModule);
+ } else {
+ // Some requires still pending.
+ pending.push(currModule);
+ }
+ }
+
+ return sorted;
+ }
+
+ /**
+ * Merge the contents of two objects into the first object.
+ * @private
+ * @param {Object} target Target object (child).
+ * @param {Object} source Source object (parent).
+ * @return {Object} Target object.
+ */
+ function extend(target, source) {
+ var prop = null;
+ for (prop in source) {
+ if (source.hasOwnProperty(prop)) {
+ Object.defineProperty(
+ target,
+ prop,
+ {
+ value: source[prop]
+ }
+ );
+ }
+ }
+ return target;
+ }
+
+ /**
+ * Create the object using Def as a constructor.
+ * In this case the object inherits the prototype from Def.
+ * @private
+ * @param {function} Def Constructing function.
+ * @param {object[]} args Parameters for the constructing function.
+ * @return {object} Constructed object.
+ */
+ function construct(Def, args) {
+ var argsLen = args.length;
+
+ // Switch/case is used for performance reasons.
+ switch (argsLen) {
+ case 0:
+ return new Def();
+ case 1:
+ return new Def(args[0]);
+ case 2:
+ return new Def(args[0], args[1]);
+ case 3:
+ return new Def(args[0], args[1], args[2]);
+ case 4:
+ return new Def(args[0], args[1], args[2], args[3]);
+ case 5:
+ return new Def(args[0], args[1], args[2], args[3], args[4]);
+ default:
+ // Too many parameters, use a short form instead
+ return Def.apply(Object.create(Def.prototype), args);
+ }
+ }
+
+ /**
+ * Creates an object using the passed constructor and parameters.
+ * @private
+ * @param {function} Def Constructing function.
+ * @param {object[]} args Parameters for the constructing function.
+ * @return {object} Object of Def type.
+ */
+ function instantiate(Def, args) {
+ var obj = null, proto = null;
+
+ obj = construct(Def, args);
+
+ // Constructors don't have to return anything, but we need at least
+ // an empty object.
+ if (!obj) {
+ obj = {};
+ }
+
+ /**
+ * If the module returns a plain object, we need to fix this.
+ * Create an object with a valid prototype
+ * and extend it by copying properties from the original object.
+ * The previous prototype, if any, is ignored.
+ * Only modules created with Object function will be extended.
+ * It is for ignore global objects like "window" or "tizen".
+ */
+ proto = Object.getPrototypeOf(obj);
+ if (proto !== null && !Object.prototype.isPrototypeOf(proto)) {
+ obj = extend(
+ Object.create(Def.prototype),
+ obj
+ );
+ }
+
+ return obj;
+ }
+
+ /**
+ * Assigns nested attributes.
+ * @private
+ * @param {object} obj Object.
+ * @param {string[]} pathElements Elements array.
+ * @param {object} value Object.
+ */
+ function assignNested(obj, pathElements, value) {
+ var i, key = pathElements.pop();
+ // Check the path.
+ for (i = 0; i < pathElements.length; i += 1) {
+ // If empty create an empty object here.
+ obj = obj[pathElements[i]] = obj[pathElements[i]] || {};
+ }
+ obj[key] = value;
+ }
+
+ /**
+ * Returns required module instance.
+ * Parameters are passed to the constructor.
+ * @private
+ * @param {string} moduleName Module name.
+ * @param {object} reqModule Required module object.
+ * @return {object} Module instance.
+ */
+ function requireInstance(moduleName, reqModule) {
+ var instance = reqModule.instance;
+ if (reqModule.name === 'core/event') {
+ // Make new object inherited from core/event module
+ // for adding additional properties (per caller module).
+ instance = Object.create(reqModule.instance);
+ // Module name used to fire events.
+ instance.evName = moduleName.replace(/\//g, '.');
+ }
+ return instance;
+ }
+
+ /**
+ * Creates parameters (from required modules).
+ * Parameteres are passed to the constructor.
+ * @private
+ * @param {object} module Module object.
+ * @return {object[]} params.
+ */
+ function createParams(module) {
+ var def = module.def,
+ requires = module.requires,
+ params = [],
+ req = {},
+ instance = null,
+ i = 0;
+
+ if (def.length === 1 && requires.length > 1) {
+ // Collect requires as object.
+ for (i = requires.length - 1; i >= 0; i -= 1) {
+ instance = requireInstance(module.name, modules[requires[i]]);
+
+ // Full name keys for array-like indexing.
+ req[requires[i]] = instance;
+
+ // Nested objects for cleaner syntax.
+ assignNested(req, requires[i].split('/'), instance);
+ }
+ params.push(req);
+
+ } else if (def.length === requires.length) {
+ // Collect requires as modules.
+ for (i = requires.length - 1; i >= 0; i -= 1) {
+ params[i] = requireInstance(module.name, modules[requires[i]]);
+ }
+
+ } else if (def.length !== 0) {
+ // Invalid number of params.
+ // Definition module params length is greater than zero
+ // and different than requires params length.
+ throw new Error(
+ 'Invalid number of params in ' + def.name +
+ '- expected ' + requires.length + ' but is ' + def.length
+ );
+ }
+
+ return params;
+ }
+
+
+ /**
+ * Links and runs modules in the order in which they were loaded.
+ * @private
+ */
+ function link() {
+ var i = 0,
+ sorted = [],
+ sortedLen = 0,
+ name = '',
+ module = null;
+
+ // Sort modules in requires order.
+ sorted = sort(modules);
+ sortedLen = sorted.length;
+
+ // Create instances of modules in requires order.
+ for (i = 0; i < sortedLen; i += 1) {
+ name = sorted[i];
+ module = modules[name];
+
+ if (module.instance === undefined) {
+ module.initialized = false;
+
+ // Each module should inherit from a generic Module object.
+ module.def.prototype = new Module(name);
+
+ // Execute module code, pass requires, record exports.
+ modules[name].instance = instantiate(
+ module.def,
+ createParams(module)
+ );
+ }
+ }
+
+ // Initialize modules in requires order.
+ // It must be in different loop (see above)
+ // because we need every instance ready.
+ for (i = 0; i < sortedLen; i += 1) {
+ name = sorted[i];
+ module = modules[name];
+
+ if (module.instance !== undefined && !module.initialized) {
+ if (typeof modules[name].instance.init === 'function') {
+ modules[name].instance.init();
+ module.initialized = true;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Returns instance of module.
+ * @global
+ *
+ * @example
+ * // Define `foo` module which require `bar` module:
+ * define({
+ * name: 'foo',
+ * requires: ['bar'],
+ * def: function def(bar) {}
+ * });
+ *
+ * // Define `bar` module which needs some `foo` functionalities:
+ * // You can't define a circular dependency
+ * // (foo needs bar and bar needs foo)
+ * define({
+ * name: 'bar',
+ * requires: ['foo'],
+ * def: function def(foo) {}
+ * });
+ *
+ * // In that case use:
+ * define({
+ * name: 'bar',
+ * def: function def() {
+ * var foo;
+ * function init() {
+ * foo = require('foo');
+ * }
+ * return {
+ * init: init
+ * }
+ * }
+ * });
+ *
+ * @throws {Error} Module must be defined.
+ * @throws {Error} Module must be an instance.
+ *
+ * @param {string} moduleName Module name.
+ * @return {object} Module instance.
+ */
+ function require(moduleName) {
+ var module = modules[moduleName];
+
+ if (module === undefined) {
+ throw new Error('Module ' + moduleName + ' must be defined.');
+ }
+
+ if (module.instance === undefined) {
+ throw new Error('The instance of ' + moduleName +
+ ' doesn\'t exist yet.');
+ }
+
+ return module.instance;
+ }
+
+ /**
+ * Loads a script.
+ * @private
+ * @param {string} src Script src.
+ */
+ function loadScript(src) {
+ var script = null;
+
+ script = document.createElement('script');
+ script.setAttribute('src', src);
+ script.addEventListener('error', function error() {
+ throw new Error(
+ 'Failed to load "' + src + '" script'
+ );
+ });
+ head.appendChild(script);
+ }
+
+ /**
+ * Loads a module.
+ * @private
+ * @param {string} moduleName Module name.
+ */
+ function load(moduleName) {
+ var modulePath = '';
+
+ if (modules[moduleName] !== undefined) {
+ return false;
+ }
+
+ modules[moduleName] = {};
+
+ if (moduleName.indexOf('core') === 0) {
+ modulePath = cfg.basePath || cfg.defaultPath;
+ } else {
+ modulePath = cfg.modulePath || cfg.defaultPath;
+ }
+
+ loadScript(modulePath + moduleName + '.js');
+
+ return true;
+ }
+
+ /**
+ * Check whether this was the last module to be loaded
+ * in a given dependency group.
+ * If yes, start linking and running modules.
+ * @private
+ */
+ function loaded() {
+ var m = null,
+ pending = [];
+
+ for (m in modules) {
+ if (modules.hasOwnProperty(m) && modules[m].name === undefined) {
+ pending.push(m);
+ }
+ }
+
+ if (pending.length === 0) {
+ link();
+ }
+ }
+
+ /**
+ * The function that handles definitions of modules.
+ * @global
+ *
+ * @example
+ * // Define `foo` module:
+ * define({
+ * name: 'foo',
+ * def: function def() {}
+ * });
+ *
+ * @example
+ * // Define `bar` module:
+ * define({
+ * name: 'bar',
+ * def: function def() {}
+ * });
+ *
+ * @example
+ * // Define `foo` module which require `bar` module:
+ * define({
+ * name: 'foo',
+ * requires: ['bar'],
+ * def: function def(bar) {}
+ * });
+ *
+ * @example
+ * // Define `foo` module which require `bar1` and `bar2` module:
+ * define({
+ * name: 'foo',
+ * requires: ['bar1', 'bar2'],
+ * def: function def(bar1, bar2) {}
+ * });
+ *
+ * @example
+ * // Define `foo` module which require `bar1` and `bar2` module:
+ * define({
+ * name: 'foo',
+ * requires: ['bar1', 'bar2'],
+ * def: function def(require) {
+ * var bar1 = require.bar1,
+ * bar2 = require.bar2;
+ * }
+ * });
+ *
+ * @example
+ * // Define `foo` module which require `path/bar1` and `path/bar2` module:
+ * define({
+ * name: 'foo',
+ * requires: ['path/bar1', 'path/bar2'],
+ * def: function def(require) {
+ * // recommended
+ * var bar1 = require.path.bar1,
+ * bar2 = require.path.bar2;
+ * // or
+ * var bar1 = require['path/bar1'],
+ * bar2 = require['path/bar2'];
+ * }
+ * });
+ *
+ * @example
+ * // Define `foo` module which is automatically initialized
+ * // during definition:
+ * define({
+ * name: 'foo',
+ * def: function def() {
+ * // module definition
+ * function init() {
+ * // init action
+ * }
+ *
+ * // return the module value with init function
+ * return {
+ * init: init
+ * };
+ * }
+ * });
+ *
+ * @throws {Error} Module must have name and definititon.
+ * @throws {Error} Module is already defined.
+ *
+ * @param {object} module Module object.
+ * @param {string} module.name Module name.
+ * @param {string[]} [module.requires] Module requires.
+ * @param {function} module.def Module definititon.
+ */
+ function define(module) {
+ var i = 0,
+ j = 0;
+
+ module = module || {};
+
+ if (module.name === undefined || module.def === undefined) {
+ throw new Error(
+ 'Module must have name and definition'
+ );
+ }
+
+ if (modules[module.name] !== undefined &&
+ modules[module.name].name !== undefined) {
+ throw new Error(
+ 'Module "' + module.name + '" is already defined'
+ );
+ }
+
+ module.requires = module.requires || [];
+ modules[module.name] = module;
+
+ // Load required modules.
+ for (i = 0, j = module.requires.length; i < j; i += 1) {
+ load(module.requires[i]);
+ }
+
+ // Check for loaded modules.
+ loaded();
+
+ return true;
+ }
+
+ /**
+ * Looks for a data-main attribute in script elements.
+ * Data-main attribute tells core to load main application script.
+ * @private
+ * @return {boolean}
+ */
+ function main() {
+ var i = 0,
+ len = 0,
+ scripts = document.getElementsByTagName('script'),
+ script = null,
+ dataMain = null;
+
+ for (i = 0, len = scripts.length; i < len; i += 1) {
+ script = scripts[i];
+ dataMain = script.getAttribute('data-main');
+ if (dataMain) {
+ cfg.modulePath = getPath(dataMain);
+ cfg.basePath = getPath(script.getAttribute('src'));
+ loadScript(dataMain);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ publicAPI = {
+ require: require,
+ define: define
+ };
+
+ extend(global, publicAPI);
+
+ main();
+
+}(this));
diff --git a/js/core/core/application.js b/js/core/core/application.js
new file mode 100644
index 0000000..a912b7f
--- /dev/null
+++ b/js/core/core/application.js
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console*/
+/*jslint regexp: true*/
+
+/**
+ * Application module
+ * @requires {@link core/event}
+ * @requires {@link core/tizen}
+ * @namespace core/application
+ * @memberof core
+ */
+
+define({
+ name: 'core/application',
+ requires: [
+ 'core/event',
+ 'core/window',
+ 'core/tizen'
+ ],
+ def: function coreApplication(e, window, tizen) {
+ 'use strict';
+
+ var app = null,
+ navigator = window.navigator,
+ APP_CONTROL_URL = 'http://tizen.org/appcontrol/';
+
+ /**
+ * Gets current application.
+ * @memberof core/application
+ */
+ function getCurrentApplication() {
+ return app.getCurrentApplication();
+ }
+
+ /**
+ * Gets application control URI.
+ * @memberof core/application
+ * @param {object} operation Operation name.
+ */
+ function getAppControlUri(operation) {
+ return APP_CONTROL_URL + operation;
+ }
+
+ /**
+ * Gets current application id.
+ * @memberof core/application
+ */
+ function getId() {
+ return getCurrentApplication().appInfo.id;
+ }
+
+ /**
+ * Launches application control.
+ * @memberof core/application
+ * @param {object} controlData Control data params.
+ * @param {string} controlData.operation Operation uri.
+ * @param {string} [controlData.mime] MIME type.
+ */
+ function launchAppControl(controlData) {
+ var control = new tizen.ApplicationControl(
+ getAppControlUri(controlData.operation),
+ null,
+ controlData.mime || null
+ ),
+ replyCallback = {
+ onsuccess: function onsuccess(data) {
+ e.fire(
+ 'replySuccess',
+ {
+ operation: controlData.operation,
+ data: data
+ }
+ );
+ },
+ onfailure: function onfailure() {
+ e.fire(
+ 'replyFailure',
+ {
+ operation: controlData.operation
+ }
+ );
+ }
+ };
+
+ try {
+ app.launchAppControl(
+ control,
+ null,
+ function successCallback() {
+ e.fire(
+ 'launchSuccess',
+ {
+ operation: controlData.operation
+ }
+ );
+ },
+ function errorCallback(ev) {
+ e.fire(
+ 'launchError',
+ {
+ operation: controlData.operation,
+ data: ev
+ }
+ );
+ },
+ replyCallback
+ );
+ } catch (e) {
+ console.error(e.message);
+ }
+ }
+
+ /**
+ * Returns requeste application control data.
+ * @memberof core/application
+ * @param {string} operation Action to be performed.
+ * @return {object}
+ */
+ function getRequestedAppControlData(operation) {
+ var rAppControl = getCurrentApplication().getRequestedAppControl(),
+ appControl = null;
+
+ if (rAppControl) {
+ appControl = rAppControl.appControl;
+
+ if (appControl.operation === operation) {
+ return appControl;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates ApplicationControl object.
+ * @memberof core/application
+ * @param {string} operation Action to be performed.
+ */
+ function createApplicationControl(operation) {
+ return new tizen.ApplicationControl(getAppControlUri(operation));
+ }
+
+ /**
+ * Checks if application is running in emulator.
+ * @return {bool} Is emulated.
+ */
+ function isEmulated() {
+ return navigator.platform.indexOf('emulated') !== -1;
+ }
+
+ /**
+ * Application exit.
+ * @memberof core/application
+ */
+ function exit() {
+ getCurrentApplication().exit();
+ }
+
+ /**
+ * Application hide.
+ * @memberof core/application
+ */
+ function hide() {
+ getCurrentApplication().hide();
+ }
+
+ /**
+ * No operation.
+ */
+ function noop() {
+ return;
+ }
+
+ if (typeof tizen === 'object' &&
+ typeof tizen.application === 'object') {
+ app = tizen.application;
+ } else {
+ console.warn(
+ 'tizen.application not available, using a mock instead'
+ );
+ app = {
+ launchAppControl: noop,
+ getCurrentApplication: function getApp() {
+ return {
+ getRequestedAppControl: noop,
+ exit: noop,
+ hide: noop
+ };
+ }
+ };
+ }
+
+ return {
+ getId: getId,
+ getCurrentApplication: getCurrentApplication,
+ getAppControlUri: getAppControlUri,
+ getRequestedAppControlData: getRequestedAppControlData,
+ launchAppControl: launchAppControl,
+ createApplicationControl: createApplicationControl,
+ isEmulated: isEmulated,
+ hide: hide,
+ exit: exit
+ };
+ }
+
+});
diff --git a/js/core/core/event.js b/js/core/core/event.js
new file mode 100644
index 0000000..bcf8162
--- /dev/null
+++ b/js/core/core/event.js
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*jslint forin: true*/
+/*global define*/
+
+/**
+ * Event module.
+ * @requires {@link core/window}
+ * @namespace core/event
+ * @memberof core
+ */
+
+define({
+ name: 'core/event',
+ requires: [
+ 'core/window'
+ ],
+ def: function event(window) {
+ 'use strict';
+
+ var listeners = {};
+
+ /**
+ * Gets listeners name for event.
+ * @param {string} eventName Event name.
+ * @return {array} Listeners names.
+ */
+ function getListenersNames(eventName) {
+ var key,
+ names = [],
+ handlers = listeners[eventName];
+
+ for (key in handlers) {
+ names.push(handlers[key].name);
+ }
+ return names;
+ }
+
+ /**
+ * Gets listeners for event.
+ * @memberof core/event
+ * @param {string} [eventName] Event name.
+ * @return {object} Listeners names.
+ */
+ function getListeners(eventName) {
+ var evName,
+ names = {};
+
+ if (eventName) {
+ names[eventName] = getListenersNames(eventName);
+ } else {
+ for (evName in listeners) {
+ names[evName] = getListenersNames(evName);
+ }
+ }
+ return names;
+ }
+
+ /**
+ * Dispatches an event
+ * @param {string} eventName Event name.
+ * @param {*} data Detailed data.
+ * @return {boolean} Cancelled.
+ */
+ function dispatch(eventName, data) {
+ var customEvent = new window.CustomEvent(eventName, {
+ detail: data,
+ cancelable: true
+ });
+ return window.dispatchEvent(customEvent);
+ }
+
+ /**
+ * Dispatches an event of given name and detailed data.
+ *
+ * Dispatched event name is prefixed with name of
+ * module which dispatched event.
+ *
+ * For example if event with `test` name will be dispatched from
+ * `foo` module, listener should be added to `foo.test`.
+ *
+ * The return value is false if at least one of the event handlers
+ * which handled this event called event.preventDefault().
+ * Otherwise it returns true.
+ *
+ * @memberof core/event
+ *
+ * @example
+ * // Define `bar` module which fires an event:
+ * define({
+ * name: 'bar',
+ * requires: 'core/event',
+ * def: function def(ev) {
+ * // Dispatch event
+ * ev.dispatchEvent('test');
+ *
+ * // or:
+ * // ev.fire('test');
+ * }
+ * });
+ * @see {@link core/event.addEventListener} How to add event listener.
+ *
+ * @param {string} eventName Event name.
+ * @param {*} [data] Detailed data.
+ * @return {boolean}
+ */
+ function dispatchEvent(eventName, data) {
+ /*jshint validthis: true */
+ var customEvName = this.evName + '.' + eventName;
+ return dispatch(customEvName, data);
+
+ }
+
+ /**
+ * Dispatches an event of given name and detailed data.
+ *
+ * Since every new fired event has prefixed module name
+ * this method is deprecated.
+ *
+ * For example if event with `test` name will be dispatched from
+ * `foo` module, listener should be added to `test`.
+ *
+ * Please use new dispatchEvent.
+ * This method can be used only for backward compability.
+ *
+ * @memberof core/event
+ * @deprecated Since v2.0.
+ *
+ * @example
+ * // Define `bar` module which fires an event:
+ * define({
+ * name: 'bar',
+ * requires: 'core/event',
+ * def: function def(ev) {
+ * // Dispatch event
+ * ev.shoot('test');
+ * }
+ * });
+ * @see {@link core/event.addEventListener} How to handle fired event.
+ *
+ * @param {string} eventName Event name.
+ * @param {*} [data] Detailed data.
+ * @return {boolean} Cancelled.
+ */
+ function shoot(eventName, data) {
+ return dispatch(eventName, data);
+ }
+
+ /**
+ * Adds event listener for event name.
+ * @param {string} eventName Event name.
+ * @param {function} handler Handler function.
+ */
+ function addOneEventListener(eventName, handler) {
+ listeners[eventName] = listeners[eventName] || [];
+ listeners[eventName].push(handler);
+ window.addEventListener(eventName, handler);
+ }
+
+ /**
+ * Adds event listeners.
+ * @param {object} listeners Listeners object.
+ */
+ function addEventListeners(listeners) {
+ var eventName;
+ for (eventName in listeners) {
+ if (listeners.hasOwnProperty(eventName)) {
+ addOneEventListener(eventName, listeners[eventName]);
+ }
+ }
+ }
+
+ /**
+ * Adds event listener for event name.
+ * @memberof core/event
+ *
+ * @example
+ * // Define `foo` module which handles event dispatched from `bar`
+ * // with dispatchEvent method.
+ * define({
+ * name: 'foo',
+ * requires: 'core/event',
+ * def: function def(ev) {
+ * // Add event listener
+ * ev.addEventListener('bar.test', function handler() {});
+ *
+ * // or:
+ * // ev.on('bar.test', function handler() {});
+ * // ev.listen('bar.test', function handler() {});
+ * // ev.listeners('bar.test', function handler() {});
+ *
+ * // Add event listeners using object:
+ * // ev.on({'bar.test': function handler() {}});
+ * // ev.listen({'bar.test': function handler() {}});
+ * // ev.listeners({'bar.test': function handler() {}});
+ * // ev.addEventListener({
+ * // 'bar.test': function handler() {},
+ * // });
+ * }
+ * });
+ *
+ * @example
+ * // Define `foo` module which handles event dispatched from `bar`
+ * // with shoot method.
+ * define({
+ * name: 'foo',
+ * requires: 'core/event',
+ * def: function def(ev) {
+ * // Add event listener
+ * ev.addEventListener('test', function handler() {});
+ *
+ * // Or use available aliases for addEventListener
+ * });
+ * @see {@link core/event.dispatchEvent} How to fire event.
+ *
+ * @param {string|object} context Event name or Listeners object.
+ * @param {function} [handler] Handler function.
+ */
+ function addEventListener(context, handler) {
+ var contextType = typeof context;
+ if (contextType === 'object') {
+ addEventListeners(context);
+ } else if (contextType === 'string') {
+ addOneEventListener(context, handler);
+ }
+ }
+
+ /**
+ * Removes event listener.
+ * @memberof core/event
+ *
+ * @param {string} eventName Event name.
+ * @param {function} [handler] Handler function.
+ */
+ function removeEventListener(eventName, handler) {
+ var i, handlerIndex, listenersLen;
+ if (handler !== undefined) {
+ // remove only this specific handler
+ window.removeEventListener(eventName, handler);
+
+ // find it in the array and clear the reference
+ handlerIndex = listeners[eventName].indexOf(handler);
+ if (handlerIndex !== -1) {
+ listeners[eventName].splice(handlerIndex, 1);
+ }
+ } else {
+ // removes all listeners we know of
+ listenersLen = listeners[eventName].length;
+ for (i = 0; i < listenersLen; i += 1) {
+ window.removeEventListener(
+ eventName,
+ listeners[eventName][i]
+ );
+ }
+ // clear the references
+ listeners[eventName] = [];
+ }
+ }
+
+ return {
+
+ shoot: shoot, // used only for backward compability
+
+ addEventListener: addEventListener,
+
+ /**
+ * Alias for {@link core/event.addEventListener}
+ * @memberof core/event
+ * @function
+ * @see {@link core/event.addEventListener}
+ */
+ listen: addEventListener,
+ /**
+ * Alias for {@link core/event.addEventListener}
+ * @memberof core/event
+ * @function
+ * @see {@link core/event.addEventListener}
+ */
+ listeners: addEventListener,
+ /**
+ * Alias for {@link core/event.addEventListener}
+ * @memberof core/event
+ * @function
+ * @see {@link core/event.addEventListener}
+ */
+ on: addEventListener,
+
+ /**
+ * Alias for {@link core/event.dispatchEvent}
+ * @memberof core/event
+ * @function
+ * @see {@link core/event.dispatchEvent}
+ */
+ fire: dispatchEvent,
+ dispatchEvent: dispatchEvent,
+
+ /**
+ * Alias for {@link core/event.removeEventListener}
+ * @memberof core/event
+ * @function
+ * @see {@link core/event.removeEventListener}
+ */
+ die: removeEventListener,
+ removeEventListener: removeEventListener,
+
+ getListeners: getListeners
+ };
+ }
+});
diff --git a/js/core/core/storage/idb.js b/js/core/core/storage/idb.js
new file mode 100644
index 0000000..b6b3bf1
--- /dev/null
+++ b/js/core/core/storage/idb.js
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console*/
+
+/**
+ * Simple storage module, implemented using IndexedDB.
+ * @requires {@link core/event}
+ * @requires {@link core/window}
+ * @namespace core/storage/idb
+ * @memberof core
+ */
+
+define({
+ name: 'core/storage/idb',
+ requires: [
+ 'core/event',
+ 'core/window'
+ ],
+ def: function coreStorage(req) {
+ 'use strict';
+
+ var global = req.core.window,
+ indexedDB = global.indexedDB || global.webkitIndexedDB,
+ IDBKeyRange = global.IDBKeyRange || global.webkitIDBKeyRange,
+ e = req.core.event,
+ DB_NAME = 'corestorage',
+ STORE_NAME = 'kvstore',
+ VERSION = 5, // increment the value when db structure changes
+
+ // this module fires the following events
+ EVENT_OPEN = 'open', // db is open and ready to be used
+ EVENT_READ = 'read', // read request completed
+ EVENT_WRITE = 'write', // write request completed
+ EVENT_REMOVE = 'remove', // remove request completed
+ EVENT_COMPLETED = 'completed', // cleared pending requests
+
+ requestsCounter = -1,
+ pending = {},
+ db = null;
+
+ /**
+ * @memberof core/storage/idb
+ */
+ function isReady() {
+ return db !== null;
+ }
+
+ /**
+ * Add a request to the list of pending requests.
+ * @param {string} eventName
+ * @param {string} key
+ * @param {*} [value]
+ * @return {number} unique request ID.
+ */
+ function addPendingRequest(eventName, key, value) {
+ requestsCounter += 1;
+ pending[requestsCounter] = {
+ eventName: eventName,
+ key: key,
+ value: value
+ };
+ return requestsCounter;
+ }
+
+ /**
+ * Get pending request data.
+ * Returns 'undefined' if the request is already completed.
+ * @memberof core/storage/idb
+ * @param {number} id
+ * @return {object}
+ */
+ function getPendingRequest(id) {
+ return pending[id];
+ }
+
+ /**
+ * Checks if there are any pending requests.
+ * @memberof core/storage/idb
+ * @return {boolean}
+ */
+ function hasPendingRequests() {
+ return Object.keys(pending).length !== 0;
+ }
+
+ /**
+ * Remove a completed request from the list of pending requests.
+ * The request should be removed not earlier than all relevant
+ * handlers have finished processing.
+ * @param {type} id
+ */
+ function removePendingRequest(id) {
+ delete pending[id];
+ if (!hasPendingRequests()) {
+ e.fire(EVENT_COMPLETED);
+ }
+ }
+
+ /**
+ * Generic error handler for IndexedDB-related objects.
+ * @param {Error} err
+ */
+ function onerror(err) {
+ console.error(err.target.error.message);
+ }
+
+ /**
+ * Creates or updates database structure.
+ * @param {Event} ev
+ */
+ function onUpgradeNeeded(ev) {
+ var resultDb = ev.target.result;
+
+ // a transaction for changing db version starts automatically
+ ev.target.transaction.onerror = onerror;
+
+ // remove the existing store and create it again
+ if (resultDb.objectStoreNames.contains(STORE_NAME)) {
+ resultDb.deleteObjectStore(STORE_NAME);
+ }
+
+ resultDb.createObjectStore(
+ STORE_NAME,
+ {keyPath: 'key'}
+ );
+ }
+
+ /**
+ * Assigns database object.
+ * This handler is executed right after the upgrade.
+ * This method fires the core.storage.open event upon completion.
+ * @param {Event} ev
+ */
+ function onOpenSuccess(ev) {
+ db = ev.target.result;
+ e.fire(EVENT_OPEN);
+ }
+
+ /**
+ * Open the database.
+ */
+ function open() {
+ // create a request for opening the database
+ var request = indexedDB.open(DB_NAME, VERSION);
+
+ // one or more of the handlers will be called
+ // automatically when the current function exits
+ request.onupgradeneeded = onUpgradeNeeded;
+ request.onsuccess = onOpenSuccess;
+ request.onerror = onerror;
+ }
+
+ /**
+ * Gets value for given key from the storage.
+ * The method fires the core.storage.read event upon completion.
+ * @memberof core/storage/idb
+ * @param {string} key Key.
+ * @return {number} Request id.
+ */
+ function get(key) {
+ var trans = db.transaction([STORE_NAME], 'readwrite'),
+ store = trans.objectStore(STORE_NAME),
+
+ // Find the key in the store
+ keyRange = IDBKeyRange.only(key),
+ id = addPendingRequest(EVENT_READ, key),
+ cursorRequest = store.openCursor(keyRange);
+
+ cursorRequest.onsuccess = function onCursorOpenSuccess(ev) {
+ var error = null,
+ cursor = ev.target.result;
+
+ if (!cursor) {
+ error = new Error('No records returned');
+ error.name = 'StorageNotFoundError';
+
+ e.fire(EVENT_READ, {
+ id: id,
+ key: key,
+ error: error
+ });
+ removePendingRequest(id);
+ } else {
+ e.fire(EVENT_READ, {
+ id: id,
+ key: cursor.value.key,
+ value: cursor.value.value
+ });
+ }
+ removePendingRequest(id);
+ };
+
+ cursorRequest.onerror = function onCursorOpenError(err) {
+ removePendingRequest(id);
+ console.error(err.target.error.message);
+ };
+
+ return id;
+ }
+
+ /**
+ * Sets value for given key to the storage.
+ * The method fires the core.storage.write event upon completion.
+ * @memberof core/storage/idb
+ * @param {string} key Key.
+ * @param {object} val Value object.
+ * @return {boolean}
+ */
+ function set(key, val) {
+ var trans = db.transaction([STORE_NAME], 'readwrite'),
+ store = trans.objectStore(STORE_NAME),
+ request = store.put({
+ key: key,
+ value: val
+ }),
+ id = addPendingRequest(EVENT_WRITE, key, val);
+
+ request.onsuccess = function onPutSuccess() {
+ e.fire(
+ EVENT_WRITE,
+ {id: id, key: key, value: val}
+ );
+ removePendingRequest(id);
+ };
+
+ request.onerror = function onPutError(err) {
+ console.error(err.target.error.message);
+ removePendingRequest(id);
+ };
+
+ return id;
+ }
+
+ /**
+ * Removes value with given key from the storage.
+ * The method fires the core.storage.remove event upon completion.
+ * @param {string} key Key name.
+ * @return {number} id Id.
+ */
+ function removeItem(key) {
+ var trans = db.transaction([STORE_NAME], 'readwrite'),
+ store = trans.objectStore(STORE_NAME),
+ id = addPendingRequest(EVENT_REMOVE, key),
+ request = store.delete(key);
+
+ request.onsuccess = function onDeleteSuccess() {
+ e.fire(EVENT_REMOVE, {id: id, key: key});
+ removePendingRequest(id);
+ };
+
+ request.onerror = function onDeleteError(err) {
+ console.error(err.target.error.message);
+ removePendingRequest(id);
+ };
+ return id;
+ }
+
+ /**
+ * Removes keys from given array.
+ * @param {string[]} keys Key array.
+ */
+ function removeItems(keys) {
+ var ids = [];
+ keys.forEach(function forEach(key) {
+ ids.push(removeItem(key));
+ });
+ return ids;
+ }
+
+ /**
+ * Removes value for given context.
+ * @memberof core/storage/idb
+ * @param {string|array} context Key name or keys array.
+ * @return {number|array} id Id or ids array.
+ */
+ function remove(context) {
+ var id = -1;
+ if (typeof context === 'string') {
+ id = removeItem(context);
+ } else if (Array.isArray(context)) {
+ id = removeItems(context);
+ }
+ return id;
+ }
+
+ function init() {
+ open();
+ }
+
+ return {
+ init: init,
+ getPendingRequest: getPendingRequest,
+ hasPendingRequests: hasPendingRequests,
+ isReady: isReady,
+ get: get,
+ /**
+ * Alias for {@link core/storage/idb.set}
+ * @memberof core/storage/idb
+ * @function
+ * @see {@link core/storage/idb.set}
+ */
+ add: set,
+ set: set,
+ remove: remove
+ };
+ }
+});
diff --git a/js/core/core/systeminfo.js b/js/core/core/systeminfo.js
new file mode 100644
index 0000000..21774e9
--- /dev/null
+++ b/js/core/core/systeminfo.js
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console*/
+
+/**
+ * System info module
+ * @requires {@link core/event}
+ * @requires {@link core/tizen}
+ * @namespace core/systeminfo
+ * @memberof core
+ */
+
+define({
+ name: 'core/systeminfo',
+ requires: [
+ 'core/event',
+ 'core/tizen'
+ ],
+ def: function coreSystemInfo(e, tizen) {
+ 'use strict';
+
+ var systeminfo = null,
+ lowBattery = 0.04;
+
+ function noop() {
+ return;
+ }
+
+ /**
+ * Gets system property
+ * @memberof core/systeminfo
+ * @param {string} property Property name.
+ * @param {function} onSuccess Success callback.
+ * @param {function} onError Error callback.
+ */
+ function getSystemProperty(property, onSuccess, onError) {
+ systeminfo.getPropertyValue(property, onSuccess, onError);
+ }
+
+ /**
+ * Add listener for battery change to low
+ * @memberof core/systeminfo
+ * @fires "battery.low"
+ */
+ function listenBatteryLowState() {
+ systeminfo.addPropertyValueChangeListener(
+ 'BATTERY',
+ function change(battery) {
+ if (!battery.isCharging) {
+ e.fire('battery.low');
+ }
+ },
+ {
+ lowThreshold: lowBattery
+ }
+ );
+ }
+
+ /**
+ * Check low battery state
+ * @memberof core/systeminfo
+ * @fires "battery.low"
+ * @fires "battery.normal"
+ * @fires "battery.checked"
+ */
+ function checkBatteryLowState() {
+ systeminfo.getPropertyValue('BATTERY', function getValue(battery) {
+ if (battery.level < lowBattery && !battery.isCharging) {
+ e.fire('battery.low', {
+ level: battery.level
+ });
+ } else {
+ e.fire('battery.normal');
+ }
+ e.fire('battery.checked');
+ }, null);
+ }
+
+ /**
+ * Initialise module.
+ * @memberof core/systeminfo
+ * @private
+ */
+ function init() {
+ if (typeof tizen === 'object' &&
+ typeof tizen.systeminfo === 'object') {
+ systeminfo = tizen.systeminfo;
+ } else {
+ console.warn(
+ 'tizen.systeminfo not available'
+ );
+ systeminfo = {
+ getPropertyValue: noop,
+ addPropertyValueChangeListener: noop
+ };
+ }
+ }
+
+ return {
+ getSystemProperty: getSystemProperty,
+ checkBatteryLowState: checkBatteryLowState,
+ listenBatteryLowState: listenBatteryLowState,
+ init: init
+ };
+ }
+});
diff --git a/js/core/core/tizen.js b/js/core/core/tizen.js
new file mode 100644
index 0000000..771cc36
--- /dev/null
+++ b/js/core/core/tizen.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define*/
+
+/**
+ * Tizen module.
+ * Module returns tizen global object.
+ * @namespace core/tizen
+ * @memberof core
+ *
+ * @example
+ * //Define `foo` module which require `core/tizen` module:
+ * define({
+ * name: 'foo',
+ * requires: ['core/tizen'],
+ * def: function (tizen) {
+ * var systeminfo = tizen.systeminfo;
+ * }
+ * });
+ */
+
+define({
+ name: 'core/tizen',
+ requires: ['core/window'],
+ def: function coreTizen(win) {
+ 'use strict';
+
+ return win.tizen;
+ }
+});
diff --git a/js/core/core/window.js b/js/core/core/window.js
new file mode 100644
index 0000000..c7f79cc
--- /dev/null
+++ b/js/core/core/window.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, window*/
+
+/**
+ * Window module.
+ * Module returns window global object.
+ * @namespace core/window
+ * @memberof core
+ *
+ * @example
+ * //Define `foo` module which require `core/window` module:
+ * define({
+ * name: 'foo',
+ * requires: ['core/window'],
+ * def: function (window) {
+* var document = window.document;
+ * }
+ * });
+ */
+
+define({
+ name: 'core/window',
+ def: function coreWindow() {
+ 'use strict';
+
+ return window;
+ }
+});
diff --git a/js/helpers/dom.js b/js/helpers/dom.js
new file mode 100644
index 0000000..edd1e48
--- /dev/null
+++ b/js/helpers/dom.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, tizen*/
+
+/**
+ * Dom helper module.
+ * @namespace Altimeter/helpers/dom
+ * @memberof Altimeter/helpers
+ */
+
+define({
+ name: 'helpers/dom',
+ def: function helpersDom() {
+ 'use strict';
+
+ /**
+ * Returns parent node with class name given as second parameter
+ * of the child given as first parameter.
+ * @memberof Altimeter/helpers/dom
+ * @param {DOMElement} element
+ * @param {string} parentClassName
+ * @return {DOMElement}
+ */
+ function findParentByClassName(element, parentClassName) {
+ parentClassName = parentClassName.toLowerCase();
+ do {
+ element = element.parentNode;
+ if (element.classList &&
+ element.classList.contains(parentClassName)) {
+ return element;
+ }
+ } while (element.parentNode);
+ }
+
+ return {
+ findParentByClassName: findParentByClassName
+ };
+ }
+});
diff --git a/js/models/pressure.js b/js/models/pressure.js
new file mode 100644
index 0000000..a6f0f2c
--- /dev/null
+++ b/js/models/pressure.js
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console, tizen */
+
+/**
+ * Sensor model.
+ * @requires {@link core/event}
+ * @requires {@link core/window}
+ * @namespace Altimeter/models/pressure
+ * @memberof Altimeter/models
+ */
+define({
+ name: 'models/pressure',
+ requires: [
+ 'core/event',
+ 'core/window'
+ ],
+ def: function modelsPressure(e, window) {
+ 'use strict';
+
+ /**
+ * Reference to the sensor service.
+ * @type {SensorService}
+ */
+ var sensorService = null,
+
+ /**
+ * Reference to the pressure sensor.
+ * @type {PressureSensor}
+ */
+ pressureSensor = null,
+
+ /**
+ * Name of the sensor type.
+ * @type {string}
+ */
+ SENSOR_TYPE = 'PRESSURE',
+
+ /**
+ * Error type name.
+ * @type {string}
+ */
+ ERROR_TYPE_NOT_SUPPORTED = 'NotSupportedError',
+
+ /**
+ * Array of registered pressures.
+ * @type {number[]}
+ */
+ previousPressures = [],
+
+ /**
+ * Maximum size of the previousPressures array.
+ * @type {number}
+ */
+ MAX_LENGTH = 7,
+
+ /**
+ * Average pressure.
+ * @type {number}
+ */
+ averagePressure = 0,
+
+ /**
+ * Current pressure.
+ * @type {number}
+ */
+ currentPressure = 0;
+
+ /**
+ * Performs action on start sensor success.
+ */
+ function onSensorStartSuccess() {
+ e.fire('start');
+ }
+
+ /**
+ * Performs action on start sensor error.
+ * @param {Error} e
+ */
+ function onSensorStartError(e) {
+ console.error('Pressure sensor start error: ', e);
+ e.fire('error', e);
+ }
+
+ /**
+ * Updates the average pressure value.
+ * @param {number} currentPressure
+ * @return {number}
+ */
+ function updateAveragePressure(currentPressure) {
+ previousPressures.push(currentPressure);
+
+ var len = previousPressures.length;
+
+ if (len <= MAX_LENGTH) {
+ // nothing to shift yet, recalculate whole average
+ averagePressure = previousPressures.reduce(function sum(a, b) {
+ return a + b;
+ }) / len;
+ } else {
+ // add the new item and subtract the one shifted out
+ averagePressure += (
+ currentPressure - previousPressures.shift()
+ ) / len;
+ }
+ return averagePressure;
+ }
+
+ /**
+ * Performs action on sensor change.
+ * @param {object} data
+ */
+ function onSensorChange(data) {
+ currentPressure = data.pressure;
+ updateAveragePressure(currentPressure);
+ e.fire('change', {
+ current: data.pressure,
+ average: averagePressure
+ });
+ }
+
+ /**
+ * Starts sensor.
+ * @memberof Altimeter/models/pressure
+ */
+ function start() {
+ pressureSensor.start(onSensorStartSuccess, onSensorStartError);
+ }
+
+ /**
+ * Sets sensor change listener.
+ * @memberof Altimeter/models/pressure
+ */
+ function setChangeListener() {
+ pressureSensor.setChangeListener(onSensorChange);
+ }
+
+ /**
+ * Returns sensor value.
+ * @memberof Altimeter/models/pressure
+ */
+ function getSensorValue() {
+ return currentPressure;
+ }
+
+ /**
+ * Returns average of several past readings.
+ * @memberof Altimeter/models/pressure
+ * @return {number}
+ */
+ function getAverageSensorValue() {
+ return averagePressure;
+ }
+
+ /**
+ * Handles sensor data.
+ * @param {object} data
+ */
+ function setCurrentPressureValue(data) {
+ currentPressure = data.pressure;
+ }
+
+ /**
+ * Returns true if sensor is available, false otherwise.
+ * @memberof Altimeter/models/pressure
+ * @return {boolean}
+ */
+ function isAvailable() {
+ return !!pressureSensor;
+ }
+
+ /**
+ * Initializes module.
+ * @memberof Altimeter/models/pressure
+ */
+ function init() {
+ sensorService = tizen.sensorservice ||
+ (window.webapis && window.webapis.sensorservice) ||
+ null;
+
+ if (!sensorService) {
+ e.fire('error', {type: 'notavailable'});
+ } else {
+ try {
+ pressureSensor = sensorService
+ .getDefaultSensor(SENSOR_TYPE);
+ pressureSensor
+ .getPressureSensorData(setCurrentPressureValue);
+ } catch (error) {
+ if (error.type === ERROR_TYPE_NOT_SUPPORTED) {
+ e.fire('error', {type: 'notsupported'});
+ } else {
+ e.fire('error', {type: 'unknown'});
+ }
+ }
+ }
+ }
+
+ return {
+ initSensor: init,
+ start: start,
+ isAvailable: isAvailable,
+ setChangeListener: setChangeListener,
+ getAverageSensorValue: getAverageSensorValue,
+ getSensorValue: getSensorValue
+ };
+ }
+
+});
diff --git a/js/models/settings.js b/js/models/settings.js
new file mode 100644
index 0000000..a967641
--- /dev/null
+++ b/js/models/settings.js
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console*/
+
+/**
+ * Settings model.
+ * @requires {@link core/storage/idb}
+ * @requires {@link core/event}
+ * @namespace Altimeter/models/settings
+ * @memberof Altimeter/models
+ */
+define({
+ name: 'models/settings',
+ requires: [
+ 'core/storage/idb',
+ 'core/event'
+ ],
+ def: function modelsSettings(req) {
+ 'use strict';
+
+ /**
+ * Core event module.
+ * @type {Module}
+ */
+ var e = req.core.event,
+
+ /**
+ * Core IDB storage module.
+ * @type {Module}
+ */
+ s = req.core.storage.idb,
+
+ /**
+ * Storage key.
+ * @type {string}
+ */
+ STORAGE_KEY = 'settings',
+
+ /**
+ * Default pressure.
+ * @type {object}
+ */
+ DEFAULT = Object.freeze({
+ pressure: 1013.25
+ }),
+
+ /**
+ * Settings object.
+ * @type {object}
+ */
+ settings = {};
+
+ /**
+ * Saves settings to storage.
+ */
+ function saveSettings() {
+ s.add(STORAGE_KEY, settings);
+ }
+
+ /**
+ * Sets given settings property.
+ * @memberof Altimeter/models/settings
+ * @param {string} property
+ * @param {number} value
+ * @return {boolean}
+ */
+ function set(property, value) {
+ if (property !== undefined && value !== undefined) {
+ settings[property] = value;
+ saveSettings();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns given settings property.
+ * @memberof Altimeter/models/settings
+ * @param {string} property
+ * @return {number}
+ */
+ function get(property) {
+ if (settings[property] === undefined) {
+ console.error('Settings not initialized yet.');
+ return null;
+ }
+ return settings[property];
+ }
+
+ /**
+ * Initializes module.
+ */
+ function init() {
+ s.get(STORAGE_KEY);
+ }
+
+ /**
+ * Handles core.storage.idb.read event.
+ * @param {event} ev
+ */
+ function onRead(ev) {
+ if (ev.detail.key !== STORAGE_KEY) {
+ return;
+ }
+ if (typeof ev.detail.value !== 'object') {
+ settings = {
+ pressure: DEFAULT.pressure
+ };
+ saveSettings();
+ } else {
+ settings = ev.detail.value;
+ }
+ e.fire('ready');
+ }
+
+ /**
+ * Make sure that init is run when storage is ready.
+ * @memberof Altimeter/models/settings
+ */
+ function runInit() {
+ if (s.isReady()) {
+ init();
+ } else {
+ e.listen('core.storage.idb.open', init);
+ }
+ }
+
+ e.listeners({
+ 'core.storage.idb.read': onRead
+ });
+
+ return {
+ init: runInit,
+ get: get,
+ set: set
+ };
+ }
+
+});
diff --git a/js/tau-config.js b/js/tau-config.js
new file mode 100644
index 0000000..0ee1614
--- /dev/null
+++ b/js/tau-config.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global document, tau*/
+
+document.addEventListener('tauinit', function onTauInit() {
+ 'use strict';
+
+ tau.setConfig('pageTransition', 'none');
+ tau.setConfig('popupTransition', 'none');
+});
diff --git a/js/views/init.js b/js/views/init.js
new file mode 100644
index 0000000..d048b4e
--- /dev/null
+++ b/js/views/init.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console, window, document*/
+
+/**
+ * Init page module.
+ * @requires {@link core/event}
+ * @requires {@link core/application}
+ * @requires {@link core/systeminfo}
+ * @requires {@link Altimeter/views/main}
+ * @namespace Altimeter/views/init
+ * @memberof Altimeter/views
+ */
+define({
+ name: 'views/init',
+ requires: [
+ 'core/event',
+ 'core/application',
+ 'core/systeminfo',
+ 'views/main'
+ ],
+ def: function viewsInitPage(req) {
+ 'use strict';
+
+ /**
+ * Core event module.
+ * @type {Module}
+ */
+ var e = req.core.event,
+
+ /**
+ * Core application module.
+ * @type {Module}
+ */
+ app = req.core.application,
+
+ /**
+ * Core systeminfo module.
+ * @type {Module}
+ */
+ sysInfo = req.core.systeminfo;
+
+ /**
+ * Registers view event listeners.
+ */
+ function bindEvents() {
+ document.addEventListener('tizenhwkey', function onTizenhwkey(e) {
+ if (e.keyName === 'back') {
+ app.exit();
+ }
+ });
+ sysInfo.listenBatteryLowState();
+ }
+
+ /**
+ * Handles the core.battery.low event.
+ */
+ function onLowBattery() {
+ app.exit();
+ }
+
+ /**
+ * Handles the core.battery.checked state.
+ */
+ function onBatteryChecked() {
+ e.fire('device.ready');
+ }
+
+ /**
+ * Initializes the module.
+ * @memberof Altimeter/views/init
+ */
+ function init() {
+ bindEvents();
+ sysInfo.checkBatteryLowState();
+ }
+
+ e.listeners({
+ 'core.systeminfo.battery.low': onLowBattery,
+ 'core.systeminfo.battery.checked': onBatteryChecked
+ });
+
+ return {
+ init: init
+ };
+ }
+
+});
diff --git a/js/views/main.js b/js/views/main.js
new file mode 100644
index 0000000..8dd19e3
--- /dev/null
+++ b/js/views/main.js
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2014 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.
+ */
+
+/*global define, console, document, tau*/
+
+/**
+ * Main page module.
+ * @requires {@link core/event}
+ * @requires {@link Altimeter/models/settings}
+ * @requires {@link Altimeter/models/pressure}
+ * @requires {@link core/application}
+ * @namespace Altimeter/views/main
+ * @memberof Altimeter/views
+ */
+
+define({
+ name: 'views/main',
+ requires: [
+ 'core/event',
+ 'models/settings',
+ 'models/pressure',
+ 'core/application'
+ ],
+ def: function viewsMainPage(req) {
+ 'use strict';
+
+ /**
+ * Core event module.
+ * @type {Module}
+ */
+ var e = req.core.event,
+
+ /**
+ * Pressure module.
+ * @type {Module}
+ */
+ sensor = req.models.pressure,
+
+ /**
+ * Settings module.
+ * @type {Module}
+ */
+ settings = req.models.settings,
+
+ /**
+ * Core event module.
+ * @type {Module}
+ */
+ app = req.core.application,
+
+ /**
+ * Popup message.
+ * @type {string}
+ */
+ ARE_YOU_SURE_MSG = 'Are you sure you want to calibrate device?',
+
+ /**
+ * Popup message.
+ * @type {string}
+ */
+ SENSOR_NOT_AVAILABLE_MSG = 'Pressure sensor is not available.',
+
+ /**
+ * Popup message.
+ * @type {string}
+ */
+ SENSOR_NOT_SUPPORTED_MSG = 'Pressure sensor is not supported ' +
+ 'on this device.',
+
+ /**
+ * Popup message.
+ * @type {string}
+ */
+ SENSOR_UNKNOWN_ERROR_MSG = 'Unknown sensor error occurs.',
+
+ /**
+ * Reference to the popup message element.
+ * @type {HTMLElement}
+ */
+ calibrationMessage = null,
+
+ /**
+ * Reference to the 'Calibration' button.
+ * @type {HTMLElement}
+ */
+ calibrationBtn = null,
+
+ /**
+ * Reference to the 'Yes' button.
+ * @type {HTMLElement}
+ */
+ yesBtn = null,
+
+ /**
+ * Reference to the 'No' button.
+ * @type {HTMLElement}
+ */
+ noBtn = null,
+
+ /**
+ * Reference to the 'reference' element.
+ * @type {HTMLElement}
+ */
+ referenceValue = null,
+
+ /**
+ * Reference to the 'pressure' element.
+ * @type {HTMLElement}
+ */
+ pressureValue = null,
+
+ /**
+ * Reference to the 'altitude' element.
+ * @type {HTMLElement}
+ */
+ altitudeValue = null,
+
+ /**
+ * Reference to the 'alert' popup.
+ * @type {HTMLElement}
+ */
+ alertElement = null,
+
+ /**
+ * Reference to the alert message element.
+ * @type {HTMLElement}
+ */
+ alertMessage = null,
+
+ /**
+ * Reference to the 'ok' button on the alert popup.
+ * @type {HTMLElement}
+ */
+ alertOk = null,
+
+ /**
+ * Reference to the 'calibration' popup.
+ * @type {HTMLElement}
+ */
+ popupCalibration = null;
+
+ /**
+ * Updates reference pressure value.
+ */
+ function updateReferenceValue() {
+ referenceValue.innerText = settings.get('pressure').toFixed(2);
+ }
+
+ /**
+ * Updates current pressure value.
+ * @param {number} value
+ */
+ function updatePressureValue(value) {
+ pressureValue.innerText = value.toFixed(2);
+ }
+
+ /**
+ * Updates altitude value.
+ * @param {number} value
+ */
+ function updateAltitudeValue(value) {
+ var reference = settings.get('pressure'),
+ text = '',
+ altitude = -8727 * Math.log(value / reference);
+
+ text = altitude.toFixed(0);
+ if (text === '-0') {
+ text = '0';
+ }
+ altitudeValue.innerText = text;
+ }
+
+ /**
+ * Resets altitude value.
+ */
+ function resetAltitudeValue() {
+ altitudeValue.innerText = '0';
+ }
+
+ /**
+ * Shows application working space.
+ */
+ function showWorkingSpace() {
+ updateReferenceValue();
+ }
+
+ /**
+ * Shows application start monit.
+ */
+ function showCalibrationMonit() {
+ tau.openPopup(popupCalibration);
+ }
+
+ /**
+ * Calibrates pressure.
+ */
+ function calibratePressure() {
+ settings.set('pressure', sensor.getAverageSensorValue());
+ resetAltitudeValue();
+ updateReferenceValue();
+ }
+
+ /**
+ * Shows alert popup.
+ * @param {string} message Message.
+ */
+ function openAlert(message) {
+ alertMessage.innerHTML = message;
+ tau.openPopup(alertElement);
+ }
+
+ /**
+ * Handles click event on calibration button.
+ */
+ function onCalibrationBtnClick() {
+ calibrationMessage.innerHTML = ARE_YOU_SURE_MSG;
+ showCalibrationMonit();
+ }
+
+ /**
+ * Handles click event on yes button.
+ */
+ function onYesBtnClick() {
+ tau.closePopup();
+ showWorkingSpace();
+ calibratePressure();
+ }
+
+ /**
+ * Handles click event on no button.
+ */
+ function onNoBtnClick() {
+ tau.closePopup();
+ showWorkingSpace();
+ }
+
+ /**
+ * Handles sensor.start event.
+ */
+ function onSensorStart() {
+ showCalibrationMonit();
+ }
+
+ /**
+ * Handles models.pressure.error event.
+ * @param {object} data
+ */
+ function onSensorError(data) {
+ var type = data.detail.type;
+
+ if (type === 'notavailable') {
+ openAlert(SENSOR_NOT_AVAILABLE_MSG);
+ } else if (type === 'notsupported') {
+ openAlert(SENSOR_NOT_SUPPORTED_MSG);
+ } else {
+ openAlert(SENSOR_UNKNOWN_ERROR_MSG);
+ }
+ }
+
+ /**
+ * Handles sensor.change event.
+ * @param {Event} ev
+ */
+ function onSensorChange(ev) {
+ updatePressureValue(ev.detail.average);
+ updateAltitudeValue(ev.detail.average);
+ }
+
+ /**
+ * Handles device.ready event.
+ */
+ function onDeviceReady() {
+ sensor.initSensor();
+ if (sensor.isAvailable()) {
+ sensor.setChangeListener();
+ sensor.start();
+ }
+ }
+
+ /**
+ * Handles click event on OK button.
+ */
+ function onOkClick() {
+ tau.closePopup();
+ }
+
+ /**
+ * Handles popupHide event on popup element.
+ */
+ function onPopupHide() {
+ app.exit();
+ }
+
+ /**
+ * Registers event listeners.
+ */
+ function bindEvents() {
+ calibrationBtn.addEventListener('click', onCalibrationBtnClick);
+ yesBtn.addEventListener('click', onYesBtnClick);
+ noBtn.addEventListener('click', onNoBtnClick);
+ alertElement.addEventListener('popuphide', onPopupHide);
+ alertOk.addEventListener('click', onOkClick);
+ }
+
+ /**
+ * Initializes module.
+ * @memberof Altimeter/views/main
+ */
+ function init() {
+ calibrationMessage = document.getElementById(
+ 'popup-calibration-message'
+ );
+ calibrationBtn = document.getElementById('calibration-btn');
+ yesBtn = document.getElementById(
+ 'popup-calibration-yes'
+ );
+ noBtn = document.getElementById(
+ 'popup-calibration-no'
+ );
+ referenceValue = document.getElementById('reference-value');
+ pressureValue = document.getElementById('current-value');
+ altitudeValue = document.getElementById('altitude-value');
+ alertElement = document.getElementById('alert');
+ alertMessage = document.getElementById('alert-message');
+ alertOk = document.getElementById('alert-ok');
+ popupCalibration = document.getElementById('popup-calibration');
+ bindEvents();
+ }
+
+ e.listeners({
+ 'models.pressure.start': onSensorStart,
+ 'models.pressure.error': onSensorError,
+ 'models.pressure.change': onSensorChange,
+ 'views.init.device.ready': onDeviceReady
+ });
+
+ return {
+ init: init
+ };
+ }
+
+});